Skip to content

Commit

Permalink
Support SECRET_KEY_FALLBACKS when loading tokens
Browse files Browse the repository at this point in the history
This allows for key rotation by placing the old key in the fallbacks
and switching to a new key. The new key would be used for dumping with
both used for loading.
  • Loading branch information
pgjones committed Dec 26, 2024
1 parent 9abd946 commit 9d54133
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/quart_auth/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from contextlib import asynccontextmanager
from enum import auto, Enum
from hashlib import sha512
from typing import Any, AsyncGenerator, cast, Dict, Literal, Optional, Type, Union
from typing import Any, AsyncGenerator, cast, Dict, Iterable, Literal, Optional, Type, Union

from itsdangerous import BadSignature, SignatureExpired, URLSafeTimedSerializer
from quart import (
Expand Down Expand Up @@ -46,7 +46,9 @@ class Action(Enum):


class _AuthSerializer(URLSafeTimedSerializer):
def __init__(self, secret: Union[str, bytes], salt: Union[str, bytes]) -> None:
def __init__(
self, secret: Union[str, bytes, Iterable[str], Iterable[bytes]], salt: Union[str, bytes]
) -> None:
super().__init__(secret, salt, signer_kwargs={"digest_method": sha512})


Expand Down Expand Up @@ -203,7 +205,12 @@ def load_token(self, token: str, app: Optional[Quart] = None) -> Optional[str]:
if app is None:
app = current_app

serializer = self.serializer_class(app.secret_key, self.salt)
keys = [app.secret_key]

if fallbacks := app.config.get("SECRET_KEY_FALLBACKS"):
keys.extend(fallbacks)

serializer = self.serializer_class(keys, self.salt) # type: ignore[arg-type]
try:
return serializer.loads(token, max_age=self.duration)
except (BadSignature, SignatureExpired):
Expand Down

0 comments on commit 9d54133

Please sign in to comment.