jamlib 3.2.0rc0__tar.gz → 3.3.0__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.2.0rc0/src/jamlib.egg-info → jamlib-3.3.0}/PKG-INFO +7 -3
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/README.md +6 -2
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/pyproject.toml +1 -1
- jamlib-3.3.0/src/jam/__defaults__.py +21 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/__init__.py +1 -1
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/__base__.py +8 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/instance.py +21 -9
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/sessions/__base__.py +5 -1
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/exceptions/__init__.py +20 -0
- jamlib-3.3.0/src/jam/exceptions/saml.py +66 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/flask/extensions.py +2 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/litestar/middleware.py +7 -7
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/litestar/objects.py +2 -5
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/litestar/plugins.py +3 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/starlette/backends.py +2 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/starlette/objects.py +5 -6
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/__algorithms__.py +9 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/__base__.py +16 -11
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/jwe.py +2 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/jwk.py +0 -9
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/jws.py +5 -1
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/jwt.py +64 -35
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/lists/redis.py +5 -3
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/paseto/v1.py +4 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/paseto/v2.py +4 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/paseto/v3.py +4 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/paseto/v4.py +4 -0
- jamlib-3.3.0/src/jam/saml/__base__.py +577 -0
- jamlib-3.3.0/src/jam/saml/__init__.py +129 -0
- jamlib-3.3.0/src/jam/saml/binding.py +188 -0
- jamlib-3.3.0/src/jam/saml/encryption.py +244 -0
- jamlib-3.3.0/src/jam/saml/metadata.py +211 -0
- jamlib-3.3.0/src/jam/saml/saml.py +1943 -0
- jamlib-3.3.0/src/jam/saml/signature.py +287 -0
- jamlib-3.3.0/src/jam/saml/types.py +185 -0
- jamlib-3.3.0/src/jam/saml/xml.py +174 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/sessions/__base__.py +5 -1
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/tests/clients.py +271 -53
- jamlib-3.3.0/src/jam/tests/fakers.py +187 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/config_maker.py +15 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0/src/jamlib.egg-info}/PKG-INFO +7 -3
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jamlib.egg-info/SOURCES.txt +11 -0
- jamlib-3.2.0rc0/src/jam/tests/fakers.py +0 -102
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/LICENSE.md +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/setup.cfg +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/__base__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/__base_encoder__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/__deprecated__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/jwt/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/oauth2/__base__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/oauth2/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/oauth2/builtin/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/oauth2/builtin/github.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/oauth2/builtin/gitlab.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/oauth2/builtin/google.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/oauth2/builtin/yandex.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/oauth2/client.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/sessions/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/sessions/json.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/aio/sessions/redis.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/cli/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/cli/cli.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/cli/commands/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/cli/commands/keys.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/cli/commands/password.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/encoders.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/exceptions/base.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/exceptions/jose.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/exceptions/jwt.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/exceptions/oauth2.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/exceptions/paseto.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/exceptions/plugins.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/exceptions/sessions.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/fastapi/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/flask/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/flask/objects.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/litestar/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/ext/starlette/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/instance.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/lists/__base__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/lists/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/lists/json.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/lists/memory.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jose/utils.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jwt/__algorithms__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jwt/__base__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jwt/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jwt/__types__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jwt/lists/__base__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jwt/lists/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jwt/lists/json.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jwt/lists/redis.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jwt/module.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/jwt/utils.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/logger.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/oauth2/__base__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/oauth2/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/oauth2/builtin/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/oauth2/builtin/github.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/oauth2/builtin/gitlab.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/oauth2/builtin/google.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/oauth2/builtin/yandex.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/oauth2/client.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/otp/__base__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/otp/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/otp/hotp.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/otp/totp.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/paseto/__base__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/paseto/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/paseto/utils.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/plugins/__base__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/plugins/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/py.typed +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/sessions/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/sessions/json.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/sessions/redis.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/tests/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/__init__.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/aes.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/await_maybe.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/basic_auth.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/ed.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/otp_keys.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/rsa.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/salt_hash.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/symmetric.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/version_check.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/xchacha20poly1305.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jam/utils/xor.py +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jamlib.egg-info/dependency_links.txt +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jamlib.egg-info/entry_points.txt +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/src/jamlib.egg-info/requires.txt +0 -0
- {jamlib-3.2.0rc0 → jamlib-3.3.0}/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.
|
|
3
|
+
Version: 3.3.0
|
|
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
|
|
@@ -62,6 +62,8 @@ Dynamic: license-file
|
|
|
62
62
|
[](https://deepwiki.com/lyaguxafrog/jam)
|
|
63
63
|
[](https://github.com/lyaguxafrog/jam/blob/master/LICENSE.md)
|
|
64
64
|
|
|
65
|
+
**Jam (Jam Auth Module)** - A universal auth* combine that provides popular auth mechanisms strictly according to the specification.
|
|
66
|
+
|
|
65
67
|
* Documentation: [jam.makridenko.ru](https://jam.makridenko.ru)
|
|
66
68
|
* Changelog: [CHANGELOG.md](https://github.com/lyaguxafrog/jam/blob/master/CHANGELOG.md)
|
|
67
69
|
|
|
@@ -77,7 +79,7 @@ from jam import Jam
|
|
|
77
79
|
|
|
78
80
|
jam = Jam(config="config.toml")
|
|
79
81
|
|
|
80
|
-
jwt = jam.
|
|
82
|
+
jwt = jam.jwt_encode(payload={"user": 1})
|
|
81
83
|
session_id = jam.session_create(session_key="username", data={"user": 1})
|
|
82
84
|
otp_code = jam.otp_code(secret="3DB7FOAOFBCI3WFDRE7EPF43CA")
|
|
83
85
|
```
|
|
@@ -85,11 +87,12 @@ otp_code = jam.otp_code(secret="3DB7FOAOFBCI3WFDRE7EPF43CA")
|
|
|
85
87
|
## Why Jam?
|
|
86
88
|
Jam is a library that provides the most popular AUTH* mechanisms right out of the box.
|
|
87
89
|
|
|
88
|
-
* [JOSE](https://jam.makridenko.ru/usage/jose/
|
|
90
|
+
* [JOSE](https://jam.makridenko.ru/usage/jose/)
|
|
89
91
|
* [PASETO](https://jam.makridenko.ru/usage/paseto/)
|
|
90
92
|
* [Server side sessions](https://jam.makridenko.ru/usage/sessions/)
|
|
91
93
|
* [OTP](https://jam.makridenko.ru/usage/otp/)
|
|
92
94
|
* [OAuth2](https://jam.makridenko.ru/usage/oauth2/)
|
|
95
|
+
* [SAML](https://jam.makridenko.ru/usage/saml/)
|
|
93
96
|
|
|
94
97
|
### Framework integrations
|
|
95
98
|
|
|
@@ -115,5 +118,6 @@ Here is a comparison with other libraries:
|
|
|
115
118
|
| Server side sessions | ✅ | ✅ | ❌ | ❌ | ❌ |
|
|
116
119
|
| OTP | ✅ | ❌ | ❌ | ❌ | ✅ |
|
|
117
120
|
| OAuth2 | ✅ | ✅ | ❌ | ✅ | ❌ |
|
|
121
|
+
| SAML 2.0 | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
118
122
|
| Flexible config | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
119
123
|
| Modularity | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
[](https://deepwiki.com/lyaguxafrog/jam)
|
|
10
10
|
[](https://github.com/lyaguxafrog/jam/blob/master/LICENSE.md)
|
|
11
11
|
|
|
12
|
+
**Jam (Jam Auth Module)** - A universal auth* combine that provides popular auth mechanisms strictly according to the specification.
|
|
13
|
+
|
|
12
14
|
* Documentation: [jam.makridenko.ru](https://jam.makridenko.ru)
|
|
13
15
|
* Changelog: [CHANGELOG.md](https://github.com/lyaguxafrog/jam/blob/master/CHANGELOG.md)
|
|
14
16
|
|
|
@@ -24,7 +26,7 @@ from jam import Jam
|
|
|
24
26
|
|
|
25
27
|
jam = Jam(config="config.toml")
|
|
26
28
|
|
|
27
|
-
jwt = jam.
|
|
29
|
+
jwt = jam.jwt_encode(payload={"user": 1})
|
|
28
30
|
session_id = jam.session_create(session_key="username", data={"user": 1})
|
|
29
31
|
otp_code = jam.otp_code(secret="3DB7FOAOFBCI3WFDRE7EPF43CA")
|
|
30
32
|
```
|
|
@@ -32,11 +34,12 @@ otp_code = jam.otp_code(secret="3DB7FOAOFBCI3WFDRE7EPF43CA")
|
|
|
32
34
|
## Why Jam?
|
|
33
35
|
Jam is a library that provides the most popular AUTH* mechanisms right out of the box.
|
|
34
36
|
|
|
35
|
-
* [JOSE](https://jam.makridenko.ru/usage/jose/
|
|
37
|
+
* [JOSE](https://jam.makridenko.ru/usage/jose/)
|
|
36
38
|
* [PASETO](https://jam.makridenko.ru/usage/paseto/)
|
|
37
39
|
* [Server side sessions](https://jam.makridenko.ru/usage/sessions/)
|
|
38
40
|
* [OTP](https://jam.makridenko.ru/usage/otp/)
|
|
39
41
|
* [OAuth2](https://jam.makridenko.ru/usage/oauth2/)
|
|
42
|
+
* [SAML](https://jam.makridenko.ru/usage/saml/)
|
|
40
43
|
|
|
41
44
|
### Framework integrations
|
|
42
45
|
|
|
@@ -62,5 +65,6 @@ Here is a comparison with other libraries:
|
|
|
62
65
|
| Server side sessions | ✅ | ✅ | ❌ | ❌ | ❌ |
|
|
63
66
|
| OTP | ✅ | ❌ | ❌ | ❌ | ✅ |
|
|
64
67
|
| OAuth2 | ✅ | ✅ | ❌ | ✅ | ❌ |
|
|
68
|
+
| SAML 2.0 | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
65
69
|
| Flexible config | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
66
70
|
| Modularity | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass(slots=True, frozen=True)
|
|
8
|
+
class DEFAULTS:
|
|
9
|
+
"""Jam defaults vars."""
|
|
10
|
+
|
|
11
|
+
DEBUG: bool = os.getenv("JAM_DEBUG", "False") == "True"
|
|
12
|
+
"""Debug flag. Use only while developing jam module."""
|
|
13
|
+
|
|
14
|
+
TEMP_DIR: str = os.getenv("JAM_TMP_DIR", "/tmp/jam/")
|
|
15
|
+
"""tmp directory for storing temporary files and blobs."""
|
|
16
|
+
|
|
17
|
+
ENABLE_PLUGINS: bool = os.getenv("JAM_ENABLE_PLUGINS", "1") == "0"
|
|
18
|
+
"""Enabling experimental plugin features."""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
defaults = DEFAULTS()
|
|
@@ -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":
|
|
47
|
-
"exp": (
|
|
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(
|
|
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
|
|
373
|
-
issuer: str
|
|
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.
|
|
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:
|
|
@@ -45,6 +45,17 @@ from .sessions import (
|
|
|
45
45
|
JamSessionEmptyAESKey,
|
|
46
46
|
JamSessionNotFound,
|
|
47
47
|
)
|
|
48
|
+
from .saml import (
|
|
49
|
+
JamSAMLError,
|
|
50
|
+
JamSAMLExpired,
|
|
51
|
+
JamSAMLNotYetValid,
|
|
52
|
+
JamSAMLInvalidAudience,
|
|
53
|
+
JamSAMLInvalidIssuer,
|
|
54
|
+
JamSAMLEmptyPrivateKey,
|
|
55
|
+
JamSAMLEmptyPublicKey,
|
|
56
|
+
JamSAMLUnsupportedAlgorithm,
|
|
57
|
+
JamSAMLValidationError,
|
|
58
|
+
)
|
|
48
59
|
|
|
49
60
|
|
|
50
61
|
__all__ = [
|
|
@@ -81,4 +92,13 @@ __all__ = [
|
|
|
81
92
|
"JamStarlettePluginError",
|
|
82
93
|
"JamSessionNotFound",
|
|
83
94
|
"JamSessionEmptyAESKey",
|
|
95
|
+
"JamSAMLError",
|
|
96
|
+
"JamSAMLExpired",
|
|
97
|
+
"JamSAMLNotYetValid",
|
|
98
|
+
"JamSAMLInvalidAudience",
|
|
99
|
+
"JamSAMLInvalidIssuer",
|
|
100
|
+
"JamSAMLEmptyPrivateKey",
|
|
101
|
+
"JamSAMLEmptyPublicKey",
|
|
102
|
+
"JamSAMLUnsupportedAlgorithm",
|
|
103
|
+
"JamSAMLValidationError",
|
|
84
104
|
]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from .base import JamConfigurationError, JamError, JamValidationError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class JamSAMLError(JamError):
|
|
7
|
+
default_message = "SAML error occurred."
|
|
8
|
+
default_code = "saml.error"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class JamSAMLExpired(JamError):
|
|
12
|
+
default_message = "SAML assertion has expired."
|
|
13
|
+
default_code = "saml.assertion_expired"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class JamSAMLNotYetValid(JamError):
|
|
17
|
+
default_message = "SAML assertion is not yet valid."
|
|
18
|
+
default_code = "saml.assertion_not_yet_valid"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class JamSAMLInvalidAudience(JamError):
|
|
22
|
+
default_message = "SAML assertion audience validation failed."
|
|
23
|
+
default_code = "saml.invalid_audience"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class JamSAMLInvalidIssuer(JamError):
|
|
27
|
+
default_message = "SAML assertion issuer validation failed."
|
|
28
|
+
default_code = "saml.invalid_issuer"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class JamSAMLEmptyPrivateKey(JamConfigurationError):
|
|
32
|
+
default_message = "For SAML signing, you must specify `private_key`."
|
|
33
|
+
default_code = "saml.config.empty_private_key"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class JamSAMLEmptyPublicKey(JamConfigurationError):
|
|
37
|
+
default_message = "For SAML verification, you must specify `public_key`."
|
|
38
|
+
default_code = "saml.config.empty_public_key"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class JamSAMLUnsupportedAlgorithm(JamConfigurationError):
|
|
42
|
+
default_message = "Unsupported SAML algorithm."
|
|
43
|
+
default_code = "saml.config.unsupported_algorithm"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class JamSAMLValidationError(JamValidationError):
|
|
47
|
+
default_message = "SAML assertion validation failed."
|
|
48
|
+
default_code = "saml.validation.assertion_error"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class JamSAMLInvalidRecipient(JamError):
|
|
52
|
+
default_message = (
|
|
53
|
+
"SAML assertion SubjectConfirmationData Recipient "
|
|
54
|
+
"does not match the expected ACS URL."
|
|
55
|
+
)
|
|
56
|
+
default_code = "saml.invalid_recipient"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class JamSAMLReplayDetected(JamError):
|
|
60
|
+
default_message = "SAML message ID has already been consumed (replay attack)."
|
|
61
|
+
default_code = "saml.replay_detected"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class JamSAMLSOAPError(JamError):
|
|
65
|
+
default_message = "SAML SOAP/artifact resolution failed."
|
|
66
|
+
default_code = "saml.soap_error"
|
|
@@ -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)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from typing import Any
|
|
4
4
|
|
|
5
5
|
from litestar.connection import ASGIConnection
|
|
6
6
|
from litestar.middleware import (
|
|
@@ -18,7 +18,7 @@ from jam.paseto import BasePASETO
|
|
|
18
18
|
class BaseMiddleware(AbstractAuthenticationMiddleware):
|
|
19
19
|
"""Base Jam middleware for litestar."""
|
|
20
20
|
|
|
21
|
-
AUTH_MODULE:
|
|
21
|
+
AUTH_MODULE: Any
|
|
22
22
|
HEADER_NAME: str | None
|
|
23
23
|
COOKIE_NAME: str | None
|
|
24
24
|
BEARER: bool = False
|
|
@@ -95,7 +95,7 @@ class SessionMiddleware(BaseMiddleware):
|
|
|
95
95
|
if not data:
|
|
96
96
|
return AuthenticationResult(None, auth=token_model)
|
|
97
97
|
user = self.USER.from_payload(data)
|
|
98
|
-
return AuthenticationResult(user,
|
|
98
|
+
return AuthenticationResult(user=user, auth=token_model)
|
|
99
99
|
except Exception as e:
|
|
100
100
|
raise JamLitestarPluginError(message=str(e))
|
|
101
101
|
|
|
@@ -113,10 +113,10 @@ class PASETOMiddleware(BaseMiddleware):
|
|
|
113
113
|
if not token:
|
|
114
114
|
return AuthenticationResult(None, auth=token_model)
|
|
115
115
|
try:
|
|
116
|
-
|
|
117
|
-
if not
|
|
116
|
+
result = self.AUTH_MODULE.decode(token)
|
|
117
|
+
if not result:
|
|
118
118
|
return AuthenticationResult(None, auth=token_model)
|
|
119
|
-
user = self.USER.from_payload(
|
|
120
|
-
return AuthenticationResult(user,
|
|
119
|
+
user = self.USER.from_payload(result[0])
|
|
120
|
+
return AuthenticationResult(user=user, auth=token_model)
|
|
121
121
|
except Exception as e:
|
|
122
122
|
raise JamLitestarPluginError(message=str(e))
|
|
@@ -4,10 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from abc import ABC, abstractmethod
|
|
6
6
|
from dataclasses import dataclass
|
|
7
|
-
from typing import Any
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
User = TypeVar("User", bound="BaseUser")
|
|
7
|
+
from typing import Any
|
|
11
8
|
|
|
12
9
|
|
|
13
10
|
@dataclass(slots=True)
|
|
@@ -23,7 +20,7 @@ class BaseUser(ABC):
|
|
|
23
20
|
|
|
24
21
|
@classmethod
|
|
25
22
|
@abstractmethod
|
|
26
|
-
def from_payload(cls, payload: dict[str, Any]) ->
|
|
23
|
+
def from_payload(cls, payload: dict[str, Any]) -> BaseUser:
|
|
27
24
|
"""Build model from payload.
|
|
28
25
|
|
|
29
26
|
Args:
|
|
@@ -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)
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
from abc import ABC, abstractmethod
|
|
4
6
|
from dataclasses import dataclass
|
|
5
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
6
8
|
|
|
7
9
|
from starlette.authentication import BaseUser as StarletteBaseUser
|
|
8
10
|
|
|
9
11
|
|
|
10
|
-
User = TypeVar("User", bound="BaseUser")
|
|
11
|
-
|
|
12
|
-
|
|
13
12
|
class BaseUser(ABC, StarletteBaseUser):
|
|
14
13
|
"""BaseUser with builder from payload."""
|
|
15
14
|
|
|
16
15
|
@classmethod
|
|
17
16
|
@abstractmethod
|
|
18
|
-
def from_payload(cls, payload: dict[str, Any]) ->
|
|
17
|
+
def from_payload(cls, payload: dict[str, Any]) -> BaseUser:
|
|
19
18
|
"""Create instance by payload.
|
|
20
19
|
|
|
21
20
|
Args:
|
|
@@ -49,7 +48,7 @@ class SimpleUser(BaseUser):
|
|
|
49
48
|
payload: dict[str, Any]
|
|
50
49
|
|
|
51
50
|
@classmethod
|
|
52
|
-
def from_payload(cls, payload: dict[str, Any]): # noqa
|
|
51
|
+
def from_payload(cls, payload: dict[str, Any]) -> SimpleUser: # noqa
|
|
53
52
|
return cls(payload=payload)
|
|
54
53
|
|
|
55
54
|
def is_authenticated(self) -> bool: # type: ignore # noqa
|
|
@@ -112,6 +112,8 @@ class BaseAlgorithm(ABC):
|
|
|
112
112
|
except OSError:
|
|
113
113
|
is_file = False
|
|
114
114
|
return path.read_bytes() if is_file else data.encode()
|
|
115
|
+
if isinstance(data, rsa.RSAPrivateKey | ec.EllipticCurvePrivateKey):
|
|
116
|
+
data = data.public_key()
|
|
115
117
|
return data.public_bytes(
|
|
116
118
|
encoding=serialization.Encoding.PEM,
|
|
117
119
|
format=serialization.PublicFormat.SubjectPublicKeyInfo,
|
|
@@ -602,6 +604,11 @@ class BaseKeyAlgorithm(ABC):
|
|
|
602
604
|
if hasattr(self._key, "private_key"):
|
|
603
605
|
return self._key.private_key()
|
|
604
606
|
|
|
607
|
+
if isinstance(
|
|
608
|
+
self._key, rsa.RSAPrivateKey | ec.EllipticCurvePrivateKey
|
|
609
|
+
):
|
|
610
|
+
return self._key
|
|
611
|
+
|
|
605
612
|
key_bytes = self._load_key_data(self._key)
|
|
606
613
|
return serialization.load_pem_private_key(
|
|
607
614
|
key_bytes, password=self._password
|
|
@@ -620,6 +627,8 @@ class BaseKeyAlgorithm(ABC):
|
|
|
620
627
|
except OSError:
|
|
621
628
|
is_file = False
|
|
622
629
|
return path.read_bytes() if is_file else data.encode()
|
|
630
|
+
if isinstance(data, rsa.RSAPrivateKey | ec.EllipticCurvePrivateKey):
|
|
631
|
+
data = data.public_key()
|
|
623
632
|
return data.public_bytes(
|
|
624
633
|
encoding=serialization.Encoding.PEM,
|
|
625
634
|
format=serialization.PublicFormat.SubjectPublicKeyInfo,
|
|
@@ -73,34 +73,39 @@ class BaseJWT(ABC):
|
|
|
73
73
|
@abstractmethod
|
|
74
74
|
def encrypt(
|
|
75
75
|
self,
|
|
76
|
-
|
|
76
|
+
plaintext: bytes | str | dict[str, Any],
|
|
77
77
|
header: dict[str, Any] | None = None,
|
|
78
78
|
) -> str:
|
|
79
|
-
"""Encrypt
|
|
79
|
+
"""Encrypt plaintext.
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
Produces JWE Compact Serialization:
|
|
82
|
+
BASE64URL(header).BASE64URL(encrypted_key).BASE64URL(iv).BASE64URL(ciphertext).BASE64URL(tag)
|
|
82
83
|
|
|
83
84
|
Args:
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
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
|
|
98
|
+
def decrypt(self, token: str) -> dict[str, Any] | bytes:
|
|
99
|
+
"""Decrypt JWE token.
|
|
95
100
|
|
|
96
101
|
Args:
|
|
97
|
-
token:
|
|
102
|
+
token: JWE compact serialization string.
|
|
98
103
|
|
|
99
104
|
Returns:
|
|
100
|
-
|
|
105
|
+
bytes: Decrypted plaintext.
|
|
101
106
|
|
|
102
107
|
Raises:
|
|
103
|
-
|
|
108
|
+
JamJWEDecryptionError: If decryption fails.
|
|
104
109
|
"""
|
|
105
110
|
raise NotImplementedError
|
|
106
111
|
|
|
@@ -56,9 +56,6 @@ class JWKRSA(JWKCommon, total=False):
|
|
|
56
56
|
... }
|
|
57
57
|
"""
|
|
58
58
|
|
|
59
|
-
kty: Literal["RSA"]
|
|
60
|
-
"""Key Type. Fixed to "RSA"."""
|
|
61
|
-
|
|
62
59
|
n: str
|
|
63
60
|
"""RSA modulus n. The modulus value for the RSA public key."""
|
|
64
61
|
|
|
@@ -98,9 +95,6 @@ class JWKEC(JWKCommon, total=False):
|
|
|
98
95
|
... }
|
|
99
96
|
"""
|
|
100
97
|
|
|
101
|
-
kty: Literal["EC"]
|
|
102
|
-
"""Key Type. Fixed to "EC"."""
|
|
103
|
-
|
|
104
98
|
crv: Literal["P-256", "P-384", "P-521"]
|
|
105
99
|
"""Elliptic curve name. The curve on which the key is based."""
|
|
106
100
|
|
|
@@ -126,9 +120,6 @@ class JWKOct(JWKCommon, total=False):
|
|
|
126
120
|
... }
|
|
127
121
|
"""
|
|
128
122
|
|
|
129
|
-
kty: Literal["oct"]
|
|
130
|
-
"""Key Type. Fixed to "oct"."""
|
|
131
|
-
|
|
132
123
|
k: str
|
|
133
124
|
"""Key value. The base64url-encoded symmetric key value."""
|
|
134
125
|
|
|
@@ -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
|
|
|
@@ -80,7 +84,7 @@ class JWS(BaseJWS):
|
|
|
80
84
|
def serialize_compact(
|
|
81
85
|
self,
|
|
82
86
|
protected: dict[str, Any],
|
|
83
|
-
payload: bytes | str,
|
|
87
|
+
payload: bytes | str | dict[str, Any],
|
|
84
88
|
) -> str:
|
|
85
89
|
"""Create JWS Compact Serialization.
|
|
86
90
|
|