jamlib 3.2.0rc0__tar.gz → 3.2.0rc2__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.
Files changed (124) hide show
  1. {jamlib-3.2.0rc0/src/jamlib.egg-info → jamlib-3.2.0rc2}/PKG-INFO +3 -3
  2. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/README.md +2 -2
  3. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/pyproject.toml +1 -1
  4. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/__init__.py +1 -1
  5. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/__base__.py +8 -0
  6. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/instance.py +21 -9
  7. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/sessions/__base__.py +5 -1
  8. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/flask/extensions.py +2 -0
  9. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/litestar/plugins.py +3 -0
  10. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/starlette/backends.py +2 -0
  11. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/__base__.py +16 -11
  12. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/jws.py +4 -0
  13. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/jwt.py +12 -10
  14. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/paseto/v1.py +4 -0
  15. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/paseto/v2.py +4 -0
  16. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/paseto/v3.py +4 -0
  17. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/paseto/v4.py +4 -0
  18. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/sessions/__base__.py +5 -1
  19. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/tests/clients.py +4 -0
  20. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/config_maker.py +15 -0
  21. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2/src/jamlib.egg-info}/PKG-INFO +3 -3
  22. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/LICENSE.md +0 -0
  23. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/setup.cfg +0 -0
  24. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/__base__.py +0 -0
  25. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/__base_encoder__.py +0 -0
  26. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/__deprecated__.py +0 -0
  27. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/__init__.py +0 -0
  28. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/jwt/__init__.py +0 -0
  29. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/oauth2/__base__.py +0 -0
  30. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/oauth2/__init__.py +0 -0
  31. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/oauth2/builtin/__init__.py +0 -0
  32. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/oauth2/builtin/github.py +0 -0
  33. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/oauth2/builtin/gitlab.py +0 -0
  34. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/oauth2/builtin/google.py +0 -0
  35. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/oauth2/builtin/yandex.py +0 -0
  36. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/oauth2/client.py +0 -0
  37. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/sessions/__init__.py +0 -0
  38. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/sessions/json.py +0 -0
  39. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/aio/sessions/redis.py +0 -0
  40. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/cli/__init__.py +0 -0
  41. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/cli/cli.py +0 -0
  42. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/cli/commands/__init__.py +0 -0
  43. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/cli/commands/keys.py +0 -0
  44. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/cli/commands/password.py +0 -0
  45. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/encoders.py +0 -0
  46. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/exceptions/__init__.py +0 -0
  47. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/exceptions/base.py +0 -0
  48. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/exceptions/jose.py +0 -0
  49. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/exceptions/jwt.py +0 -0
  50. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/exceptions/oauth2.py +0 -0
  51. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/exceptions/paseto.py +0 -0
  52. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/exceptions/plugins.py +0 -0
  53. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/exceptions/sessions.py +0 -0
  54. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/__init__.py +0 -0
  55. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/fastapi/__init__.py +0 -0
  56. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/flask/__init__.py +0 -0
  57. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/flask/objects.py +0 -0
  58. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/litestar/__init__.py +0 -0
  59. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/litestar/middleware.py +0 -0
  60. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/litestar/objects.py +0 -0
  61. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/starlette/__init__.py +0 -0
  62. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/ext/starlette/objects.py +0 -0
  63. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/instance.py +0 -0
  64. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/__algorithms__.py +0 -0
  65. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/__init__.py +0 -0
  66. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/jwe.py +0 -0
  67. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/jwk.py +0 -0
  68. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/lists/__base__.py +0 -0
  69. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/lists/__init__.py +0 -0
  70. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/lists/json.py +0 -0
  71. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/lists/memory.py +0 -0
  72. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/lists/redis.py +0 -0
  73. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jose/utils.py +0 -0
  74. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jwt/__algorithms__.py +0 -0
  75. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jwt/__base__.py +0 -0
  76. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jwt/__init__.py +0 -0
  77. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jwt/__types__.py +0 -0
  78. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jwt/lists/__base__.py +0 -0
  79. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jwt/lists/__init__.py +0 -0
  80. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jwt/lists/json.py +0 -0
  81. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jwt/lists/redis.py +0 -0
  82. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jwt/module.py +0 -0
  83. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/jwt/utils.py +0 -0
  84. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/logger.py +0 -0
  85. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/oauth2/__base__.py +0 -0
  86. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/oauth2/__init__.py +0 -0
  87. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/oauth2/builtin/__init__.py +0 -0
  88. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/oauth2/builtin/github.py +0 -0
  89. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/oauth2/builtin/gitlab.py +0 -0
  90. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/oauth2/builtin/google.py +0 -0
  91. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/oauth2/builtin/yandex.py +0 -0
  92. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/oauth2/client.py +0 -0
  93. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/otp/__base__.py +0 -0
  94. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/otp/__init__.py +0 -0
  95. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/otp/hotp.py +0 -0
  96. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/otp/totp.py +0 -0
  97. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/paseto/__base__.py +0 -0
  98. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/paseto/__init__.py +0 -0
  99. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/paseto/utils.py +0 -0
  100. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/plugins/__base__.py +0 -0
  101. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/plugins/__init__.py +0 -0
  102. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/py.typed +0 -0
  103. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/sessions/__init__.py +0 -0
  104. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/sessions/json.py +0 -0
  105. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/sessions/redis.py +0 -0
  106. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/tests/__init__.py +0 -0
  107. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/tests/fakers.py +0 -0
  108. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/__init__.py +0 -0
  109. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/aes.py +0 -0
  110. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/await_maybe.py +0 -0
  111. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/basic_auth.py +0 -0
  112. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/ed.py +0 -0
  113. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/otp_keys.py +0 -0
  114. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/rsa.py +0 -0
  115. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/salt_hash.py +0 -0
  116. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/symmetric.py +0 -0
  117. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/version_check.py +0 -0
  118. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/xchacha20poly1305.py +0 -0
  119. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jam/utils/xor.py +0 -0
  120. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jamlib.egg-info/SOURCES.txt +0 -0
  121. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jamlib.egg-info/dependency_links.txt +0 -0
  122. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jamlib.egg-info/entry_points.txt +0 -0
  123. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jamlib.egg-info/requires.txt +0 -0
  124. {jamlib-3.2.0rc0 → jamlib-3.2.0rc2}/src/jamlib.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jamlib
