From 31d51be3e4255715f5aa47a8afbacd192a6b7e80 Mon Sep 17 00:00:00 2001 From: Quentin BEY Date: Tue, 13 May 2025 23:31:28 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B(auth)=20allow=20several=20auth=20b?= =?UTF-8?q?ackend=20on=20m2m=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous `ServerToServerAuthentication` was raising authentication failed error if anything is wrong (the header, the token) which prevents any possibility to have several authentication backends. --- src/backend/core/api/viewsets.py | 2 +- src/backend/core/authentication/__init__.py | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index cd79f4c8b..e042a6f72 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -689,7 +689,7 @@ class DocumentViewSet( authentication_classes=[authentication.ServerToServerAuthentication], detail=False, methods=["post"], - permission_classes=[], + permission_classes=[permissions.IsAuthenticated], url_path="create-for-owner", ) @transaction.atomic diff --git a/src/backend/core/authentication/__init__.py b/src/backend/core/authentication/__init__.py index c5fa0c711..d5c6c4e31 100644 --- a/src/backend/core/authentication/__init__.py +++ b/src/backend/core/authentication/__init__.py @@ -6,6 +6,15 @@ from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed +class AuthenticatedServer: + """ + Simple class to represent an authenticated server to be used along the + IsAuthenticated permission. + """ + + is_authenticated = True + + class ServerToServerAuthentication(BaseAuthentication): """ Custom authentication class for server-to-server requests. @@ -39,13 +48,16 @@ class ServerToServerAuthentication(BaseAuthentication): # Validate token format and existence auth_parts = auth_header.split(" ") if len(auth_parts) != 2 or auth_parts[0] != self.TOKEN_TYPE: - raise AuthenticationFailed("Invalid authorization header.") + # Do not raise here to leave the door open for other authentication methods + return None token = auth_parts[1] if token not in settings.SERVER_TO_SERVER_API_TOKENS: - raise AuthenticationFailed("Invalid server-to-server token.") + # Do not raise here to leave the door open for other authentication methods + return None - # Authentication is successful, but no user is authenticated + # Authentication is successful + return AuthenticatedServer(), token def authenticate_header(self, request): """Return the WWW-Authenticate header value."""