auth0-server-python 1.0.0b1__py3-none-any.whl
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.
- auth0_server_python-1.0.0b1.dist-info/LICENSE +21 -0
- auth0_server_python-1.0.0b1.dist-info/METADATA +160 -0
- auth0_server_python-1.0.0b1.dist-info/RECORD +14 -0
- auth0_server_python-1.0.0b1.dist-info/WHEEL +4 -0
- auth_server/__init__.py +4 -0
- auth_server/server_client.py +1123 -0
- auth_types/__init__.py +222 -0
- encryption/__init__.py +4 -0
- encryption/encrypt.py +73 -0
- error/__init__.py +119 -0
- store/__init__.py +7 -0
- store/abstract.py +113 -0
- utils/__init__.py +7 -0
- utils/helpers.py +225 -0
auth_types/__init__.py
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Type definitions for auth0-server-python SDK.
|
|
3
|
+
These Pydantic models provide type safety and validation for all SDK data structures.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Dict, List, Optional, Any, Union
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class UserClaims(BaseModel):
|
|
12
|
+
"""
|
|
13
|
+
User profile information as returned by Auth0.
|
|
14
|
+
Contains standard OIDC claims about the authenticated user.
|
|
15
|
+
"""
|
|
16
|
+
sub: str
|
|
17
|
+
name: Optional[str] = None
|
|
18
|
+
nickname: Optional[str] = None
|
|
19
|
+
given_name: Optional[str] = None
|
|
20
|
+
family_name: Optional[str] = None
|
|
21
|
+
picture: Optional[str] = None
|
|
22
|
+
email: Optional[str] = None
|
|
23
|
+
email_verified: Optional[bool] = None
|
|
24
|
+
org_id: Optional[str] = None
|
|
25
|
+
|
|
26
|
+
class Config:
|
|
27
|
+
extra = "allow" # Allow additional fields not defined in the model
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class TokenSet(BaseModel):
|
|
31
|
+
"""
|
|
32
|
+
Represents a set of tokens issued by Auth0.
|
|
33
|
+
Contains the access token and related metadata.
|
|
34
|
+
"""
|
|
35
|
+
audience: str
|
|
36
|
+
access_token: str
|
|
37
|
+
scope: Optional[str] = None
|
|
38
|
+
expires_at: int
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ConnectionTokenSet(TokenSet):
|
|
42
|
+
"""
|
|
43
|
+
Token set specific to a connection.
|
|
44
|
+
Extends TokenSet with connection-specific information.
|
|
45
|
+
"""
|
|
46
|
+
connection: str
|
|
47
|
+
login_hint: str
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class InternalStateData(BaseModel):
|
|
51
|
+
"""
|
|
52
|
+
Internal data used for managing state.
|
|
53
|
+
Not meant to be accessed directly by SDK users.
|
|
54
|
+
"""
|
|
55
|
+
sid: str
|
|
56
|
+
created_at: int
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class SessionData(BaseModel):
|
|
60
|
+
"""
|
|
61
|
+
Represents a user session with Auth0.
|
|
62
|
+
Contains user information and tokens.
|
|
63
|
+
"""
|
|
64
|
+
user: Optional[UserClaims] = None
|
|
65
|
+
id_token: Optional[str] = None
|
|
66
|
+
refresh_token: Optional[str] = None
|
|
67
|
+
token_sets: List[TokenSet] = Field(default_factory=list)
|
|
68
|
+
connection_token_sets: List[ConnectionTokenSet] = Field(default_factory=list)
|
|
69
|
+
|
|
70
|
+
class Config:
|
|
71
|
+
extra = "allow" # Allow additional fields not defined in the model
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class StateData(SessionData):
|
|
75
|
+
"""
|
|
76
|
+
Complete state data stored in the state store.
|
|
77
|
+
Extends SessionData with internal management information.
|
|
78
|
+
"""
|
|
79
|
+
internal: InternalStateData
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class TransactionData(BaseModel):
|
|
83
|
+
"""
|
|
84
|
+
Represents data for an in-progress authentication transaction.
|
|
85
|
+
Used during the authorization code flow to correlate requests.
|
|
86
|
+
"""
|
|
87
|
+
audience: Optional[str] = None
|
|
88
|
+
code_verifier: str
|
|
89
|
+
app_state: Optional[Any] = None
|
|
90
|
+
|
|
91
|
+
class Config:
|
|
92
|
+
extra = "allow" # Allow additional fields not defined in the model
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class LogoutTokenClaims(BaseModel):
|
|
96
|
+
"""
|
|
97
|
+
Claims expected in a logout token.
|
|
98
|
+
Used for backchannel logout processing.
|
|
99
|
+
"""
|
|
100
|
+
sub: str
|
|
101
|
+
sid: str
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class EncryptedStoreOptions(BaseModel):
|
|
105
|
+
"""
|
|
106
|
+
Options for encrypted stores.
|
|
107
|
+
Contains the secret used for encryption.
|
|
108
|
+
"""
|
|
109
|
+
secret: str
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class ServerClientOptionsBase(BaseModel):
|
|
113
|
+
"""
|
|
114
|
+
Base options for configuring the Auth0 server client.
|
|
115
|
+
Contains core settings required for all clients.
|
|
116
|
+
"""
|
|
117
|
+
domain: str
|
|
118
|
+
client_id: str
|
|
119
|
+
client_secret: str
|
|
120
|
+
client_assertion_signing_key: Optional[str] = None
|
|
121
|
+
client_assertion_signing_alg: Optional[str] = None
|
|
122
|
+
authorization_params: Optional[Dict[str, Any]] = Field(default_factory=dict)
|
|
123
|
+
transaction_identifier: Optional[str] = "_a0_tx"
|
|
124
|
+
state_identifier: Optional[str] = "_a0_session"
|
|
125
|
+
custom_fetch: Optional[Any] = None # Function type hint would be more complex
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class ServerClientOptionsWithSecret(ServerClientOptionsBase):
|
|
129
|
+
"""
|
|
130
|
+
Client options using a secret for encryption.
|
|
131
|
+
Extends base options with secret and duration settings.
|
|
132
|
+
"""
|
|
133
|
+
secret: str
|
|
134
|
+
state_absolute_duration: Optional[int] = 259200 # 3 days in seconds
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class StartInteractiveLoginOptions(BaseModel):
|
|
138
|
+
"""
|
|
139
|
+
Options for starting the interactive login process.
|
|
140
|
+
Configures how the authorization request is constructed.
|
|
141
|
+
"""
|
|
142
|
+
pushed_authorization_requests: Optional[bool] = False
|
|
143
|
+
app_state: Optional[Any] = None
|
|
144
|
+
authorization_params: Optional[Dict[str, Any]] = None
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class LoginBackchannelOptions(BaseModel):
|
|
148
|
+
"""
|
|
149
|
+
Options for backchannel authentication.
|
|
150
|
+
Configures how the backchannel authentication request is constructed.
|
|
151
|
+
"""
|
|
152
|
+
binding_message: Optional[str] = None
|
|
153
|
+
login_hint: Optional[Dict[str, str]] = None
|
|
154
|
+
authorization_params: Optional[Dict[str, Any]] = None
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class LogoutOptions(BaseModel):
|
|
158
|
+
"""
|
|
159
|
+
Options for logout operations.
|
|
160
|
+
Configures how the logout request is constructed.
|
|
161
|
+
"""
|
|
162
|
+
return_to: Optional[str] = None
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class AuthorizationParameters(BaseModel):
|
|
166
|
+
"""
|
|
167
|
+
Parameters used in authorization requests.
|
|
168
|
+
Based on standard OAuth2/OIDC parameters.
|
|
169
|
+
"""
|
|
170
|
+
scope: Optional[str] = None
|
|
171
|
+
audience: Optional[str] = None
|
|
172
|
+
redirect_uri: Optional[str] = None
|
|
173
|
+
|
|
174
|
+
class Config:
|
|
175
|
+
extra = "allow" # Allow additional OAuth parameters
|
|
176
|
+
|
|
177
|
+
class AuthorizationDetails(BaseModel):
|
|
178
|
+
"""
|
|
179
|
+
Authorization details returned from Auth0.
|
|
180
|
+
Used for Resource Access Rights (RAR).
|
|
181
|
+
"""
|
|
182
|
+
type: str
|
|
183
|
+
actions: Optional[List[str]] = None
|
|
184
|
+
locations: Optional[List[str]] = None
|
|
185
|
+
datatypes: Optional[List[str]] = None
|
|
186
|
+
identifier: Optional[str] = None
|
|
187
|
+
|
|
188
|
+
class Config:
|
|
189
|
+
extra = "allow" # Allow additional fields not defined in the model
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class LoginBackchannelOptions(BaseModel):
|
|
193
|
+
"""
|
|
194
|
+
Options for Client-Initiated Backchannel Authentication.
|
|
195
|
+
"""
|
|
196
|
+
binding_message: str
|
|
197
|
+
login_hint: Dict[str, str] # Should contain a 'sub' field
|
|
198
|
+
authorization_params: Optional[Dict[str, Any]] = None
|
|
199
|
+
|
|
200
|
+
class Config:
|
|
201
|
+
extra = "allow" # Allow additional fields not defined in the model
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class LoginBackchannelResult(BaseModel):
|
|
205
|
+
"""
|
|
206
|
+
Result from Client-Initiated Backchannel Authentication.
|
|
207
|
+
"""
|
|
208
|
+
authorization_details: Optional[List[AuthorizationDetails]] = None
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class AccessTokenForConnectionOptions(BaseModel):
|
|
212
|
+
"""
|
|
213
|
+
Options for retrieving an access token for a specific connection.
|
|
214
|
+
"""
|
|
215
|
+
connection: str
|
|
216
|
+
login_hint: Optional[str] = None
|
|
217
|
+
|
|
218
|
+
class StartLinkUserOptions(BaseModel):
|
|
219
|
+
connection: str
|
|
220
|
+
connection_scope: Optional[str] = None
|
|
221
|
+
authorization_params: Optional[Dict[str, Any]] = None
|
|
222
|
+
app_state: Optional[Any] = None
|
encryption/__init__.py
ADDED
encryption/encrypt.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
|
|
6
|
+
from cryptography.hazmat.primitives import hashes
|
|
7
|
+
from jwcrypto import jwk, jwe
|
|
8
|
+
from jwcrypto.common import base64url_encode
|
|
9
|
+
|
|
10
|
+
# Constants equivalent to the TypeScript version
|
|
11
|
+
ENC = 'A256CBC-HS512'
|
|
12
|
+
ALG = 'dir'
|
|
13
|
+
DIGEST = hashes.SHA256()
|
|
14
|
+
BYTE_LENGTH = 64
|
|
15
|
+
ENCRYPTION_INFO = b'Auth0 Generated ryption'
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def derive_encryption_key(secret: bytes, salt: bytes) -> bytes:
|
|
20
|
+
"""
|
|
21
|
+
Derives a key using HKDF with SHA-256.
|
|
22
|
+
"""
|
|
23
|
+
hkdf = HKDF(
|
|
24
|
+
algorithm=DIGEST,
|
|
25
|
+
length=BYTE_LENGTH,
|
|
26
|
+
salt=salt,
|
|
27
|
+
info=ENCRYPTION_INFO,
|
|
28
|
+
)
|
|
29
|
+
return hkdf.derive(secret)
|
|
30
|
+
|
|
31
|
+
def encrypt(payload: dict, secret: str, salt: str) -> str:
|
|
32
|
+
"""
|
|
33
|
+
Encrypts the given payload into a JWE using the direct algorithm and A256CBC-HS512 encryption.
|
|
34
|
+
"""
|
|
35
|
+
# Convert secret and salt to bytes
|
|
36
|
+
secret_bytes = secret.encode('utf-8')
|
|
37
|
+
salt_bytes = salt.encode('utf-8')
|
|
38
|
+
|
|
39
|
+
# Derive the encryption key
|
|
40
|
+
encryption_secret = derive_encryption_key(secret_bytes, salt_bytes)
|
|
41
|
+
|
|
42
|
+
# Create a symmetric key for JWE. jwcrypto expects the key as a base64url-encoded string.
|
|
43
|
+
key = jwk.JWK(k=base64url_encode(encryption_secret), kty="oct")
|
|
44
|
+
|
|
45
|
+
payload_json = json.dumps(payload)
|
|
46
|
+
|
|
47
|
+
# Create a JWE object with the specified header
|
|
48
|
+
jwetoken = jwe.JWE(
|
|
49
|
+
payload_json,
|
|
50
|
+
protected={'alg': ALG, 'enc': ENC}
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
jwetoken.add_recipient(key)
|
|
54
|
+
c = jwetoken.serialize(compact=True)
|
|
55
|
+
|
|
56
|
+
# Return the compact serialization of the token
|
|
57
|
+
return jwetoken.serialize(compact=True)
|
|
58
|
+
|
|
59
|
+
def decrypt(token: str, secret: str, salt: str) -> dict:
|
|
60
|
+
"""
|
|
61
|
+
Decrypts the JWE token back to the original payload.
|
|
62
|
+
"""
|
|
63
|
+
secret_bytes = secret.encode('utf-8')
|
|
64
|
+
salt_bytes = salt.encode('utf-8')
|
|
65
|
+
|
|
66
|
+
encryption_secret = derive_encryption_key(secret_bytes, salt_bytes)
|
|
67
|
+
key = jwk.JWK(k=base64url_encode(encryption_secret), kty="oct")
|
|
68
|
+
|
|
69
|
+
jwetoken = jwe.JWE()
|
|
70
|
+
jwetoken.deserialize(token)
|
|
71
|
+
jwetoken.decrypt(key)
|
|
72
|
+
payload_json = jwetoken.payload.decode('utf-8')
|
|
73
|
+
return json.loads(payload_json)
|
error/__init__.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Error classes for the auth0-server-python SDK.
|
|
3
|
+
These exceptions provide specific error types for different failure scenarios.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
class Auth0Error(Exception):
|
|
7
|
+
"""Base class for all Auth0 SDK errors."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, message=None):
|
|
10
|
+
self.message = message
|
|
11
|
+
super().__init__(message)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MissingTransactionError(Auth0Error):
|
|
15
|
+
"""
|
|
16
|
+
Error raised when a required transaction is missing.
|
|
17
|
+
This typically happens during the callback phase when the transaction
|
|
18
|
+
from the initial authorization request cannot be found.
|
|
19
|
+
"""
|
|
20
|
+
code = "missing_transaction_error"
|
|
21
|
+
|
|
22
|
+
def __init__(self, message=None):
|
|
23
|
+
super().__init__(message or "The transaction is missing.")
|
|
24
|
+
self.name = "MissingTransactionError"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ApiError(Auth0Error):
|
|
28
|
+
"""
|
|
29
|
+
Error raised when an API request to Auth0 fails.
|
|
30
|
+
Contains details about the original error from Auth0.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, code: str, message: str, cause=None):
|
|
34
|
+
super().__init__(message)
|
|
35
|
+
self.code = code
|
|
36
|
+
self.cause = cause
|
|
37
|
+
|
|
38
|
+
# Extract additional error details if available
|
|
39
|
+
if cause:
|
|
40
|
+
self.error = getattr(cause, "error", None)
|
|
41
|
+
self.error_description = getattr(cause, "error_description", None)
|
|
42
|
+
else:
|
|
43
|
+
self.error = None
|
|
44
|
+
self.error_description = None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class AccessTokenError(Auth0Error):
|
|
48
|
+
"""Error raised when there's an issue with access tokens."""
|
|
49
|
+
|
|
50
|
+
def __init__(self, code: str, message: str):
|
|
51
|
+
super().__init__(message)
|
|
52
|
+
self.code = code
|
|
53
|
+
self.name = "AccessTokenError"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class MissingRequiredArgumentError(Auth0Error):
|
|
57
|
+
"""
|
|
58
|
+
Error raised when a required argument is missing.
|
|
59
|
+
Includes the name of the missing argument in the error message.
|
|
60
|
+
"""
|
|
61
|
+
code = "missing_required_argument_error"
|
|
62
|
+
|
|
63
|
+
def __init__(self, argument: str):
|
|
64
|
+
message = f"The argument '{argument}' is required but was not provided."
|
|
65
|
+
super().__init__(message)
|
|
66
|
+
self.name = "MissingRequiredArgumentError"
|
|
67
|
+
self.argument = argument
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class BackchannelLogoutError(Auth0Error):
|
|
71
|
+
"""
|
|
72
|
+
Error raised during backchannel logout processing.
|
|
73
|
+
This can happen when validating or processing logout tokens.
|
|
74
|
+
"""
|
|
75
|
+
code = "backchannel_logout_error"
|
|
76
|
+
|
|
77
|
+
def __init__(self, message: str):
|
|
78
|
+
super().__init__(message)
|
|
79
|
+
self.name = "BackchannelLogoutError"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class AccessTokenForConnectionError(Auth0Error):
|
|
83
|
+
"""Error when retrieving access tokens for a specific connection fails."""
|
|
84
|
+
|
|
85
|
+
def __init__(self, code: str, message: str):
|
|
86
|
+
super().__init__(message)
|
|
87
|
+
self.code = code
|
|
88
|
+
self.name = "AccessTokenForConnectionError"
|
|
89
|
+
|
|
90
|
+
class StartLinkUserError(Auth0Error):
|
|
91
|
+
"""
|
|
92
|
+
Error raised when user linking process fails to start.
|
|
93
|
+
This typically happens when trying to link accounts without
|
|
94
|
+
having an authenticated user first.
|
|
95
|
+
"""
|
|
96
|
+
code = "start_link_user_error"
|
|
97
|
+
|
|
98
|
+
def __init__(self, message: str):
|
|
99
|
+
super().__init__(message)
|
|
100
|
+
self.name = "StartLinkUserError"
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# Error code enumerations - these can be used to identify specific error scenarios
|
|
104
|
+
|
|
105
|
+
class AccessTokenErrorCode:
|
|
106
|
+
"""Error codes for access token operations."""
|
|
107
|
+
MISSING_SESSION = "missing_session"
|
|
108
|
+
MISSING_REFRESH_TOKEN = "missing_refresh_token"
|
|
109
|
+
FAILED_TO_REFRESH_TOKEN = "failed_to_refresh_token"
|
|
110
|
+
FAILED_TO_REQUEST_TOKEN = "failed_to_request_token"
|
|
111
|
+
REFRESH_TOKEN_ERROR = "refresh_token_error"
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class AccessTokenForConnectionErrorCode:
|
|
115
|
+
"""Error codes for connection-specific token operations."""
|
|
116
|
+
MISSING_REFRESH_TOKEN = "missing_refresh_token"
|
|
117
|
+
FAILED_TO_RETRIEVE = "failed_to_retrieve"
|
|
118
|
+
API_ERROR = "api_error"
|
|
119
|
+
FETCH_ERROR = "retrieval_error"
|
store/__init__.py
ADDED
store/abstract.py
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Generic, TypeVar, Optional, Dict, Any
|
|
3
|
+
|
|
4
|
+
from encryption import encrypt, decrypt
|
|
5
|
+
|
|
6
|
+
T = TypeVar('T') # Generic type for the data stored
|
|
7
|
+
|
|
8
|
+
class AbstractDataStore(Generic[T], ABC):
|
|
9
|
+
"""
|
|
10
|
+
Abstract base class for data stores.
|
|
11
|
+
Provides common functionality for different store implementations.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, options: Dict[str, Any]):
|
|
15
|
+
"""
|
|
16
|
+
Initialize the data store with options.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
options: Configuration options including encryption secret
|
|
20
|
+
"""
|
|
21
|
+
self._options = options
|
|
22
|
+
|
|
23
|
+
@abstractmethod
|
|
24
|
+
async def set(self, identifier: str, state: T, remove_if_expires: bool = False, options: Optional[Dict[str, Any]] = None) -> None:
|
|
25
|
+
"""
|
|
26
|
+
Store data with the given identifier.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
identifier: Unique key for the stored data
|
|
30
|
+
state: Data to store
|
|
31
|
+
remove_if_expires: Whether to auto-remove expired data
|
|
32
|
+
options: Additional operation-specific options
|
|
33
|
+
"""
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
@abstractmethod
|
|
37
|
+
async def get(self, identifier: str, options: Optional[Dict[str, Any]] = None) -> Optional[T]:
|
|
38
|
+
"""
|
|
39
|
+
Retrieve data by identifier.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
identifier: Unique key for the stored data
|
|
43
|
+
options: Additional operation-specific options
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
The stored data or None if not found
|
|
47
|
+
"""
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
@abstractmethod
|
|
51
|
+
async def delete(self, identifier: str, options: Optional[Dict[str, Any]] = None) -> None:
|
|
52
|
+
"""
|
|
53
|
+
Delete data by identifier.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
identifier: Unique key for the stored data
|
|
57
|
+
options: Additional operation-specific options
|
|
58
|
+
"""
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
def encrypt(self, identifier: str, state_data: Dict[str, Any]) -> T:
|
|
62
|
+
"""
|
|
63
|
+
Encrypt data before storing.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
identifier: Unique key used as part of encryption salt
|
|
67
|
+
state_data: Data to encrypt
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
Encrypted string representation of the data
|
|
71
|
+
"""
|
|
72
|
+
return encrypt(state_data, self._options.get("secret"), identifier)
|
|
73
|
+
|
|
74
|
+
def decrypt(self, identifier: str, encrypted_data: str) -> T:
|
|
75
|
+
"""
|
|
76
|
+
Decrypt data after retrieval.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
identifier: Unique key used as part of encryption salt
|
|
80
|
+
encrypted_data: Encrypted data to decrypt
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Decrypted data
|
|
84
|
+
"""
|
|
85
|
+
return decrypt(encrypted_data, self._options.get("secret"), identifier)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class StateStore(AbstractDataStore[Dict[str, Any]]):
|
|
89
|
+
"""
|
|
90
|
+
Abstract store for persistent session data.
|
|
91
|
+
Extends AbstractDataStore with logout token functionality.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
async def delete_by_logout_token(self, claims: Dict[str, Any], options: Optional[Dict[str, Any]] = None) -> None:
|
|
95
|
+
"""
|
|
96
|
+
Delete sessions based on logout token claims.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
claims: Claims from the logout token
|
|
100
|
+
options: Additional operation-specific options
|
|
101
|
+
|
|
102
|
+
Note:
|
|
103
|
+
Default implementation throws NotImplementedError.
|
|
104
|
+
Concrete implementations should override this method.
|
|
105
|
+
"""
|
|
106
|
+
raise NotImplementedError("Method not implemented.")
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class TransactionStore(AbstractDataStore[Dict[str, Any]]):
|
|
110
|
+
"""
|
|
111
|
+
Abstract store for temporary transaction data during auth flows.
|
|
112
|
+
"""
|
|
113
|
+
pass
|