3
- Version: 3.2.0rc0
3
+ Version: 3.2.0rc2
4
4
  Summary: Simple and universal library for authorization.
5
5
  Author-email: Makridenko Adrian <adrianmakridenko@duck.com>, Ksenia Travnikova <kseniatravnikova@duck.com>
6
6
  License: Apache-2.0
@@ -77,7 +77,7 @@ from jam import Jam
77
77
 
78
78
  jam = Jam(config="config.toml")
79
79
 
80
- jwt = jam.jwt_create({"user": 1})
80
+ jwt = jam.jwt_encode(payload={"user": 1})
81
81
  session_id = jam.session_create(session_key="username", data={"user": 1})
82
82
  otp_code = jam.otp_code(secret="3DB7FOAOFBCI3WFDRE7EPF43CA")
83
83
  ```
@@ -85,7 +85,7 @@ otp_code = jam.otp_code(secret="3DB7FOAOFBCI3WFDRE7EPF43CA")
85
85
  ## Why Jam?
86
86
  Jam is a library that provides the most popular AUTH* mechanisms right out of the box.
87
87
 
88
- * [JOSE](https://jam.makridenko.ru/usage/jose/index/)
88
+ * [JOSE](https://jam.makridenko.ru/usage/jose/)
89
89
  * [PASETO](https://jam.makridenko.ru/usage/paseto/)
90
90
  * [Server side sessions](https://jam.makridenko.ru/usage/sessions/)
91
91
  * [OTP](https://jam.makridenko.ru/usage/otp/)
@@ -24,7 +24,7 @@ from jam import Jam
24
24
 
25
25
  jam = Jam(config="config.toml")
26
26
 
27
- jwt = jam.jwt_create({"user": 1})
27
+ jwt = jam.jwt_encode(payload={"user": 1})
28
28
  session_id = jam.session_create(session_key="username", data={"user": 1})
29
29
  otp_code = jam.otp_code(secret="3DB7FOAOFBCI3WFDRE7EPF43CA")
30
30
  ```
