|
2 | 2 | from contextlib import asynccontextmanager |
3 | 3 | from enum import auto, Enum |
4 | 4 | from hashlib import sha512 |
5 | | -from typing import Any, AsyncGenerator, cast, Dict, Literal, Optional, Type, Union |
| 5 | +from typing import Any, AsyncGenerator, cast, Dict, Iterable, Literal, Optional, Type, Union |
6 | 6 |
|
7 | 7 | from itsdangerous import BadSignature, SignatureExpired, URLSafeTimedSerializer |
8 | 8 | from quart import ( |
@@ -46,7 +46,9 @@ class Action(Enum): |
46 | 46 |
|
47 | 47 |
|
48 | 48 | class _AuthSerializer(URLSafeTimedSerializer): |
49 | | - def __init__(self, secret: Union[str, bytes], salt: Union[str, bytes]) -> None: |
| 49 | + def __init__( |
| 50 | + self, secret: Union[str, bytes, Iterable[str], Iterable[bytes]], salt: Union[str, bytes] |
| 51 | + ) -> None: |
50 | 52 | super().__init__(secret, salt, signer_kwargs={"digest_method": sha512}) |
51 | 53 |
|
52 | 54 |
|
@@ -203,7 +205,12 @@ def load_token(self, token: str, app: Optional[Quart] = None) -> Optional[str]: |
203 | 205 | if app is None: |
204 | 206 | app = current_app |
205 | 207 |
|
206 | | - serializer = self.serializer_class(app.secret_key, self.salt) |
| 208 | + keys = [app.secret_key] |
| 209 | + |
| 210 | + if fallbacks := app.config.get("SECRET_KEY_FALLBACKS"): |
| 211 | + keys.extend(fallbacks) |
| 212 | + |
| 213 | + serializer = self.serializer_class(keys, self.salt) # type: ignore[arg-type] |
207 | 214 | try: |
208 | 215 | return serializer.loads(token, max_age=self.duration) |
209 | 216 | except (BadSignature, SignatureExpired): |
|
0 commit comments