(backend) add unit tests for user provisioning via external API

Add test coverage for provisional user creation through the external API,
including creating users with email-only (no sub)
This commit is contained in:
lebaudantoine
2025-12-17 17:03:50 +01:00
committed by aleb_the_flash
parent 827014c952
commit fe83c5fa07

View File

@@ -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",
}