diff --git a/src/backend/core/tests/test_external_api_token.py b/src/backend/core/tests/test_external_api_token.py index e37ca179..450dec9d 100644 --- a/src/backend/core/tests/test_external_api_token.py +++ b/src/backend/core/tests/test_external_api_token.py @@ -14,7 +14,7 @@ from core.factories import ( ApplicationFactory, UserFactory, ) -from core.models import ApplicationScope +from core.models import ApplicationScope, User pytestmark = pytest.mark.django_db @@ -232,6 +232,7 @@ def test_api_applications_token_payload_structure(settings): """Generated token should have correct payload structure.""" settings.APPLICATION_JWT_SECRET_KEY = "devKey" user = UserFactory(email="user@example.com") + application = ApplicationFactory( active=True, scopes=[ApplicationScope.ROOMS_LIST, ApplicationScope.ROOMS_CREATE], @@ -273,3 +274,119 @@ def test_api_applications_token_payload_structure(settings): "delegated": True, "scope": "rooms:list rooms:create", } + + +@freeze_time("2023-01-15 12:00:00") +def test_api_applications_token_new_user(settings): + """Should create a new pending user when creation is allowed and user doesn't exist.""" + + settings.APPLICATION_JWT_SECRET_KEY = "devKey" + settings.APPLICATION_ALLOW_USER_CREATION = True + settings.OIDC_FALLBACK_TO_EMAIL_FOR_IDENTIFICATION = True + settings.OIDC_USER_SUB_FIELD_IMMUTABLE = False + + assert len(User.objects.all()) == 0 + + application = ApplicationFactory( + active=True, + scopes=[ApplicationScope.ROOMS_LIST, ApplicationScope.ROOMS_CREATE], + ) + + plain_secret = "test-secret-123" + application.client_secret = plain_secret + application.save() + + client = APIClient() + response = client.post( + "/external-api/v1.0/application/token/", + { + "client_id": application.client_id, + "client_secret": plain_secret, + "grant_type": "client_credentials", + "scope": "unknown@world.com", + }, + format="json", + ) + + # Decode token to verify payload + token = response.data["access_token"] + payload = jwt.decode( + token, + settings.APPLICATION_JWT_SECRET_KEY, + algorithms=[settings.APPLICATION_JWT_ALG], + issuer=settings.APPLICATION_JWT_ISSUER, + audience=settings.APPLICATION_JWT_AUDIENCE, + ) + + user = User.objects.get(email="unknown@world.com") + assert user.sub is None + + assert payload == { + "iss": settings.APPLICATION_JWT_ISSUER, + "aud": settings.APPLICATION_JWT_AUDIENCE, + "client_id": application.client_id, + "exp": 1673787600, + "iat": 1673784000, + "user_id": str(user.id), + "delegated": True, + "scope": "rooms:list rooms:create", + } + + +@freeze_time("2023-01-15 12:00:00") +def test_api_applications_token_existing_user(settings): + """Application should not create a new user when user exist.""" + + settings.APPLICATION_JWT_SECRET_KEY = "devKey" + user = UserFactory(email="user@example.com") + + settings.APPLICATION_ALLOW_USER_CREATION = True + settings.OIDC_FALLBACK_TO_EMAIL_FOR_IDENTIFICATION = True + settings.OIDC_USER_SUB_FIELD_IMMUTABLE = False + + assert len(User.objects.all()) == 1 + + application = ApplicationFactory( + active=True, + scopes=[ApplicationScope.ROOMS_LIST, ApplicationScope.ROOMS_CREATE], + ) + + plain_secret = "test-secret-123" + application.client_secret = plain_secret + application.save() + + client = APIClient() + response = client.post( + "/external-api/v1.0/application/token/", + { + "client_id": application.client_id, + "client_secret": plain_secret, + "grant_type": "client_credentials", + "scope": user.email, + }, + format="json", + ) + + # Assert no new user was created + assert len(User.objects.all()) == 1 + + # Decode token to verify payload + token = response.data["access_token"] + payload = jwt.decode( + token, + settings.APPLICATION_JWT_SECRET_KEY, + algorithms=[settings.APPLICATION_JWT_ALG], + issuer=settings.APPLICATION_JWT_ISSUER, + audience=settings.APPLICATION_JWT_AUDIENCE, + ) + + assert payload == { + "iss": settings.APPLICATION_JWT_ISSUER, + "aud": settings.APPLICATION_JWT_AUDIENCE, + "client_id": application.client_id, + "exp": 1673787600, + "iat": 1673784000, + "user_id": str(user.id), + "delegated": True, + "scope": "rooms:list rooms:create", + }