@@ -32,7 +32,7 @@ otp_code = jam.otp_code(secret="3DB7FOAOFBCI3WFDRE7EPF43CA")
32
32
  ## Why Jam?
33
33
  Jam is a library that provides the most popular AUTH* mechanisms right out of the box.
34
34
 
35
- * [JOSE](https://jam.makridenko.ru/usage/jose/index/)
35
+ * [JOSE](https://jam.makridenko.ru/usage/jose/)
36
36
  * [PASETO](https://jam.makridenko.ru/usage/paseto/)
37
37
  * [Server side sessions](https://jam.makridenko.ru/usage/sessions/)
38
38
  * [OTP](https://jam.makridenko.ru/usage/otp/)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "jamlib"
3
- version = "3.2.0rc0"
3
+ version = "3.2.0rc2"
4
4
  description = "Simple and universal library for authorization."
5
5
  authors = [
6
6
  {name = "Makridenko Adrian",email = "adrianmakridenko@duck.com"},
@@ -10,5 +10,5 @@ from jam.__base__ import BaseJam
10
10
  from jam.instance import Jam
11
11
 
12
12
 
13
- __version__ = "3.2.0rc0"
13
+ __version__ = "3.2.0rc2"
14
14
  __all__ = ["Jam", "BaseJam"]
@@ -4,6 +4,7 @@ from abc import abstractmethod
4
4
  from typing import Any
5
5
 
6
6
  from jam.__base__ import BaseJam
7
+ from jam.__deprecated__ import deprecated
7
8
  from jam.aio.oauth2.__base__ import BaseAsyncOAuth2Client
8
9
  from jam.aio.sessions.__base__ import BaseAsyncSessionModule
9
10
  from jam.jose.__base__ import BaseJWE, BaseJWS
@@ -21,11 +22,17 @@ class BaseAsyncJam(BaseJam):
21
22
  jwe: BaseJWE | None = None # type: ignore[override]
22
23
 
23
24
  @abstractmethod
25
+ @deprecated(
26
+ "This method is deprecated; the JWT payload is generated automatically in accordance with the specification."
27
+ )
24
28
  async def jwt_make_payload( # type: ignore[override]
25
29
  self, exp: int | None, data: dict[str, Any]
26
30
  ) -> dict[str, Any]:
27
31
  """Make JWT-specific payload.
28
32
 
33
+ !!! Deprecated
34
+ This method is deprecated; the JWT payload is generated automatically in accordance with the specification.
35
+
29
36
  Args:
30
37
  exp (int | None): Token expire, if None -> use default
31
38
  data (dict[str, Any]): Data to payload
@@ -36,6 +43,7 @@ class BaseAsyncJam(BaseJam):
36
43
  raise NotImplementedError
37
44
 
38
45
  @abstractmethod
46
+ @deprecated("Use jam.jwt_encode")
39
47
  async def jwt_create( # type: ignore[override]
40
48
  self, payload: dict[str, Any]
41
49
  ) -> str:
@@ -1,10 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- import datetime
4
3
  import time
5
4
  from typing import Any
6
5
  import uuid
7
6
 
7
+ from jam.__deprecated__ import deprecated
8
8
  from jam.aio.__base__ import BaseAsyncJam
9
9
  from jam.exceptions import (
10
10
  JamConfigurationError,
@@ -30,11 +30,17 @@ class Jam(BaseAsyncJam):
30
30
  "otp": "jam.otp.__base__.OTPConfig",
31
31
  }
32
32
 
33
+ @deprecated(
34
+ "This method is deprecated; the JWT payload is generated automatically in accordance with the specification."
35
+ )
33
36
  async def jwt_make_payload(
34
37
  self, exp: int | None, data: dict[str, Any]
35
38
  ) -> dict[str, Any]:
36
39
  """Make JWT-specific payload.
37
40
 
41
+ !!! Deprecated
42
+ This method is deprecated; the JWT payload is generated automatically in accordance with the specification.
43
+
38
44
  Args:
39
45
  exp (int | None): Token expire
40
46
  data (dict[str, Any]): Data to payload
@@ -42,17 +48,22 @@ class Jam(BaseAsyncJam):
42
48
  Returns:
43
49
  dict[str, Any]: Payload
44
50
  """
51
+ now = time.time()
45
52
  payload = {
46
- "iat": datetime.datetime.now().timestamp(),
47
- "exp": (datetime.datetime.now().timestamp() + exp) if exp else None,
53
+ "iat": now,
54
+ "exp": (now + exp) if exp else None,
48
55
  "jti": str(uuid.uuid4()),
49
56
  }
50
57
  payload = payload | data
51
58
  return payload
52
59
 
60
+ @deprecated("Use jam.jwt_encode")
53
61
  async def jwt_create(self, payload: dict[str, Any]) -> str:
54
62
  """Create JWT token.
55
63
 
64
+ !!! Deprecated
65
+ Use Jam.jwt_encode
66
+
56
67
  Args:
57
68
  payload (dict[str, Any]): Data payload
58
69
 
@@ -244,7 +255,10 @@ class Jam(BaseAsyncJam):
244
255
  """
245
256
  assert self.jwe is not None
246
257
  self._logger.debug(f"Encrypting data with JWE, header: {header}")
247
- token = self.jwe.encrypt(data, header)
258
+ token = self.jwe.encrypt(
259
+ self._serializer.dumps(data) if isinstance(data, dict) else data,
260
+ header,
261
+ )
248
262
  self._logger.debug(f"JWE token created, length: {len(token)}")
249
263
  return token
250
264
 
@@ -369,8 +383,8 @@ class Jam(BaseAsyncJam):
369
383
  async def otp_uri(
370
384
  self,
371
385
  secret: str,
372
- name: str | None = None,
373
- issuer: str | None = None,
386
+ name: str,
387
+ issuer: str,
374
388
  counter: int | None = None,
375
389
  ) -> str:
376
390
  """Generates an otpauth:// URI for Google Authenticator.
@@ -388,9 +402,7 @@ class Jam(BaseAsyncJam):
388
402
  assert self._otp is not None
389
403
  return self._otp(
390
404
  secret=secret, digits=self.otp.digits, digest=self.otp.digest
391
- ).provisioning_uri(
392
- name=name or "", issuer=issuer or "", counter=counter
393
- )
405
+ ).provisioning_uri(name=name, issuer=issuer, counter=counter)
394
406
 
395
407
  async def otp_verify_code(
396
408
  self,
@@ -7,9 +7,11 @@ from uuid import uuid4
7
7
 
8
8
  from cryptography.fernet import Fernet
9
9
 
10
- from jam.encoders import BaseEncoder, JsonEncoder
10
+ from jam.__base_encoder__ import BaseEncoder
11
+ from jam.encoders import JsonEncoder
11
12
  from jam.exceptions import JamSessionEmptyAESKey
12
13
  from jam.logger import BaseLogger
14
+ from jam.utils.config_maker import __key_loader__
13
15
 
14
16
 
15
17
  class BaseAsyncSessionModule(ABC):
@@ -32,6 +34,8 @@ class BaseAsyncSessionModule(ABC):
32
34
  raise JamSessionEmptyAESKey
33
35
  if is_session_crypt:
34
36
  assert session_aes_secret is not None
37
+ if isinstance(session_aes_secret, str):
38
+ session_aes_secret = __key_loader__(session_aes_secret)
35
39
  self._code_session_key = Fernet(session_aes_secret)
36
40
 
37
41
  def __encode_session_id__(self, data: str) -> str:
@@ -89,6 +89,8 @@ class BaseAuthExtension(BaseExtension):
89
89
  _config: dict[str, Any] | None = (
90
90
  __config_maker__(config, pointer) if config else None
91
91
  )
92
+ if _config and _config.get("jose", None) and self.MODULE == create_jwt:
93
+ _config = _config["jose"]
92
94
 
93
95
  params = _config.pop(self._CONFIG_KEY) if _config else kwargs
94
96
  super().__init__(app=app, **params)
@@ -76,6 +76,9 @@ class BasePlugin(InitPlugin):
76
76
  __config_maker__(config, pointer) if config else None
77
77
  )
78
78
 
79
+ # FIXME: Make config wrapper
80
+ if _config and _config.get("jose", None) and self.MODULE == create_jwt:
81
+ _config = _config["jose"]
79
82
  params = _config.pop(self._CONFIG_KEY) if _config else kwargs
80
83
  self._setup_config(params)
81
84
  self._middleware = None
@@ -81,6 +81,8 @@ class BaseBackend(AuthenticationBackend):
81
81
  try:
82
82
  if config:
83
83
  config_ = __config_maker__(config, pointer)[self._CONFIG_KEY]
84
+ if config_.get("jose", None) and self.MODULE == create_jwt:
85
+ config_ = config_["jose"]
84
86
  self._auth = self.MODULE(**config_)
85
87
  else:
86
88
  self._auth = self.MODULE(**kwargs)
@@ -73,34 +73,39 @@ class BaseJWT(ABC):
73
73
  @abstractmethod
74
74
  def encrypt(
75
75
  self,
76
- payload: dict[str, Any] | str,
76
+ plaintext: bytes | str | dict[str, Any],
77
77
  header: dict[str, Any] | None = None,
78
78
  ) -> str:
79
- """Encrypt payload using JWE.
79
+ """Encrypt plaintext.
80
80
 
81
- Creates JWE or JWS+JWE token (sign then encrypt).
81
+ Produces JWE Compact Serialization:
82
+ BASE64URL(header).BASE64URL(encrypted_key).BASE64URL(iv).BASE64URL(ciphertext).BASE64URL(tag)
82
83
 
83
84
  Args:
84
- payload: Data to encrypt. If dict, will be JSON encoded.
85
- header: Additional JWE header.
85
+ plaintext: Data to encrypt. If str, will be encoded to UTF-8.
86
+ If dict, will be JSON encoded.
87
+ header: JWE header (must include 'alg' and 'enc').
86
88
 
87
89
  Returns:
88
- str: Encrypted JWT (JWE or JWS+JWE).
90
+ JWE compact serialization string.
91
+
92
+ Raises:
93
+ JamJWEEncryptionError: If encryption fails.
89
94
  """
90
95
  raise NotImplementedError
91
96
 
92
97
  @abstractmethod
93
- def decrypt(self, token: str) -> dict[str, Any]:
94
- """Decrypt JWE or JWS+JWE token.
98
+ def decrypt(self, token: str) -> dict[str, Any] | bytes:
99
+ """Decrypt JWE token.
95
100
 
96
101
  Args:
97
- token: Encrypted JWT token.
102
+ token: JWE compact serialization string.
98
103
 
99
104
  Returns:
100
- dict[str, Any]: Decrypted payload.
105
+ bytes: Decrypted plaintext.
101
106
 
102
107
  Raises:
103
- ValueError: If token is invalid or decryption fails.
108
+ JamJWEDecryptionError: If decryption fails.
104
109
  """
105
110
  raise NotImplementedError
106
111
 
@@ -15,6 +15,7 @@ from jam.jose.__algorithms__ import (
15
15
  from jam.jose.__base__ import BaseJWS
16
16
  from jam.jose.utils import __base64url_decode__, __base64url_encode__
17
17
  from jam.logger import BaseLogger, logger
18
+ from jam.utils.config_maker import __key_loader__
18
19
 
19
20
 
20
21
  if TYPE_CHECKING:
@@ -46,6 +47,9 @@ class JWS(BaseJWS):
46
47
  self._alg = alg.upper()
47
48
  self._validate_algorithm(self._alg)
48
49
 
50
+ if isinstance(key, str):
51
+ key = __key_loader__(key)
52
+
49
53
  if isinstance(key, JWKClass):
50
54
  key = key._to_keylike()
51
55
 
@@ -9,12 +9,12 @@ import uuid
9
9
  from jam.__base_encoder__ import BaseEncoder
10
10
  from jam.encoders import JsonEncoder
11
11
  from jam.exceptions import (
12
+ JamConfigurationError,
12
13
  JamJWTExpired,
13
14
  JamJWTNotYetValid,
14
15
  JamJWTUnsupportedAlgorithm,
15
16
  )
16
17
  from jam.exceptions.jose import (
17
- JamConfigurationError,
18
18
  JamInvalidKeyTypeError,
19
19
  JamJWSVerificationError,
20
20
  )
@@ -30,6 +30,7 @@ from jam.jose.jwe import JWE
30
30
  from jam.jose.jws import JWS
31
31
  from jam.jose.lists import BaseJWTList
32
32
  from jam.logger import BaseLogger, logger
33
+ from jam.utils.config_maker import __key_loader__
33
34
 
34
35
 
35
36
  if TYPE_CHECKING:
@@ -153,6 +154,7 @@ class JWT(BaseJWT):
153
154
  if isinstance(key, JWKClass):
154
155
  return key._to_keylike()
155
156
  if isinstance(key, str):
157
+ key = __key_loader__(key)
156
158
  return key.encode() if key else key
157
159
  return key
158
160
 
@@ -498,7 +500,7 @@ class JWT(BaseJWT):
498
500
 
499
501
  def encrypt(
500
502
  self,
501
- payload: dict[str, Any] | str,
503
+ plaintext: bytes | str | dict[str, Any],
502
504
  header: dict[str, Any] | None = None,
503
505
  ) -> str:
504
506
  """Encrypt payload using JWE.
@@ -508,8 +510,8 @@ class JWT(BaseJWT):
508
510
  2. Use JWS result as plaintext for JWE (encrypt)
509
511
 
510
512
  Args:
511
- payload: Data to encrypt. If dict, will be JSON encoded.
512
- header: Additional JWE header.
513
+ plaintext (bytes | str | dict[str, Any]): Data to encrypt. If dict, will be JSON encoded.
514
+ header (dict[str, Any] | None): Additional JWE header.
513
515
 
514
516
  Returns:
515
517
  str: Encrypted JWT (JWE or JWS+JWE).
@@ -522,12 +524,12 @@ class JWT(BaseJWT):
522
524
  message="JWE not configured. Provide 'enc' parameter."
523
525
  )
524
526
 
525
- if isinstance(payload, dict):
526
- payload_bytes = self._serializer.dumps(payload)
527
- elif isinstance(payload, str):
528
- payload_bytes = payload.encode("utf-8")
527
+ if isinstance(plaintext, dict):
528
+ payload_bytes = self._serializer.dumps(plaintext)
529
+ elif isinstance(plaintext, str):
530
+ payload_bytes = plaintext.encode("utf-8")
529
531
  else:
530
- payload_bytes = payload
532
+ payload_bytes = plaintext
531
533
 
532
534
  if self.jws and self.jwe:
533
535
  _base_header = {"alg": self._alg, "typ": "JWT"}
@@ -538,7 +540,7 @@ class JWT(BaseJWT):
538
540
  else:
539
541
  return self.jwe.encrypt(payload_bytes, header)
540
542
 
541
- def decrypt(self, token: str) -> dict[str, Any]:
543
+ def decrypt(self, token: str) -> dict[str, Any] | bytes:
542
544
  """Decrypt JWE or JWS+JWE token.
543
545
 
544
546
  If token is JWS+JWE (sign then encrypt):
@@ -29,6 +29,7 @@ from jam.paseto.utils import (
29
29
  base64url_decode,
30
30
  base64url_encode,
31
31
  )
32
+ from jam.utils.config_maker import __key_loader__
32
33
 
33
34
 
34
35
  class PASETOv1(BasePASETO):
@@ -59,6 +60,7 @@ class PASETOv1(BasePASETO):
59
60
 
60
61
  if purpose == "local":
61
62
  if isinstance(secret_key, str):
63
+ secret_key = __key_loader__(secret_key)
62
64
  raw = base64url_decode(secret_key.encode("utf-8"))
63
65
  else:
64
66
  raw = secret_key
@@ -75,6 +77,8 @@ class PASETOv1(BasePASETO):
75
77
  return inst
76
78
 
77
79
  elif purpose == "public":
80
+ if isinstance(secret_key, str):
81
+ secret_key = __key_loader__(secret_key)
78
82
  if isinstance(secret_key, RSAPrivateKey):
79
83
  inst._secret = secret_key
80
84
  inst._public_key = secret_key.public_key()
@@ -19,6 +19,7 @@ from jam.exceptions import (
19
19
  )
20
20
  from jam.paseto.__base__ import PASETO, BasePASETO
21
21
  from jam.paseto.utils import __pae__, base64url_decode, base64url_encode
22
+ from jam.utils.config_maker import __key_loader__
22
23
  from jam.utils.xchacha20poly1305 import (
23
24
  xchacha20poly1305_decrypt,
24
25
  xchacha20poly1305_encrypt,
@@ -42,6 +43,7 @@ class PASETOv2(BasePASETO):
42
43
 
43
44
  if purpose == "local":
44
45
  if isinstance(secret_key, str):
46
+ secret_key = __key_loader__(secret_key)
45
47
  secret_key = base64.urlsafe_b64decode(secret_key + "==")
46
48
  if not isinstance(secret_key, bytes) or len(secret_key) != 32:
47
49
  raise ValueError("v2.local key must be 32 bytes")
@@ -49,6 +51,8 @@ class PASETOv2(BasePASETO):
49
51
  return k
50
52
 
51
53
  elif purpose == "public":
54
+ if isinstance(secret_key, str):
55
+ secret_key = __key_loader__(secret_key)
52
56
  if isinstance(secret_key, Ed25519PrivateKey):
53
57
  k._secret = secret_key
54
58
  k._public_key = secret_key.public_key()
@@ -30,6 +30,7 @@ from jam.paseto.utils import (
30
30
  base64url_decode,
31
31
  base64url_encode,
32
32
  )
33
+ from jam.utils.config_maker import __key_loader__
33
34
 
34
35
 
35
36
  class PASETOv3(BasePASETO):
@@ -56,6 +57,7 @@ class PASETOv3(BasePASETO):
56
57
 
57
58
  if purpose == "local":
58
59
  if isinstance(secret_key, str):
60
+ secret_key = __key_loader__(secret_key)
59
61
  try:
60
62
  raw = base64url_decode(secret_key.encode("utf-8"))
61
63
  except Exception:
@@ -72,6 +74,8 @@ class PASETOv3(BasePASETO):
72
74
  return inst
73
75
 
74
76
  elif purpose == "public":
77
+ if isinstance(secret_key, str):
78
+ secret_key = __key_loader__(secret_key)
75
79
  if hasattr(secret_key, "sign") and isinstance(
76
80
  secret_key, ec.EllipticCurvePrivateKey
77
81
  ):
@@ -21,6 +21,7 @@ from jam.exceptions import (
21
21
  )
22
22
  from jam.paseto.__base__ import PASETO, BasePASETO
23
23
  from jam.paseto.utils import __pae__, base64url_decode, base64url_encode
24
+ from jam.utils.config_maker import __key_loader__
24
25
  from jam.utils.xchacha20poly1305 import (
25
26
  xchacha20poly1305_decrypt,
26
27
  xchacha20poly1305_encrypt,
@@ -53,6 +54,7 @@ class PASETOv4(BasePASETO):
53
54
 
54
55
  if purpose == "local":
55
56
  if isinstance(secret_key, str):
57
+ secret_key = __key_loader__(secret_key)
56
58
  raw = base64url_decode(secret_key.encode("utf-8"))
57
59
  else:
58
60
  raw = secret_key
@@ -65,6 +67,8 @@ class PASETOv4(BasePASETO):
65
67
 
66
68
  elif purpose == "public":
67
69
  # Ed25519 objects
70
+ if isinstance(secret_key, str):
71
+ secret_key = __key_loader__(secret_key)
68
72
  if isinstance(secret_key, Ed25519PrivateKey):
69
73
  inst._secret = secret_key
70
74
  inst._public_key = secret_key.public_key()
@@ -7,9 +7,11 @@ from uuid import uuid4
7
7
 
8
8
  from cryptography.fernet import Fernet
9
9
 
10
- from jam.encoders import BaseEncoder, JsonEncoder
10
+ from jam.__base_encoder__ import BaseEncoder
11
+ from jam.encoders import JsonEncoder
11
12
  from jam.exceptions import JamSessionEmptyAESKey
12
13
  from jam.logger import BaseLogger
14
+ from jam.utils.config_maker import __key_loader__
13
15
 
14
16
 
15
17
  class BaseSessionModule(ABC):
@@ -76,6 +78,8 @@ class BaseSessionModule(ABC):
76
78
  raise JamSessionEmptyAESKey
77
79
  if is_session_crypt:
78
80
  assert session_aes_secret is not None
81
+ if isinstance(session_aes_secret, str):
82
+ session_aes_secret = __key_loader__(session_aes_secret)
79
83
  self._code_session_key = Fernet(session_aes_secret)
80
84
 
81
85
  def __encode_session_id__(self, data: str) -> str:
@@ -5,6 +5,7 @@ import json
5
5
  from typing import Any, Union
6
6
  import uuid
7
7
 
8
+ from jam.__deprecated__ import deprecated
8
9
  from jam.aio import Jam as AioJam
9
10
  from jam.instance import Jam
10
11
  from jam.jose.utils import __base64url_decode__ as base64url_decode
@@ -66,6 +67,9 @@ class TestJam(Jam):
66
67
  self._sessions: dict[str, dict[str, Any]] = {}
67
68
  self._session_keys: dict[str, str] = {}
68
69
 
70
+ @deprecated(
71
+ "This method is deprecated; the JWT payload is generated automatically in accordance with the specification."
72
+ )
69
73
  def jwt_make_payload(
70
74
  self, exp: int | None, data: dict[str, Any]
71
75
  ) -> dict[str, Any]:
@@ -413,3 +413,18 @@ def __module_loader__(path: str) -> Callable:
413
413
  module_path, class_name = path.rsplit(".", 1)
414
414
  module = import_module(module_path)
415
415
  return getattr(module, class_name)
416
+
417
+
418
+ def __key_loader__(key: str) -> str:
419
+ """Loads a key from file, if `key` is a path to a file.
420
+
421
+ Args:
422
+ key (str): Key to load. If it is a path to a file, the file will be loaded.
423
+
424
+ Returns:
425
+ str: Loaded key or original key if not a file path.
426
+ """
427
+ if os.path.isfile(key):
428
+ with open(key) as f:
429
+ return f.read().strip()
430
+ return key
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jamlib
3
- Version: 3.2.0rc0
3
+ Version: 3.2.0rc2
4
4
  Summary: Simple and universal library for authorization.
5
5
  Author-email: Makridenko Adrian <adrianmakridenko@duck.com>, Ksenia Travnikova <kseniatravnikova@duck.com>
6
6
  License: Apache-2.0
@@ -77,7 +77,7 @@ from jam import Jam
77
77
 
78
78
  jam = Jam(config="config.toml")
79
79
 
80
- jwt = jam.jwt_create({"user": 1})
80
+ jwt = jam.jwt_encode(payload={"user": 1})
81
81
  session_id = jam.session_create(session_key="username", data={"user": 1})
82
82
  otp_code = jam.otp_code(secret="3DB7FOAOFBCI3WFDRE7EPF43CA")
83
83
  ```
@@ -85,7 +85,7 @@ otp_code = jam.otp_code(secret="3DB7FOAOFBCI3WFDRE7EPF43CA")
85
85
  ## Why Jam?
86
86
  Jam is a library that provides the most popular AUTH* mechanisms right out of the box.
87
87
 
88
- * [JOSE](https://jam.makridenko.ru/usage/jose/index/)
88
+ * [JOSE](https://jam.makridenko.ru/usage/jose/)
89
89
  * [PASETO](https://jam.makridenko.ru/usage/paseto/)
90
90
  * [Server side sessions](https://jam.makridenko.ru/usage/sessions/)
91
91
  * [OTP](https://jam.makridenko.ru/usage/otp/)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes