diff --git a/lemarche/api/authentication.py b/lemarche/api/authentication.py index ea195db3d..8e909a423 100644 --- a/lemarche/api/authentication.py +++ b/lemarche/api/authentication.py @@ -13,21 +13,15 @@ class CustomBearerAuthentication(BaseAuthentication): """ Authentication via: 1. Authorization header: Bearer (recommended). - 2. URL parameter ?token= (deprecated, temporary support). """ def authenticate(self, request): token = None - warning_issued = False # Priority to the Authorization header auth_header = request.headers.get("Authorization") if auth_header and auth_header.startswith("Bearer "): token = auth_header.split("Bearer ")[1] - elif request.GET.get("token"): # Otherwise, try the URL parameter - token = request.GET.get("token") - warning_issued = True - logger.info("Authentication via URL token detected. This method is deprecated and less secure.") # If no token is provided if not token: @@ -46,10 +40,6 @@ def authenticate(self, request): except User.DoesNotExist: raise AuthenticationFailed("Invalid or expired token") - # Add a warning in the response for URL tokens - if warning_issued: - request._deprecated_auth_warning = True # Marker for middleware or view - # Return the user and the token return (user, token) @@ -58,35 +48,3 @@ def authenticate_header(self, request): Returns the expected header for 401 responses. """ return 'Bearer realm="api"' - - -class DeprecationWarningMiddleware: - """ - Middleware to inform users that authentication via URL `?token=` is deprecated. - - This middleware checks if the request contains a deprecated authentication token - and adds a warning header to the response if it does. - - Attributes: - get_response (callable): The next middleware or view in the chain. - - Methods: - __call__(request): - Processes the request and adds a deprecation warning header to the response - if the request contains a deprecated authentication token. - """ - - def __init__(self, get_response): - self.get_response = get_response - - def __call__(self, request): - response = self.get_response(request) - - # Add a warning if the marker is set in the request - if hasattr(request, "_deprecated_auth_warning") and request._deprecated_auth_warning: - response.headers["Deprecation-Warning"] = ( - "URL token authentication is deprecated and will be removed on 2025/01. " - "Please use Authorization header with Bearer tokens." - ) - - return response diff --git a/lemarche/api/siaes/views.py b/lemarche/api/siaes/views.py index 718c14721..d01b7751f 100644 --- a/lemarche/api/siaes/views.py +++ b/lemarche/api/siaes/views.py @@ -1,6 +1,6 @@ from django.http import HttpResponseBadRequest from django.shortcuts import get_object_or_404 -from drf_spectacular.utils import OpenApiParameter, extend_schema +from drf_spectacular.utils import extend_schema from rest_framework import mixins, viewsets from rest_framework.response import Response @@ -23,11 +23,6 @@ class SiaeViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.Gen @extend_schema( summary="Lister toutes les structures", tags=[Siae._meta.verbose_name_plural], - parameters=[ - OpenApiParameter( - name="token", description="Token Utilisateur (pour compatibilité ancienne)", required=False, type=str - ), - ], ) def list(self, request, format=None): """ @@ -49,11 +44,6 @@ def list(self, request, format=None): @extend_schema( summary="Détail d'une structure (par son id)", tags=[Siae._meta.verbose_name_plural], - parameters=[ - OpenApiParameter( - name="token", description="Token Utilisateur (pour compatibilité ancienne)", required=False, type=str - ), - ], responses=SiaeDetailSerializer, ) def retrieve(self, request, pk=None, format=None): @@ -67,11 +57,6 @@ def retrieve(self, request, pk=None, format=None): @extend_schema( summary="Détail d'une structure (par son slug)", tags=[Siae._meta.verbose_name_plural], - parameters=[ - OpenApiParameter( - name="token", description="Token Utilisateur (pour compatibilité ancienne)", required=False, type=str - ), - ], responses=SiaeDetailSerializer, ) def retrieve_by_slug(self, request, slug=None, format=None): @@ -86,11 +71,6 @@ def retrieve_by_slug(self, request, slug=None, format=None): @extend_schema( summary="Détail d'une structure (par son siren)", tags=[Siae._meta.verbose_name_plural], - parameters=[ - OpenApiParameter( - name="token", description="Token Utilisateur (pour compatibilité ancienne)", required=False, type=str - ), - ], responses=SiaeDetailSerializer, ) def retrieve_by_siren(self, request, siren=None, format=None): @@ -106,11 +86,6 @@ def retrieve_by_siren(self, request, siren=None, format=None): @extend_schema( summary="Détail d'une structure (par son siret)", tags=[Siae._meta.verbose_name_plural], - parameters=[ - OpenApiParameter( - name="token", description="Token Utilisateur (pour compatibilité ancienne)", required=False, type=str - ), - ], responses=SiaeDetailSerializer, ) def retrieve_by_siret(self, request, siret=None, format=None): diff --git a/lemarche/api/tenders/views.py b/lemarche/api/tenders/views.py index 9ab1d8b4b..bff170eb9 100644 --- a/lemarche/api/tenders/views.py +++ b/lemarche/api/tenders/views.py @@ -1,6 +1,6 @@ from django.conf import settings from django.utils import timezone -from drf_spectacular.utils import OpenApiParameter, extend_schema +from drf_spectacular.utils import extend_schema from rest_framework import mixins, viewsets from rest_framework.permissions import IsAuthenticated @@ -23,9 +23,6 @@ class TenderViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet): @extend_schema( summary="Déposer un besoin d'achat", tags=[Tender._meta.verbose_name_plural], - parameters=[ - OpenApiParameter(name="token", description="Token Utilisateur", required=True, type=str), - ], ) def create(self, request, *args, **kwargs): return super().create(request, args, kwargs) diff --git a/lemarche/api/tests.py b/lemarche/api/tests.py index a7528b4b5..9020f532b 100644 --- a/lemarche/api/tests.py +++ b/lemarche/api/tests.py @@ -1,8 +1,7 @@ -from django.http import HttpResponse from django.test import RequestFactory, TestCase from rest_framework.exceptions import AuthenticationFailed -from lemarche.api.authentication import CustomBearerAuthentication, DeprecationWarningMiddleware +from lemarche.api.authentication import CustomBearerAuthentication from lemarche.api.utils import generate_random_string from lemarche.users.factories import UserFactory @@ -117,44 +116,3 @@ def test_authentication_with_no_token(self): result = self.authentication.authenticate(request) self.assertIsNone(result) - - -class DeprecationWarningMiddlewareTest(TestCase): - def setUp(self): - self.factory = RequestFactory() - self.middleware = DeprecationWarningMiddleware(lambda request: HttpResponse("Test response")) - - def test_no_deprecation_warning(self): - """ - Test that no deprecation warning is present in the response. - - This test sends a GET request to a specific API endpoint and checks - that the response does not contain a 'Deprecation-Warning' attribute. - """ - request = self.factory.get("/api/some-endpoint/") - response = self.middleware(request) - - self.assertFalse(hasattr(response, "Deprecation-Warning")) - - def test_with_deprecation_warning(self): - """ - Test that a deprecation warning is included in the response when the request - contains the _deprecated_auth_warning marker. - - This test simulates a request to an endpoint with the _deprecated_auth_warning - marker set to True. It then checks that the response includes a "Deprecation-Warning" - header with the expected deprecation message indicating that URL token authentication - is deprecated and will be removed by January 2025, and advises to use the Authorization - header with Bearer tokens instead. - """ - request = self.factory.get("/api/some-endpoint/") - request._deprecated_auth_warning = True # Ajouter le marqueur - - response = self.middleware(request) - - self.assertIn("Deprecation-Warning", response) - self.assertEqual( - response["Deprecation-Warning"], - "URL token authentication is deprecated and will be removed on 2025/01. " - "Please use Authorization header with Bearer tokens.", - ) diff --git a/lemarche/templates/api/home.html b/lemarche/templates/api/home.html index 5689b6f34..2ad88a811 100644 --- a/lemarche/templates/api/home.html +++ b/lemarche/templates/api/home.html @@ -64,12 +64,7 @@

Comment obtenir un token ?

Comment se servir du token ?

-

Rien de plus simple, il suffit de rajouter token=<VOTRE-TOKEN> dans l'URL de vos requêtes API

-

- Exemples :
- - https://lemarche.inclusion.beta.gouv.fr/api/siae/?token=test
- - https://lemarche.inclusion.beta.gouv.fr/api/siae/?department=38&kind=ESAT&token=test -

+

Rien de plus simple, il suffit de rajouter token=<VOTRE-TOKEN> dans le header "authorization" de vos requêtes API