From 77d0077503d9d6b4dd206e3fc643d96bc3c5834c Mon Sep 17 00:00:00 2001 From: "Can H. Tartanoglu" Date: Fri, 22 Jul 2022 15:53:56 +0200 Subject: [PATCH] Cookie transport must return empty json and not `null` in `response.data` on login (#1037) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix: LoginResponse is set to application/json, and should return response with status code 204 when body is empty. The database backend login response is a cookie header with empty body. This causes issues when integrating the openapi schema into openapi-generator. Because the code generator expects the response to be a JSON when the status code isn't 204. * Fix: Bump fastapi version to appropriate version for status code 204 handling. * Build a full response for CookieTransport login_response Co-authored-by: Can H. Tartanoglu <2947298-caniko@users.noreply.gitlab.com> Co-authored-by: François Voron --- fastapi_users/authentication/transport/cookie.py | 8 +++----- tests/test_authentication_transport_cookie.py | 8 ++++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/fastapi_users/authentication/transport/cookie.py b/fastapi_users/authentication/transport/cookie.py index 6fa8e198..372a5eb5 100644 --- a/fastapi_users/authentication/transport/cookie.py +++ b/fastapi_users/authentication/transport/cookie.py @@ -30,6 +30,7 @@ class CookieTransport(Transport): self.scheme = APIKeyCookie(name=self.cookie_name, auto_error=False) async def get_login_response(self, token: str, response: Response) -> Any: + response = Response(status_code=status.HTTP_204_NO_CONTENT) response.set_cookie( self.cookie_name, token, @@ -40,10 +41,7 @@ class CookieTransport(Transport): httponly=self.cookie_httponly, samesite=self.cookie_samesite, ) - - # We shouldn't return directly the response - # so that FastAPI can terminate it properly - return None + return response async def get_logout_response(self, response: Response) -> Any: response.set_cookie( @@ -59,7 +57,7 @@ class CookieTransport(Transport): @staticmethod def get_openapi_login_responses_success() -> OpenAPIResponseType: - return {status.HTTP_200_OK: {"model": None}} + return {status.HTTP_204_NO_CONTENT: {"model": None}} @staticmethod def get_openapi_logout_responses_success() -> OpenAPIResponseType: diff --git a/tests/test_authentication_transport_cookie.py b/tests/test_authentication_transport_cookie.py index ca99f9ca..7c90808f 100644 --- a/tests/test_authentication_transport_cookie.py +++ b/tests/test_authentication_transport_cookie.py @@ -38,10 +38,10 @@ async def test_get_login_response(cookie_transport: CookieTransport): secure = cookie_transport.cookie_secure httponly = cookie_transport.cookie_httponly - response = Response() - login_response = await cookie_transport.get_login_response("TOKEN", response) + response = await cookie_transport.get_login_response("TOKEN", Response()) - assert login_response is None + assert isinstance(response, Response) + assert response.status_code == status.HTTP_204_NO_CONTENT cookies = [header for header in response.raw_headers if header[0] == b"set-cookie"] assert len(cookies) == 1 @@ -96,7 +96,7 @@ async def test_get_logout_response(cookie_transport: CookieTransport): @pytest.mark.openapi def test_get_openapi_login_responses_success(cookie_transport: CookieTransport): assert cookie_transport.get_openapi_login_responses_success() == { - status.HTTP_200_OK: {"model": None} + status.HTTP_204_NO_CONTENT: {"model": None} }