diff --git a/api/custom_auth/oauth/views.py b/api/custom_auth/oauth/views.py index 8eb11d59b73c..e526b6b86603 100644 --- a/api/custom_auth/oauth/views.py +++ b/api/custom_auth/oauth/views.py @@ -1,12 +1,15 @@ import logging +from django.conf import settings from drf_yasg.utils import swagger_auto_schema # type: ignore[import-untyped] from rest_framework import status from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import AllowAny from rest_framework.response import Response +from rest_framework.status import HTTP_204_NO_CONTENT from api.serializers import ErrorSerializer +from custom_auth.jwt_cookie.services import authorise_response from custom_auth.oauth.exceptions import GithubError, GoogleError from custom_auth.oauth.serializers import ( GithubLoginSerializer, @@ -35,6 +38,8 @@ def login_with_google(request): # type: ignore[no-untyped-def] ) serializer.is_valid(raise_exception=True) token = serializer.save() + if settings.COOKIE_AUTH_ENABLED: + return authorise_response(token.user, Response(status=HTTP_204_NO_CONTENT)) return Response(data=CustomTokenSerializer(instance=token).data) except GoogleError as e: logger.warning("%s: %s" % (GOOGLE_AUTH_ERROR_MESSAGE, str(e))) @@ -58,6 +63,8 @@ def login_with_github(request): # type: ignore[no-untyped-def] ) serializer.is_valid(raise_exception=True) token = serializer.save() + if settings.COOKIE_AUTH_ENABLED: + return authorise_response(token.user, Response(status=HTTP_204_NO_CONTENT)) return Response(data=CustomTokenSerializer(instance=token).data) except GithubError as e: logger.warning("%s: %s" % (GITHUB_AUTH_ERROR_MESSAGE, str(e))) diff --git a/api/tests/unit/custom_auth/oauth/test_unit_oauth_views.py b/api/tests/unit/custom_auth/oauth/test_unit_oauth_views.py index d36a9f4aec7e..d292fd168194 100644 --- a/api/tests/unit/custom_auth/oauth/test_unit_oauth_views.py +++ b/api/tests/unit/custom_auth/oauth/test_unit_oauth_views.py @@ -1,3 +1,4 @@ +from typing import Any from unittest import mock from django.db.models import Model @@ -301,3 +302,69 @@ def test_user_with_duplicate_accounts_authenticates_as_the_correct_oauth_user( google_auth_key = auth_with_google_response.json().get("key") assert google_auth_key == google_user.auth_token.key + + +@mock.patch("custom_auth.oauth.serializers.get_user_info") +@override_settings(COOKIE_AUTH_ENABLED=True) +def test_login_with_google_jwt_cookie( + mock_get_user_info: mock.Mock, + db: None, + django_user_model: type[Any], + api_client: APIClient, +) -> None: + # Given + email = "test@example.com" + google_user_id = "abc123" + + django_user_model.objects.create(email=email) + mock_get_user_info.return_value = { + "email": email, + "first_name": "John", + "last_name": "Smith", + "google_user_id": google_user_id, + } + + url = reverse("api-v1:custom_auth:oauth:google-oauth-login") + + # When + response = api_client.post(url, data={"access_token": "some-token"}) + + # Then + assert response.status_code == status.HTTP_204_NO_CONTENT + assert response.cookies["jwt"]["httponly"] is True + assert not response.data + + +@override_settings(COOKIE_AUTH_ENABLED=True) +def test_login_with_github_jwt_cookie( + db: None, + django_user_model: type[Any], + api_client: APIClient, + mocker: MockerFixture, +) -> None: + # Given + email = "test@example.com" + github_user_id = "abc123" + + django_user_model.objects.create(email=email) + + mock_github_user = mock.MagicMock() + mocker.patch( + "custom_auth.oauth.serializers.GithubUser", return_value=mock_github_user + ) + mock_github_user.get_user_info.return_value = { + "email": email, + "first_name": "John", + "last_name": "Smith", + "github_user_id": github_user_id, + } + + url = reverse("api-v1:custom_auth:oauth:github-oauth-login") + + # When + response = api_client.post(url, data={"access_token": "some-token"}) + + # Then + assert response.status_code == status.HTTP_204_NO_CONTENT + assert response.cookies["jwt"]["httponly"] is True + assert not response.data