From e60d1ab188fb4cb42755ba25e2999bb4069cde6b Mon Sep 17 00:00:00 2001 From: Raymond Penners Date: Tue, 30 Jul 2024 11:57:53 +0200 Subject: [PATCH] feat(headless): Support for exposing `refresh_token` --- allauth/headless/internal/authkit.py | 6 +++--- allauth/headless/internal/restkit/response.py | 6 +++--- allauth/headless/tokens/base.py | 21 +++++++++++++++---- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/allauth/headless/internal/authkit.py b/allauth/headless/internal/authkit.py index a705199ff2..37b470f1a9 100644 --- a/allauth/headless/internal/authkit.py +++ b/allauth/headless/internal/authkit.py @@ -1,5 +1,5 @@ -import typing from contextlib import contextmanager +from typing import Any, Dict, Optional from django.utils.functional import SimpleLazyObject, empty @@ -77,7 +77,7 @@ def authentication_context(request): request.META["CSRF_COOKIE_NEEDS_UPDATE"] = False -def expose_access_token(request) -> typing.Optional[str]: +def expose_access_token(request) -> Optional[Dict[str, Any]]: """ Determines if a new access token needs to be exposed. """ @@ -89,4 +89,4 @@ def expose_access_token(request) -> typing.Optional[str]: if pre_user.is_authenticated and pre_user.pk == request.user.pk: return None strategy = app_settings.TOKEN_STRATEGY - return strategy.create_access_token(request) + return strategy.create_access_token_payload(request) diff --git a/allauth/headless/internal/restkit/response.py b/allauth/headless/internal/restkit/response.py index da5b6a345e..3dc116c894 100644 --- a/allauth/headless/internal/restkit/response.py +++ b/allauth/headless/internal/restkit/response.py @@ -29,13 +29,13 @@ def __init__( def _add_session_meta(self, request, meta: Optional[Dict]) -> Optional[Dict]: session_token = sessionkit.expose_session_token(request) - access_token = authkit.expose_access_token(request) + access_token_payload = authkit.expose_access_token(request) if session_token: meta = meta or {} meta["session_token"] = session_token - if access_token: + if access_token_payload: meta = meta or {} - meta["access_token"] = access_token + meta.update(access_token_payload) return meta diff --git a/allauth/headless/tokens/base.py b/allauth/headless/tokens/base.py index 34a742384c..cd826d5ccf 100644 --- a/allauth/headless/tokens/base.py +++ b/allauth/headless/tokens/base.py @@ -1,19 +1,32 @@ import abc -import typing +from typing import Any, Dict, Optional from django.contrib.sessions.backends.base import SessionBase from django.http import HttpRequest class AbstractTokenStrategy(abc.ABC): - def get_session_token(self, request: HttpRequest) -> typing.Optional[str]: + def get_session_token(self, request: HttpRequest) -> Optional[str]: """ Returns the session token, if any. """ token = request.headers.get("x-session-token") return token - def create_access_token(self, request: HttpRequest) -> typing.Optional[str]: + def create_access_token_payload( + self, request: HttpRequest + ) -> Optional[Dict[str, Any]]: + """ + After authenticating, this method is called to create the access + token response payload, exposing the access token and possibly other + information such as a ``refresh_token`` and ``expires_in``. + """ + at = self.create_access_token(request) + if not at: + return None + return {"access_token": at} + + def create_access_token(self, request: HttpRequest) -> Optional[str]: """Create an access token. While session tokens are required to handle the authentication process, @@ -39,7 +52,7 @@ def create_session_token(self, request: HttpRequest) -> str: ... @abc.abstractmethod - def lookup_session(self, session_token: str) -> typing.Optional[SessionBase]: + def lookup_session(self, session_token: str) -> Optional[SessionBase]: """ Looks up the Django session given the session token. Returns `None` if the session does not / no longer exist.