|
4 | 4 |
|
5 | 5 | import re |
6 | 6 | import secrets |
7 | | -from enum import Enum |
8 | 7 | from functools import cached_property |
9 | | -from typing import TYPE_CHECKING, Any, Callable, ClassVar |
| 8 | +from typing import TYPE_CHECKING, Any, ClassVar |
10 | 9 |
|
11 | 10 | from attrs import asdict, field, fields, frozen |
12 | 11 | from binapy import BinaPy |
13 | 12 | from furl import furl # type: ignore[import-untyped] |
14 | 13 | from jwskate import JweCompact, Jwk, Jwt, SignatureAlgs, SignedJwt |
15 | 14 |
|
16 | 15 | from .dpop import DPoPKey |
| 16 | +from .enums import CodeChallengeMethods, ResponseTypes |
17 | 17 | from .exceptions import ( |
18 | 18 | AuthorizationResponseError, |
19 | 19 | ConsentRequired, |
|
32 | 32 | from datetime import datetime |
33 | 33 |
|
34 | 34 |
|
35 | | -class ResponseTypes(str, Enum): |
36 | | - """All standardised `response_type` values. |
37 | | -
|
38 | | - Note that you should always use `code`. All other values are deprecated. |
39 | | -
|
40 | | - """ |
41 | | - |
42 | | - CODE = "code" |
43 | | - NONE = "none" |
44 | | - TOKEN = "token" |
45 | | - IDTOKEN = "id_token" |
46 | | - CODE_IDTOKEN = "code id_token" |
47 | | - CODE_TOKEN = "code token" |
48 | | - CODE_IDTOKEN_TOKEN = "code id_token token" |
49 | | - IDTOKEN_TOKEN = "id_token token" |
50 | | - |
51 | | - |
52 | | -class CodeChallengeMethods(str, Enum): |
53 | | - """All standardised `code_challenge_method` values. |
54 | | -
|
55 | | - You should always use `S256`. |
56 | | -
|
57 | | - """ |
58 | | - |
59 | | - S256 = "S256" |
60 | | - plain = "plain" |
61 | | - |
62 | | - |
63 | 35 | class UnsupportedCodeChallengeMethod(ValueError): |
64 | 36 | """Raised when an unsupported `code_challenge_method` is provided.""" |
65 | 37 |
|
@@ -908,92 +880,3 @@ def __getattr__(self, item: str) -> Any: |
908 | 880 | def __repr__(self) -> str: |
909 | 881 | """Return the Authorization Request URI, as a `str`.""" |
910 | 882 | return self.uri |
911 | | - |
912 | | - |
913 | | -class AuthorizationRequestSerializer: |
914 | | - """(De)Serializer for `AuthorizationRequest` instances. |
915 | | -
|
916 | | - You might need to store pending authorization requests in session, either server-side or client- side. This class is |
917 | | - here to help you do that. |
918 | | -
|
919 | | - """ |
920 | | - |
921 | | - def __init__( |
922 | | - self, |
923 | | - dumper: Callable[[AuthorizationRequest], str] | None = None, |
924 | | - loader: Callable[[str], AuthorizationRequest] | None = None, |
925 | | - ) -> None: |
926 | | - self.dumper = dumper or self.default_dumper |
927 | | - self.loader = loader or self.default_loader |
928 | | - |
929 | | - @staticmethod |
930 | | - def default_dumper(azr: AuthorizationRequest) -> str: |
931 | | - """Provide a default dumper implementation. |
932 | | -
|
933 | | - Serialize an AuthorizationRequest as JSON, then compress with deflate, then encodes as |
934 | | - base64url. |
935 | | -
|
936 | | - Args: |
937 | | - azr: the `AuthorizationRequest` to serialize |
938 | | -
|
939 | | - Returns: |
940 | | - the serialized value |
941 | | -
|
942 | | - """ |
943 | | - d = asdict(azr) |
944 | | - if azr.dpop_key: |
945 | | - d["dpop_key"]["private_key"] = azr.dpop_key.private_key.to_dict() |
946 | | - d.update(**d.pop("kwargs", {})) |
947 | | - return BinaPy.serialize_to("json", d).to("deflate").to("b64u").ascii() |
948 | | - |
949 | | - @staticmethod |
950 | | - def default_loader( |
951 | | - serialized: str, |
952 | | - azr_class: type[AuthorizationRequest] = AuthorizationRequest, |
953 | | - ) -> AuthorizationRequest: |
954 | | - """Provide a default deserializer implementation. |
955 | | -
|
956 | | - This does the opposite operations than `default_dumper`. |
957 | | -
|
958 | | - Args: |
959 | | - serialized: the serialized AuthorizationRequest |
960 | | - azr_class: the class to deserialize the Authorization Request to |
961 | | -
|
962 | | - Returns: |
963 | | - an AuthorizationRequest |
964 | | -
|
965 | | - """ |
966 | | - args = BinaPy(serialized).decode_from("b64u").decode_from("deflate").parse_from("json") |
967 | | - |
968 | | - if dpop_key := args.get("dpop_key"): |
969 | | - dpop_key["private_key"] = Jwk(dpop_key["private_key"]) |
970 | | - dpop_key.pop("jti_generator", None) |
971 | | - dpop_key.pop("iat_generator", None) |
972 | | - dpop_key.pop("dpop_token_class", None) |
973 | | - args["dpop_key"] = DPoPKey(**dpop_key) |
974 | | - |
975 | | - return azr_class(**args) |
976 | | - |
977 | | - def dumps(self, azr: AuthorizationRequest) -> str: |
978 | | - """Serialize and compress a given AuthorizationRequest for easier storage. |
979 | | -
|
980 | | - Args: |
981 | | - azr: an AuthorizationRequest to serialize |
982 | | -
|
983 | | - Returns: |
984 | | - the serialized AuthorizationRequest, as a str |
985 | | -
|
986 | | - """ |
987 | | - return self.dumper(azr) |
988 | | - |
989 | | - def loads(self, serialized: str) -> AuthorizationRequest: |
990 | | - """Deserialize a serialized AuthorizationRequest. |
991 | | -
|
992 | | - Args: |
993 | | - serialized: the serialized AuthorizationRequest |
994 | | -
|
995 | | - Returns: |
996 | | - the deserialized AuthorizationRequest |
997 | | -
|
998 | | - """ |
999 | | - return self.loader(serialized) |
0 commit comments