first commit

This commit is contained in:
linkitapps
2026-09-14 23:22:10 +09:00
commit 9f9c8fb69b
4207 changed files with 1333187 additions and 0 deletions
+133
View File
@@ -0,0 +1,133 @@
import json
from json import JSONEncoder, JSONDecoder
from collections.abc import Collection
from ._rfc7519.claims import (
convert_claims,
Claims,
ClaimsOption,
BaseClaimsRegistry,
JWTClaimsRegistry,
)
from ._rfc7519.security import check_sensitive_data
from .jws import (
JWSRegistry,
serialize_compact,
deserialize_compact,
)
from .jwe import (
JWERegistry,
encrypt_compact,
decrypt_compact,
)
from .jwk import KeyFlexible
from .errors import InvalidPayloadError
from .util import to_bytes
from .registry import Header
__all__ = [
# types
"Claims",
"ClaimsOption",
# modules
"BaseClaimsRegistry",
"JWTClaimsRegistry",
"Token",
# methods
"encode",
"decode",
"check_sensitive_data",
]
class Token:
"""The extracted token object, which contains ``header`` and ``claims``.
:param header: the header part of the JWT
:param claims: the payload part of the JWT
"""
def __init__(self, header: Header, claims: Claims):
#: header in dict
self.header = header
#: payload claims in dict
self.claims = claims
def encode(
header: Header,
claims: Claims,
key: KeyFlexible,
algorithms: Collection[str] | None = None,
registry: JWSRegistry | JWERegistry | None = None,
encoder_cls: type[JSONEncoder] | None = None,
default_type: str | None = "JWT",
) -> str:
"""Encode a JSON Web Token with the given header, and claims.
:param header: A dict of the JWT header
:param claims: A dict of the JWT claims to be encoded
:param key: key used to sign the signature
:param algorithms: a collection (list, tuple, or set) of allowed algorithms
:param registry: a ``JWSRegistry`` or ``JWERegistry`` to use
:param encoder_cls: A JSONEncoder subclass to use
:param default_type: default value of the ``typ`` header parameter
"""
if default_type is not None:
_header = {"typ": default_type, **header}
else:
_header = {**header}
payload = convert_claims(claims, encoder_cls)
if isinstance(registry, JWERegistry):
return encrypt_compact(_header, payload, key, algorithms, registry)
else:
return serialize_compact(_header, payload, key, algorithms, registry)
def decode(
value: bytes | str,
key: KeyFlexible,
algorithms: Collection[str] | None = None,
registry: JWSRegistry | JWERegistry | None = None,
decoder_cls: type[JSONDecoder] | None = None,
) -> Token:
"""Decode the JSON Web Token string with the given key, and validate
it with the claims requests.
:param value: text of the JWT
:param key: key used to verify the signature
:param algorithms: a collection (list, tuple, or set) of allowed algorithms
:param registry: a ``JWSRegistry`` or ``JWERegistry`` to use
:param decoder_cls: A JSONDecoder subclass to use
:raise BadSignatureError: when signature verification fails
:raise InvalidPayloadError: when payload is not a valid JSON object
"""
_value = to_bytes(value)
header: Header
payload: bytes
if isinstance(registry, JWERegistry):
header, payload = _decode_jwe(_value, key, algorithms, registry)
else:
header, payload = _decode_jws(_value, key, algorithms, registry)
try:
claims: Claims = json.loads(payload, cls=decoder_cls)
except (TypeError, ValueError):
raise InvalidPayloadError()
return Token(header, claims)
def _decode_jwe(
value: bytes, key: KeyFlexible, algorithms: Collection[str] | None = None, registry: JWERegistry | None = None
) -> tuple[Header, bytes]:
jwe_obj = decrypt_compact(value, key, algorithms, registry)
assert jwe_obj.plaintext is not None
return jwe_obj.headers(), jwe_obj.plaintext
def _decode_jws(
value: bytes, key: KeyFlexible, algorithms: Collection[str] | None = None, registry: JWSRegistry | None = None
) -> tuple[Header, bytes]:
jws_obj = deserialize_compact(value, key, algorithms, registry)
assert jws_obj.payload is not None
return jws_obj.headers(), jws_obj.payload