jamlib 3.1.0__tar.gz → 3.2.0b0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {jamlib-3.1.0/src/jamlib.egg-info → jamlib-3.2.0b0}/PKG-INFO +1 -1
- {jamlib-3.1.0 → jamlib-3.2.0b0}/pyproject.toml +1 -1
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/__base__.py +29 -22
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/__deprecated__.py +1 -1
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/__init__.py +1 -1
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/__base__.py +28 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/instance.py +39 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/exceptions/__init__.py +24 -21
- jamlib-3.2.0b0/src/jam/exceptions/jose.py +23 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/exceptions/jwt.py +4 -2
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/instance.py +72 -10
- jamlib-3.2.0b0/src/jam/jose/__algorithms__.py +1161 -0
- jamlib-3.2.0b0/src/jam/jose/__base__.py +348 -0
- jamlib-3.2.0b0/src/jam/jose/__init__.py +19 -0
- jamlib-3.2.0b0/src/jam/jose/jwe.py +197 -0
- jamlib-3.2.0b0/src/jam/jose/jwk.py +504 -0
- jamlib-3.2.0b0/src/jam/jose/jws.py +192 -0
- jamlib-3.2.0b0/src/jam/jose/jwt.py +498 -0
- jamlib-3.2.0b0/src/jam/jose/lists/__base__.py +40 -0
- jamlib-3.2.0b0/src/jam/jose/lists/__init__.py +11 -0
- jamlib-3.2.0b0/src/jam/jose/lists/json.py +136 -0
- jamlib-3.2.0b0/src/jam/jose/lists/memory.py +111 -0
- jamlib-3.2.0b0/src/jam/jose/lists/redis.py +161 -0
- {jamlib-3.1.0/src/jam/jwt → jamlib-3.2.0b0/src/jam/jose}/utils.py +3 -2
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/jwt/__base__.py +2 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/jwt/lists/__base__.py +3 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/jwt/lists/json.py +2 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/jwt/lists/redis.py +2 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/jwt/module.py +2 -0
- jamlib-3.2.0b0/src/jam/jwt/utils.py +36 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/tests/clients.py +56 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0/src/jamlib.egg-info}/PKG-INFO +1 -1
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jamlib.egg-info/SOURCES.txt +14 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/LICENSE.md +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/README.md +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/setup.cfg +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/__base_encoder__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/jwt/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/oauth2/__base__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/oauth2/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/oauth2/builtin/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/oauth2/builtin/github.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/oauth2/builtin/gitlab.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/oauth2/builtin/google.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/oauth2/builtin/yandex.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/oauth2/client.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/sessions/__base__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/sessions/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/sessions/json.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/aio/sessions/redis.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/cli/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/cli/cli.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/cli/commands/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/cli/commands/keys.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/cli/commands/password.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/encoders.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/exceptions/base.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/exceptions/oauth2.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/exceptions/paseto.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/exceptions/plugins.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/exceptions/sessions.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/fastapi/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/flask/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/flask/extensions.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/flask/objects.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/litestar/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/litestar/middleware.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/litestar/objects.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/litestar/plugins.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/starlette/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/starlette/backends.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/ext/starlette/objects.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/jwt/__algorithms__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/jwt/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/jwt/__types__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/jwt/lists/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/logger.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/oauth2/__base__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/oauth2/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/oauth2/builtin/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/oauth2/builtin/github.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/oauth2/builtin/gitlab.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/oauth2/builtin/google.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/oauth2/builtin/yandex.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/oauth2/client.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/otp/__base__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/otp/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/otp/hotp.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/otp/totp.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/paseto/__base__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/paseto/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/paseto/utils.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/paseto/v1.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/paseto/v2.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/paseto/v3.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/paseto/v4.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/py.typed +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/sessions/__base__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/sessions/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/sessions/json.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/sessions/redis.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/tests/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/tests/fakers.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/__init__.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/aes.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/await_maybe.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/basic_auth.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/config_maker.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/ed.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/otp_keys.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/rsa.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/salt_hash.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/symmetric.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/xchacha20poly1305.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jam/utils/xor.py +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jamlib.egg-info/dependency_links.txt +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jamlib.egg-info/entry_points.txt +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jamlib.egg-info/requires.txt +0 -0
- {jamlib-3.1.0 → jamlib-3.2.0b0}/src/jamlib.egg-info/top_level.txt +0 -0
|
@@ -6,7 +6,7 @@ from typing import Any, Literal
|
|
|
6
6
|
|
|
7
7
|
from jam.encoders import BaseEncoder, JsonEncoder
|
|
8
8
|
from jam.exceptions import JamConfigurationError
|
|
9
|
-
from jam.
|
|
9
|
+
from jam.jose.__base__ import BaseJWT
|
|
10
10
|
from jam.logger import BaseLogger, JamLogger
|
|
11
11
|
from jam.oauth2.__base__ import BaseOAuth2Client
|
|
12
12
|
from jam.otp.__base__ import BaseOTP, OTPConfig
|
|
@@ -189,36 +189,41 @@ class BaseJam(ABC):
|
|
|
189
189
|
raise JamConfigurationError(message="Unknown OTP type.")
|
|
190
190
|
|
|
191
191
|
@abstractmethod
|
|
192
|
-
def
|
|
193
|
-
self,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
"""
|
|
204
|
-
raise NotImplementedError
|
|
205
|
-
|
|
206
|
-
@abstractmethod
|
|
207
|
-
def jwt_create(self, payload: dict[str, Any]) -> str:
|
|
208
|
-
"""Create JWT token.
|
|
192
|
+
def jwt_encode(
|
|
193
|
+
self,
|
|
194
|
+
iss: str | None = None,
|
|
195
|
+
sub: str | None = None,
|
|
196
|
+
aud: str | None = None,
|
|
197
|
+
exp: int | None = None,
|
|
198
|
+
nbf: int | None = None,
|
|
199
|
+
*,
|
|
200
|
+
payload: dict[str, Any] | None = None,
|
|
201
|
+
header: dict[str, Any] | None = None,
|
|
202
|
+
) -> str:
|
|
203
|
+
"""Encode the JWT with the given expire, header, and payload.
|
|
209
204
|
|
|
210
205
|
Args:
|
|
211
|
-
|
|
206
|
+
exp (int | None): The expiration time in seconds.
|
|
207
|
+
nbf (int | None): The not-before time in seconds.
|
|
208
|
+
iss (str | None): The issuer.
|
|
209
|
+
sub (str | None): The subject.
|
|
210
|
+
aud (str | None): The audience.
|
|
211
|
+
header (dict[str, Any] | None): The header to include in the JWT.
|
|
212
|
+
payload (dict[str, Any] | None): The payload to include in the JWT.
|
|
212
213
|
|
|
213
214
|
Returns:
|
|
214
|
-
str:
|
|
215
|
-
|
|
215
|
+
str: The encoded JWT.
|
|
216
216
|
"""
|
|
217
217
|
raise NotImplementedError
|
|
218
218
|
|
|
219
219
|
@abstractmethod
|
|
220
220
|
def jwt_decode(
|
|
221
|
-
self,
|
|
221
|
+
self,
|
|
222
|
+
token: str,
|
|
223
|
+
check_exp: bool = True,
|
|
224
|
+
check_list: bool = True,
|
|
225
|
+
check_nbf: bool = False,
|
|
226
|
+
include_headers: bool = False,
|
|
222
227
|
) -> dict[str, Any]:
|
|
223
228
|
"""Verify and decode JWT token.
|
|
224
229
|
|
|
@@ -226,6 +231,8 @@ class BaseJam(ABC):
|
|
|
226
231
|
token (str): JWT token
|
|
227
232
|
check_exp (bool): Check expire
|
|
228
233
|
check_list (bool): Check white/black list. Docs: https://jam.makridenko.ru/jwt/lists/what/
|
|
234
|
+
check_nbf (bool): Check not-before time
|
|
235
|
+
include_headers (bool): Include headers in the decoded payload
|
|
229
236
|
|
|
230
237
|
Returns:
|
|
231
238
|
dict[str, Any]: Decoded payload
|
|
@@ -45,6 +45,34 @@ class BaseAsyncJam(BaseJam):
|
|
|
45
45
|
"""
|
|
46
46
|
raise NotImplementedError
|
|
47
47
|
|
|
48
|
+
@abstractmethod
|
|
49
|
+
async def jwt_encode(
|
|
50
|
+
self,
|
|
51
|
+
iss: str | None = None,
|
|
52
|
+
sub: str | None = None,
|
|
53
|
+
aud: str | None = None,
|
|
54
|
+
exp: int | None = None,
|
|
55
|
+
nbf: int | None = None,
|
|
56
|
+
*,
|
|
57
|
+
payload: dict[str, Any] | None = None,
|
|
58
|
+
header: dict[str, Any] | None = None,
|
|
59
|
+
) -> str:
|
|
60
|
+
"""Encode the JWT with the given expire, header, and payload.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
exp (int | None): The expiration time in seconds.
|
|
64
|
+
nbf (int | None): The not-before time in seconds.
|
|
65
|
+
iss (str | None): The issuer.
|
|
66
|
+
sub (str | None): The subject.
|
|
67
|
+
aud (str | None): The audience.
|
|
68
|
+
header (dict[str, Any] | None): The header to include in the JWT.
|
|
69
|
+
payload (dict[str, Any] | None): The payload to include in the JWT.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
str: The encoded JWT.
|
|
73
|
+
"""
|
|
74
|
+
raise NotImplementedError
|
|
75
|
+
|
|
48
76
|
@abstractmethod
|
|
49
77
|
async def jwt_decode( # type: ignore[override]
|
|
50
78
|
self, token: str, check_exp: bool = True, check_list: bool = True
|
|
@@ -68,6 +68,45 @@ class Jam(BaseAsyncJam):
|
|
|
68
68
|
|
|
69
69
|
return token
|
|
70
70
|
|
|
71
|
+
async def jwt_encode(
|
|
72
|
+
self,
|
|
73
|
+
iss: str | None = None,
|
|
74
|
+
sub: str | None = None,
|
|
75
|
+
aud: str | None = None,
|
|
76
|
+
exp: int | None = None,
|
|
77
|
+
nbf: int | None = None,
|
|
78
|
+
*,
|
|
79
|
+
payload: dict[str, Any] | None = None,
|
|
80
|
+
header: dict[str, Any] | None = None,
|
|
81
|
+
) -> str:
|
|
82
|
+
"""Encode the JWT with the given expire, header, and payload.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
exp (int | None): The expiration time in seconds.
|
|
86
|
+
nbf (int | None): The not-before time in seconds.
|
|
87
|
+
iss (str | None): The issuer.
|
|
88
|
+
sub (str | None): The subject.
|
|
89
|
+
aud (str | None): The audience.
|
|
90
|
+
header (dict[str, Any] | None): The header to include in the JWT.
|
|
91
|
+
payload (dict[str, Any] | None): The payload to include in the JWT.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
str: The encoded JWT.
|
|
95
|
+
"""
|
|
96
|
+
assert self.jwt is not None
|
|
97
|
+
token = self.jwt.encode(
|
|
98
|
+
iss=iss,
|
|
99
|
+
sub=sub,
|
|
100
|
+
aud=aud,
|
|
101
|
+
exp=exp,
|
|
102
|
+
nbf=nbf,
|
|
103
|
+
payload=payload,
|
|
104
|
+
header=header,
|
|
105
|
+
)
|
|
106
|
+
if self.jwt.list and self.jwt.list.__list_type__ == "white":
|
|
107
|
+
self.jwt.list.add(token)
|
|
108
|
+
return token
|
|
109
|
+
|
|
71
110
|
async def jwt_decode(
|
|
72
111
|
self, token: str, check_exp: bool = True, check_list: bool = True
|
|
73
112
|
) -> dict[str, Any]:
|
|
@@ -1,49 +1,48 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
|
|
3
|
-
"""
|
|
4
|
-
All Jam exceptions
|
|
5
|
-
"""
|
|
3
|
+
"""All Jam exceptions"""
|
|
6
4
|
|
|
7
|
-
from .base import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
from .base import JamConfigurationError, JamError, JamValidationError
|
|
6
|
+
from .jose import (
|
|
7
|
+
JamJWEEncryptionError,
|
|
8
|
+
JamJWEDecryptionError,
|
|
9
|
+
JamJWKValidationError,
|
|
10
|
+
JamJWSVerificationError,
|
|
13
11
|
)
|
|
14
|
-
|
|
15
12
|
from .jwt import (
|
|
13
|
+
JamJWTEmptyPrivateKey,
|
|
14
|
+
JamJWTEmptySecretKey,
|
|
16
15
|
JamJWTExpired,
|
|
17
16
|
JamJWTInBlackList,
|
|
18
17
|
JamJWTNotInWhiteList,
|
|
19
|
-
JamJWTEmptyPrivateKey,
|
|
20
|
-
JamJWTEmptySecretKey,
|
|
21
18
|
JamJWTUnsupportedAlgorithm,
|
|
22
19
|
JamJWTValidationError,
|
|
23
20
|
)
|
|
24
|
-
|
|
21
|
+
from .oauth2 import (
|
|
22
|
+
JamOAuth2EmptyRaw,
|
|
23
|
+
JamOAuth2Error,
|
|
24
|
+
JamOAuth2ProviderNotConfigured,
|
|
25
|
+
)
|
|
25
26
|
from .paseto import (
|
|
26
|
-
JamPASETOInvalidSymmetricKey,
|
|
27
|
-
JamPASETOInvalidRSAKey,
|
|
28
27
|
JamPASETOInvalidED25519Key,
|
|
29
|
-
JamPASETOInvalidSecp384r1Key,
|
|
30
|
-
JamPASTOKeyVerificationError,
|
|
31
28
|
JamPASETOInvalidPurpose,
|
|
29
|
+
JamPASETOInvalidRSAKey,
|
|
30
|
+
JamPASETOInvalidSecp384r1Key,
|
|
31
|
+
JamPASETOInvalidSymmetricKey,
|
|
32
32
|
JamPASETOInvalidTokenFormat,
|
|
33
|
+
JamPASTOKeyVerificationError,
|
|
33
34
|
)
|
|
34
|
-
|
|
35
35
|
from .plugins import (
|
|
36
36
|
JamFlaskPluginConfigError,
|
|
37
37
|
JamFlaskPluginError,
|
|
38
38
|
JamLitestarPluginConfigError,
|
|
39
39
|
JamLitestarPluginError,
|
|
40
40
|
JamStarlettePluginConfigError,
|
|
41
|
-
JamStarlettePluginError
|
|
41
|
+
JamStarlettePluginError,
|
|
42
42
|
)
|
|
43
|
-
|
|
44
43
|
from .sessions import (
|
|
45
|
-
JamSessionNotFound,
|
|
46
44
|
JamSessionEmptyAESKey,
|
|
45
|
+
JamSessionNotFound,
|
|
47
46
|
)
|
|
48
47
|
|
|
49
48
|
|
|
@@ -61,6 +60,10 @@ __all__ = [
|
|
|
61
60
|
"JamJWTEmptySecretKey",
|
|
62
61
|
"JamJWTUnsupportedAlgorithm",
|
|
63
62
|
"JamJWTValidationError",
|
|
63
|
+
"JamJWSVerificationError",
|
|
64
|
+
"JamJWKValidationError",
|
|
65
|
+
"JamJWEEncryptionError",
|
|
66
|
+
"JamJWEDecryptionError",
|
|
64
67
|
"JamPASETOInvalidSymmetricKey",
|
|
65
68
|
"JamPASETOInvalidRSAKey",
|
|
66
69
|
"JamPASETOInvalidED25519Key",
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from .base import JamValidationError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class JamJWSVerificationError(JamValidationError):
|
|
7
|
+
default_message = "JWS signature verification failed."
|
|
8
|
+
default_code = "jws.verification_error"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class JamJWKValidationError(JamValidationError):
|
|
12
|
+
default_message = "JWK validation failed."
|
|
13
|
+
default_code = "jwk.validation_error"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class JamJWEEncryptionError(JamValidationError):
|
|
17
|
+
default_message = "JWE encryption failed."
|
|
18
|
+
default_code = "jwe.encryption_error"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class JamJWEDecryptionError(JamValidationError):
|
|
22
|
+
default_message = "JWE decryption failed."
|
|
23
|
+
default_code = "jwe.decryption_error"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
|
|
3
|
-
from .base import JamError, JamValidationError
|
|
3
|
+
from .base import JamConfigurationError, JamError, JamValidationError
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class JamJWTExpired(JamError):
|
|
@@ -24,7 +24,9 @@ class JamJWTEmptySecretKey(JamConfigurationError):
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class JamJWTEmptyPrivateKey(JamConfigurationError):
|
|
27
|
-
default_message =
|
|
27
|
+
default_message = (
|
|
28
|
+
"For asymmetric encryption, you must specify `private_key`."
|
|
29
|
+
)
|
|
28
30
|
default_code = "jwt.config.empty_private_key"
|
|
29
31
|
|
|
30
32
|
|
|
@@ -5,9 +5,9 @@ from typing import Any
|
|
|
5
5
|
import uuid
|
|
6
6
|
|
|
7
7
|
from jam.__base__ import BaseJam
|
|
8
|
+
from jam.__deprecated__ import deprecated
|
|
8
9
|
from jam.exceptions import (
|
|
9
10
|
JamConfigurationError,
|
|
10
|
-
JamJWTExpired,
|
|
11
11
|
JamJWTInBlackList,
|
|
12
12
|
JamJWTNotInWhiteList,
|
|
13
13
|
)
|
|
@@ -17,18 +17,24 @@ class Jam(BaseJam):
|
|
|
17
17
|
"""Main instance."""
|
|
18
18
|
|
|
19
19
|
MODULES: dict[str, str] = {
|
|
20
|
-
"jwt": "jam.
|
|
20
|
+
"jwt": "jam.jose.JWT",
|
|
21
21
|
"session": "jam.sessions.create_instance",
|
|
22
22
|
"oauth2": "jam.oauth2.create_instance",
|
|
23
23
|
"paseto": "jam.paseto.create_instance",
|
|
24
24
|
"otp": "jam.otp.__base__.OTPConfig",
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
@deprecated(
|
|
28
|
+
"This method is deprecated; the JWT payload is generated automatically in accordance with the specification."
|
|
29
|
+
)
|
|
27
30
|
def jwt_make_payload(
|
|
28
31
|
self, exp: int | None, data: dict[str, Any]
|
|
29
32
|
) -> dict[str, Any]:
|
|
30
33
|
"""Make JWT-specific payload.
|
|
31
34
|
|
|
35
|
+
!!! Deprecated
|
|
36
|
+
This method is deprecated; the JWT payload is generated automatically in accordance with the specification.
|
|
37
|
+
|
|
32
38
|
Args:
|
|
33
39
|
exp (int | None): Token expire
|
|
34
40
|
data (dict[str, Any]): Data to payload
|
|
@@ -44,9 +50,13 @@ class Jam(BaseJam):
|
|
|
44
50
|
payload = payload | data
|
|
45
51
|
return payload
|
|
46
52
|
|
|
53
|
+
@deprecated("Use jam.jwt_encode")
|
|
47
54
|
def jwt_create(self, payload: dict[str, Any]) -> str:
|
|
48
55
|
"""Create JWT token.
|
|
49
56
|
|
|
57
|
+
!!! Deprecated
|
|
58
|
+
Use Jam.jwt_encode
|
|
59
|
+
|
|
50
60
|
Args:
|
|
51
61
|
payload (dict[str, Any]): Data payload
|
|
52
62
|
|
|
@@ -68,8 +78,52 @@ class Jam(BaseJam):
|
|
|
68
78
|
|
|
69
79
|
return token
|
|
70
80
|
|
|
81
|
+
def jwt_encode(
|
|
82
|
+
self,
|
|
83
|
+
iss: str | None = None,
|
|
84
|
+
sub: str | None = None,
|
|
85
|
+
aud: str | None = None,
|
|
86
|
+
exp: int | None = None,
|
|
87
|
+
nbf: int | None = None,
|
|
88
|
+
*,
|
|
89
|
+
payload: dict[str, Any] | None = None,
|
|
90
|
+
header: dict[str, Any] | None = None,
|
|
91
|
+
) -> str:
|
|
92
|
+
"""Encode the JWT with the given expire, header, and payload.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
exp (int | None): The expiration time in seconds.
|
|
96
|
+
nbf (int | None): The not-before time in seconds.
|
|
97
|
+
iss (str | None): The issuer.
|
|
98
|
+
sub (str | None): The subject.
|
|
99
|
+
aud (str | None): The audience.
|
|
100
|
+
header (dict[str, Any] | None): The header to include in the JWT.
|
|
101
|
+
payload (dict[str, Any] | None): The payload to include in the JWT.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
str: The encoded JWT.
|
|
105
|
+
"""
|
|
106
|
+
assert self.jwt is not None
|
|
107
|
+
token = self.jwt.encode(
|
|
108
|
+
iss=iss,
|
|
109
|
+
sub=sub,
|
|
110
|
+
aud=aud,
|
|
111
|
+
exp=exp,
|
|
112
|
+
nbf=nbf,
|
|
113
|
+
payload=payload,
|
|
114
|
+
header=header,
|
|
115
|
+
)
|
|
116
|
+
if self.jwt.list and self.jwt.list.__list_type__ == "white":
|
|
117
|
+
self.jwt.list.add(token)
|
|
118
|
+
return token
|
|
119
|
+
|
|
71
120
|
def jwt_decode(
|
|
72
|
-
self,
|
|
121
|
+
self,
|
|
122
|
+
token: str,
|
|
123
|
+
check_exp: bool = True,
|
|
124
|
+
check_list: bool = True,
|
|
125
|
+
check_nbf: bool = False,
|
|
126
|
+
include_headers: bool = False,
|
|
73
127
|
) -> dict[str, Any]:
|
|
74
128
|
"""Verify and decode JWT token.
|
|
75
129
|
|
|
@@ -77,6 +131,8 @@ class Jam(BaseJam):
|
|
|
77
131
|
token (str): JWT token
|
|
78
132
|
check_exp (bool): Check expire
|
|
79
133
|
check_list (bool): Check white/black list. Docs: https://jam.makridenko.ru/jwt/lists/what/
|
|
134
|
+
check_nbf (bool): Check not-before time
|
|
135
|
+
include_headers (bool): Include headers in the decoded payload
|
|
80
136
|
|
|
81
137
|
Returns:
|
|
82
138
|
dict[str, Any]: Decoded payload
|
|
@@ -91,15 +147,21 @@ class Jam(BaseJam):
|
|
|
91
147
|
f"Verifying JWT token (length: {len(token)} chars), check_exp={check_exp}, check_list={check_list}"
|
|
92
148
|
)
|
|
93
149
|
assert self.jwt is not None
|
|
94
|
-
|
|
150
|
+
data = self.jwt.decode(token, include_headers)
|
|
151
|
+
|
|
152
|
+
if include_headers:
|
|
153
|
+
payload = data
|
|
154
|
+
else:
|
|
155
|
+
payload = data
|
|
156
|
+
if isinstance(payload, bytes):
|
|
157
|
+
import json
|
|
158
|
+
|
|
159
|
+
payload = json.loads(payload)
|
|
160
|
+
|
|
95
161
|
self._logger.debug(
|
|
96
162
|
f"JWT token verified successfully, payload keys: {list(payload.keys())}"
|
|
97
163
|
)
|
|
98
164
|
|
|
99
|
-
if check_exp:
|
|
100
|
-
if payload["exp"] < datetime.datetime.now().timestamp():
|
|
101
|
-
raise JamJWTExpired
|
|
102
|
-
|
|
103
165
|
if check_list:
|
|
104
166
|
if not self.jwt.list:
|
|
105
167
|
raise JamConfigurationError(
|
|
@@ -391,9 +453,9 @@ class Jam(BaseJam):
|
|
|
391
453
|
Returns:
|
|
392
454
|
dict: Payload
|
|
393
455
|
"""
|
|
394
|
-
from jam.paseto.utils import payload_maker
|
|
456
|
+
from jam.paseto.utils import payload_maker as pm
|
|
395
457
|
|
|
396
|
-
return
|
|
458
|
+
return pm(expire=exp, data=data)
|
|
397
459
|
|
|
398
460
|
def paseto_create(
|
|
399
461
|
self,
|