From 6f5b6a3d009b87921df028f9bd75dae1f00fcff5 Mon Sep 17 00:00:00 2001 From: armanddidierjean <95971503+armanddidierjean@users.noreply.github.com> Date: Sat, 8 Aug 2026 23:32:27 +0200 Subject: [PATCH 1/5] fix: use a schema for enable_inscription body to prevent our ts codegen from failing with a type error --- .../sport_competition/endpoints_sport_competition.py | 10 +++++++--- .../sport_competition/schemas_sport_competition.py | 4 ++++ .../sport_competition/test_sport_inscription.py | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/modules/sport_competition/endpoints_sport_competition.py b/app/modules/sport_competition/endpoints_sport_competition.py index 404792d4d1..2bee1dd3e9 100644 --- a/app/modules/sport_competition/endpoints_sport_competition.py +++ b/app/modules/sport_competition/endpoints_sport_competition.py @@ -3,7 +3,7 @@ from io import BytesIO from uuid import UUID, uuid4 -from fastapi import Body, Depends, HTTPException, Query, Response +from fastapi import Depends, HTTPException, Query, Response from fastapi.responses import FileResponse from sqlalchemy.ext.asyncio import AsyncSession @@ -271,12 +271,12 @@ async def activate_edition( status_code=204, ) async def enable_inscription( + enable_inscription: schemas_sport_competition.CompetitionEnableInscription, edition_id: UUID, db: AsyncSession = Depends(get_db), user: models_users.CoreUser = Depends( is_user_allowed_to([SportCompetitionPermissions.manage_sport_competition]), ), - enable: bool = Body(), ) -> None: """ Enable inscription for a competition edition. @@ -293,7 +293,11 @@ async def enable_inscription( status_code=400, detail="Edition is not active, cannot patch inscription", ) - await cruds_sport_competition.patch_edition_inscription(edition_id, enable, db) + await cruds_sport_competition.patch_edition_inscription( + edition_id, + enable_inscription.enable, + db, + ) @module.router.patch( diff --git a/app/modules/sport_competition/schemas_sport_competition.py b/app/modules/sport_competition/schemas_sport_competition.py index 0b81a9c324..dfc1a46595 100644 --- a/app/modules/sport_competition/schemas_sport_competition.py +++ b/app/modules/sport_competition/schemas_sport_competition.py @@ -35,6 +35,10 @@ class CompetitionEditionEdit(BaseModel): end_date: datetime | None = None +class CompetitionEnableInscription(BaseModel): + enable: bool + + class SchoolExtensionBase(BaseModel): school_id: UUID from_lyon: bool diff --git a/tests/modules/sport_competition/test_sport_inscription.py b/tests/modules/sport_competition/test_sport_inscription.py index 2a3da76227..2ce026fe5a 100644 --- a/tests/modules/sport_competition/test_sport_inscription.py +++ b/tests/modules/sport_competition/test_sport_inscription.py @@ -977,7 +977,7 @@ async def test_enable_inscription_not_active( response = client.post( f"/competition/editions/{old_edition.id}/inscription", headers={"Authorization": f"Bearer {admin_token}"}, - json=True, + json={"enable": True}, ) assert response.status_code == 400, response.json() editions = client.get( @@ -1000,7 +1000,7 @@ async def test_enable_inscription( response = client.post( f"/competition/editions/{active_edition.id}/inscription", headers={"Authorization": f"Bearer {admin_token}"}, - json=True, + json={"enable": True}, ) assert response.status_code == 204, response.json() editions = client.get( From f5f7451dca77227f5fbd73e72e5e9f7924eb6fc2 Mon Sep 17 00:00:00 2001 From: armanddidierjean <95971503+armanddidierjean@users.noreply.github.com> Date: Sat, 8 Aug 2026 23:43:43 +0200 Subject: [PATCH 2/5] feat(auth): log simple_token auth failures and return a schema --- app/core/auth/endpoints_auth.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/core/auth/endpoints_auth.py b/app/core/auth/endpoints_auth.py index 121a2d9fbe..89a78a1da6 100644 --- a/app/core/auth/endpoints_auth.py +++ b/app/core/auth/endpoints_auth.py @@ -71,6 +71,7 @@ async def login_for_access_token( form_data: OAuth2PasswordRequestForm = Depends(), db: AsyncSession = Depends(get_db), settings: Settings = Depends(get_settings), + request_id: str = Depends(get_request_id), ): """ Ask for a JWT access token using oauth password flow. @@ -79,8 +80,12 @@ async def login_for_access_token( Note: the request body needs to use **form-data** and not json. """ - user = await authenticate_user(db, form_data.username, form_data.password) + email = form_data.username + user = await authenticate_user(db, email, form_data.password) if not user: + hyperion_access_logger.warning( + f"Authorize-validation: Invalid user email or password for email {email} ({request_id})", + ) raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect login or password", @@ -90,7 +95,10 @@ async def login_for_access_token( # The subject `sub` is a JWT registered claim name, see https://datatracker.ietf.org/doc/html/rfc7519#section-4.1 data = schemas_auth.TokenData(sub=user.id, scopes=ScopeType.auth) access_token = create_access_token(settings=settings, data=data) - return {"access_token": access_token, "token_type": "bearer"} + return schemas_auth.AccessToken( + access_token=access_token, + token_type="bearer", # noqa: S106 + ) # Authorization Code Grant # From 6038c46d1c531661a6401574828196054e2a965c Mon Sep 17 00:00:00 2001 From: armanddidierjean <95971503+armanddidierjean@users.noreply.github.com> Date: Sat, 8 Aug 2026 23:44:32 +0200 Subject: [PATCH 3/5] test(auth): ensure that simple_token jwt does not give access to the API --- tests/core/test_auth.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/core/test_auth.py b/tests/core/test_auth.py index e247ffebf1..b0f4a8b2bf 100644 --- a/tests/core/test_auth.py +++ b/tests/core/test_auth.py @@ -129,6 +129,10 @@ def test_simple_token(client: TestClient): }, ) assert response.status_code == 403 # forbidden + assert ( + response.json()["detail"] + == "Unauthorized, token does not contain at least one of the following scope_set [['API']]" + ) def test_authorization_code_flow_PKCE(client: TestClient) -> None: From 6e6497de31a595eae508cca44e64cf8d756bb36b Mon Sep 17 00:00:00 2001 From: armanddidierjean <95971503+armanddidierjean@users.noreply.github.com> Date: Sat, 8 Aug 2026 23:46:22 +0200 Subject: [PATCH 4/5] test: test simple token flow with invalid password --- tests/core/test_auth.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/core/test_auth.py b/tests/core/test_auth.py index b0f4a8b2bf..ac9cfa1819 100644 --- a/tests/core/test_auth.py +++ b/tests/core/test_auth.py @@ -135,6 +135,19 @@ def test_simple_token(client: TestClient): ) +def test_simple_token_with_invalid_password(client: TestClient): + response = client.post( + "/auth/simple_token", + data={ + "username": "email@myecl.fr", + "password": "invalid_password", + }, + ) + assert response.status_code == 401 + json = response.json() + assert json["detail"] == "Incorrect login or password" + + def test_authorization_code_flow_PKCE(client: TestClient) -> None: code_verifier = "AntoineMonBelAntoine" code_challenge = "ws9GS3kBIFwDfNghvEk7GRlDvbUkSmZen8q2R4v3lBU=" # base64.urlsafe_b64encode(hashlib.sha256("AntoineMonBelAntoine".encode()).digest()) From c880c25d3064691456404ea74e8311109c06eb56 Mon Sep 17 00:00:00 2001 From: armanddidierjean <95971503+armanddidierjean@users.noreply.github.com> Date: Sat, 8 Aug 2026 23:47:09 +0200 Subject: [PATCH 5/5] feat: two-steps based auth flow OAuth2.0/OIDC auth flow requires an auth scoped token, instead of email/password --- app/core/auth/endpoints_auth.py | 48 ++++++--- app/core/auth/schemas_auth.py | 20 +--- app/utils/examples/examples_auth.py | 3 +- tests/core/test_auth.py | 161 ++++++++++++++++++++++------ 4 files changed, 167 insertions(+), 65 deletions(-) diff --git a/app/core/auth/endpoints_auth.py b/app/core/auth/endpoints_auth.py index 89a78a1da6..238784e8ff 100644 --- a/app/core/auth/endpoints_auth.py +++ b/app/core/auth/endpoints_auth.py @@ -38,9 +38,10 @@ get_token_data, get_user_from_token_with_scopes, ) -from app.types.exceptions import AuthHTTPException +from app.types.exceptions import AuthHTTPException, ObjectExpectedInDbNotFoundError from app.types.module import CoreModule from app.types.scopes_type import ScopeType +from app.utils.auth import auth_utils from app.utils.auth.providers import BaseAuthClient from app.utils.tools import has_user_permission @@ -61,7 +62,6 @@ # WARNING: if new flow are added, openid_config should be updated accordingly -# TODO: maybe remove @router.post( "/auth/simple_token", response_model=schemas_auth.AccessToken, @@ -229,8 +229,7 @@ async def authorize_validation( * parameters that allows to authenticate the user and know which scopes he grants access to. - * `email` - * `password` + * `auth_access_token`: a JWT granting the scope *auth* References: * https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1.2 @@ -308,20 +307,35 @@ async def authorize_validation( url += "&state=" + authorizereq.state return RedirectResponse(url, status_code=status.HTTP_302_FOUND) - # TODO: Currently if the user enters the wrong credentials in the form, they won't be redirected to the login page again but the OAuth process will fail. - user = await authenticate_user(db, authorizereq.email, authorizereq.password) - if not user: - hyperion_access_logger.warning( - f"Authorize-validation: Invalid user email or password for email {authorizereq.email} ({request_id})", + # We check the validity of the jwt token + try: + token_data = auth_utils.get_token_data( + settings=settings, + token=authorizereq.auth_access_token, + request_id=request_id, ) - return RedirectResponse( - settings.CLIENT_URL - + calypsso.get_login_relative_url( - **authorizereq.model_dump(exclude={"email", "password"}), - credentials_error=True, - ), - status_code=status.HTTP_302_FOUND, + except HTTPException as e: + # OAuth specifications requires to redirect to the `redirect_uri` with an error parameter if the request is invalid + # instead of returning a 4xx error code + hyperion_access_logger.warning( + f"Authorize-validation: Invalid auth_access_token {e.status_code}: {e.detail} ({request_id})", ) + url = redirect_uri + "?error=" + e.detail + if authorizereq.state: + url += "&state=" + authorizereq.state + return RedirectResponse(url, status_code=status.HTTP_302_FOUND) + + # The token should have the scope *auth* in order to be able to use this endpoint + user_id = auth_utils.get_user_id_from_token_with_scopes( + scopes=[[ScopeType.auth]], + token_data=token_data, + ) + user = await cruds_users.get_user_by_id( + db=db, + user_id=user_id, + ) + if not user: + raise ObjectExpectedInDbNotFoundError("user", user_id) # The auth_client may restrict the usage of the client to specific Hyperion permissions if auth_client.permission is not None: @@ -333,7 +347,7 @@ async def authorize_validation( ) ): hyperion_access_logger.warning( - f"Authorize-validation: user is not member of an allowed group {authorizereq.email} ({request_id})", + f"Authorize-validation: user is not member of an allowed group {user.email} ({request_id})", ) return RedirectResponse( settings.CLIENT_URL diff --git a/app/core/auth/schemas_auth.py b/app/core/auth/schemas_auth.py index 978d3fd148..0d74e937b0 100644 --- a/app/core/auth/schemas_auth.py +++ b/app/core/auth/schemas_auth.py @@ -4,9 +4,8 @@ from typing import Literal from fastapi import Form -from pydantic import BaseModel, field_validator +from pydantic import BaseModel -from app.utils import validators from app.utils.examples import examples_auth @@ -34,8 +33,7 @@ class AuthorizeValidation(Authorize): ``` """ - email: str - password: str + auth_access_token: str # If we don't add these parameters # the heritage from Authorize does not allow Mypy to infer the str | None @@ -46,12 +44,6 @@ class AuthorizeValidation(Authorize): code_challenge: str | None = None code_challenge_method: str | None = None - # Email normalization, this will modify the email variable - # https://pydantic-docs.helpmanual.io/usage/validators/#reuse-validators - _normalize_email = field_validator( - "email", - )(validators.email_normalizer) - class config: schema_extra = {"example": examples_auth.example_AuthorizeValidation} @@ -66,8 +58,7 @@ def as_form( nonce: str | None = Form(None), code_challenge: str | None = Form(None), code_challenge_method: str | None = Form(None), - email: str = Form(...), - password: str = Form(...), + auth_access_token: str = Form(...), ): if nonce == "None": nonce = None @@ -81,14 +72,13 @@ def as_form( nonce=nonce, code_challenge=code_challenge, code_challenge_method=code_challenge_method, - email=email, - password=password, + auth_access_token=auth_access_token, ) class AccessToken(BaseModel): access_token: str - token_type: str + token_type: Literal["bearer"] class TokenData(BaseModel): diff --git a/app/utils/examples/examples_auth.py b/app/utils/examples/examples_auth.py index ad726d7f99..993624455c 100644 --- a/app/utils/examples/examples_auth.py +++ b/app/utils/examples/examples_auth.py @@ -6,8 +6,7 @@ "state": "azerty", "code_challenge": "c2cf464b7901205c037cd821bc493b191943bdb5244a665e9fcab6478bf79415", # hashlib.sha256("AntoineMonBelAntoine".encode()).hexdigest() "code_challenge_method": "S256", - "email": "email@myecl.fr", - "password": "azerty", + "auth_access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30", } example_TokenReq_access_token = { diff --git a/tests/core/test_auth.py b/tests/core/test_auth.py index ac9cfa1819..af5d0d77ed 100644 --- a/tests/core/test_auth.py +++ b/tests/core/test_auth.py @@ -3,6 +3,7 @@ from datetime import UTC, datetime, timedelta from urllib.parse import parse_qs, urlparse +import pytest import pytest_asyncio from fastapi.testclient import TestClient @@ -106,6 +107,54 @@ async def init_objects() -> None: await add_object_to_db(revoked_refresh_token_db) +@pytest.fixture(scope="module") +def auth_token( + client: TestClient, +) -> str: + response = client.post( + "/auth/simple_token", + data={ + "username": "email@myecl.fr", + "password": "azerty", + }, + ) + assert response.status_code == 200 + json = response.json() + return json["access_token"] + + +@pytest.fixture(scope="module") +def auth_token_of_an_allowed_group( + client: TestClient, +) -> str: + response = client.post( + "/auth/simple_token", + data={ + "username": "email@etu.ec-lyon.fr", + "password": "azerty", + }, + ) + assert response.status_code == 200 + json = response.json() + return json["access_token"] + + +@pytest.fixture(scope="module") +def auth_token_of_an_external( + client: TestClient, +) -> str: + response = client.post( + "/auth/simple_token", + data={ + "username": "external@myecl.fr", + "password": "azerty", + }, + ) + assert response.status_code == 200 + json = response.json() + return json["access_token"] + + def test_simple_token(client: TestClient): response = client.post( "/auth/simple_token", @@ -148,9 +197,48 @@ def test_simple_token_with_invalid_password(client: TestClient): assert json["detail"] == "Incorrect login or password" -def test_authorization_code_flow_PKCE(client: TestClient) -> None: +def test_get_authorize_page(client: TestClient): + code_challenge = "ws9GS3kBIFwDfNghvEk7GRlDvbUkSmZen8q2R4v3lBU=" # base64.urlsafe_b64encode(hashlib.sha256("AntoineMonBelAntoine".encode()).digest()) + + response = client.get( + "/auth/authorize", + params={ + "client_id": "AppAuthClientWithPKCE", + "redirect_uri": "http://127.0.0.1:8000/docs", + "response_type": "code", + "scope": "API openid", + "state": "azerty", + "code_challenge": code_challenge, + "code_challenge_method": "S256", + }, + follow_redirects=False, + ) + assert response.status_code == 302 + + +def test_post_authorize_page(client: TestClient): + code_challenge = "ws9GS3kBIFwDfNghvEk7GRlDvbUkSmZen8q2R4v3lBU=" # base64.urlsafe_b64encode(hashlib.sha256("AntoineMonBelAntoine".encode()).digest()) + + response = client.post( + "/auth/authorize", + data={ + "client_id": "AppAuthClientWithPKCE", + "redirect_uri": "http://127.0.0.1:8000/docs", + "response_type": "code", + "scope": "API openid", + "state": "azerty", + "code_challenge": code_challenge, + "code_challenge_method": "S256", + }, + follow_redirects=False, + ) + assert response.status_code == 302 + + +def test_authorization_code_flow_PKCE(client: TestClient, auth_token: str) -> None: code_verifier = "AntoineMonBelAntoine" code_challenge = "ws9GS3kBIFwDfNghvEk7GRlDvbUkSmZen8q2R4v3lBU=" # base64.urlsafe_b64encode(hashlib.sha256("AntoineMonBelAntoine".encode()).digest()) + data = { "client_id": "AppAuthClientWithPKCE", "redirect_uri": "http://127.0.0.1:8000/docs", @@ -159,8 +247,7 @@ def test_authorization_code_flow_PKCE(client: TestClient) -> None: "state": "azerty", "code_challenge": code_challenge, "code_challenge_method": "S256", - "email": "email@myecl.fr", - "password": "azerty", + "auth_access_token": auth_token, } response = client.post( "/auth/authorization-flow/authorize-validation", @@ -229,7 +316,8 @@ def test_authorization_code_flow_PKCE(client: TestClient) -> None: assert response.status_code == 400 -def test_authorization_code_flow_secret(client: TestClient) -> None: +def test_authorization_code_flow_secret(client: TestClient, auth_token: str) -> None: + data = { "client_id": "AppAuthClientWithClientSecret", "client_secret": "secret", @@ -237,8 +325,7 @@ def test_authorization_code_flow_secret(client: TestClient) -> None: "response_type": "code", "scope": "API openid", "state": "azerty", - "email": "email@myecl.fr", - "password": "azerty", + "auth_access_token": auth_token, } response = client.post( "/auth/authorization-flow/authorize-validation", @@ -310,7 +397,8 @@ def test_authorization_code_flow_secret(client: TestClient) -> None: assert response.status_code == 400 -def test_get_user_info(client: TestClient) -> None: +def test_get_user_info(client: TestClient, auth_token: str) -> None: + # We first need an access token to query user info endpoints # data = { "client_id": "AccountTypePermissionAuthClient", @@ -319,8 +407,7 @@ def test_get_user_info(client: TestClient) -> None: "response_type": "code", "scope": "openid", "state": "azerty", - "email": "email@myecl.fr", - "password": "azerty", + "auth_access_token": auth_token, } response = client.post( "/auth/authorization-flow/authorize-validation", @@ -359,7 +446,8 @@ def test_get_user_info(client: TestClient) -> None: assert json["name"] == user.full_name -def test_get_user_info_in_id_token(client: TestClient) -> None: +def test_get_user_info_in_id_token(client: TestClient, auth_token: str) -> None: + # We first need an access token to query user info endpoints # data = { "client_id": "AccountTypePermissionAuthClient", @@ -368,8 +456,7 @@ def test_get_user_info_in_id_token(client: TestClient) -> None: "response_type": "code", "scope": "openid", "state": "azerty", - "email": "email@myecl.fr", - "password": "azerty", + "auth_access_token": auth_token, } response = client.post( "/auth/authorization-flow/authorize-validation", @@ -409,7 +496,11 @@ def test_get_user_info_in_id_token(client: TestClient) -> None: # Invalid service configuration -def test_authorization_code_flow_with_invalid_client_id(client: TestClient) -> None: +def test_authorization_code_flow_with_invalid_client_id( + client: TestClient, + auth_token: str, +) -> None: + data_with_invalid_client_id = { "client_id": "InvalidClientId", "client_secret": "secret", @@ -417,8 +508,7 @@ def test_authorization_code_flow_with_invalid_client_id(client: TestClient) -> N "response_type": "code", "scope": "API openid", "state": "azerty", - "email": "email@myecl.fr", - "password": "azerty", + "auth_access_token": auth_token, } response = client.post( "/auth/authorization-flow/authorize-validation", @@ -433,7 +523,11 @@ def test_authorization_code_flow_with_invalid_client_id(client: TestClient) -> N # Invalid service configuration -def test_authorization_code_flow_with_invalid_redirect_uri(client: TestClient) -> None: +def test_authorization_code_flow_with_invalid_redirect_uri( + client: TestClient, + auth_token: str, +) -> None: + data_with_invalid_client_id = { "client_id": "AppAuthClientWithClientSecret", "client_secret": "secret", @@ -441,8 +535,7 @@ def test_authorization_code_flow_with_invalid_redirect_uri(client: TestClient) - "response_type": "code", "scope": "API openid", "state": "azerty", - "email": "email@myecl.fr", - "password": "azerty", + "auth_access_token": auth_token, } response = client.post( "/auth/authorization-flow/authorize-validation", @@ -458,7 +551,11 @@ def test_authorization_code_flow_with_invalid_redirect_uri(client: TestClient) - # Invalid service configuration -def test_authorization_code_flow_with_invalid_response_type(client: TestClient) -> None: +def test_authorization_code_flow_with_invalid_response_type( + client: TestClient, + auth_token: str, +) -> None: + data_with_invalid_client_id = { "client_id": "AppAuthClientWithClientSecret", "client_secret": "secret", @@ -466,8 +563,7 @@ def test_authorization_code_flow_with_invalid_response_type(client: TestClient) "response_type": "invalid_response_type", "scope": "API openid", "state": "azerty", - "email": "email@myecl.fr", - "password": "azerty", + "auth_access_token": auth_token, } response = client.post( "/auth/authorization-flow/authorize-validation", @@ -482,9 +578,11 @@ def test_authorization_code_flow_with_invalid_response_type(client: TestClient) # Invalid user response -def test_authorization_code_flow_with_invalid_user_credentials( +def test_authorization_code_flow_with_invalid_auth_token( client: TestClient, ) -> None: + auth_access_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30" + data_with_invalid_client_id = { "client_id": "AppAuthClientWithClientSecret", "client_secret": "secret", @@ -492,8 +590,7 @@ def test_authorization_code_flow_with_invalid_user_credentials( "response_type": "code", "scope": "API openid", "state": "azerty", - "email": "email@myecl.fr", - "password": "other invalid password", + "auth_access_token": auth_access_token, } response = client.post( "/auth/authorization-flow/authorize-validation", @@ -503,13 +600,14 @@ def test_authorization_code_flow_with_invalid_user_credentials( assert response.status_code == 302 assert response.next_request is not None assert str(response.next_request.url).endswith( - "calypsso/login/?client_id=AppAuthClientWithClientSecret&response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Fdocs&scope=API+openid&state=azerty&credentials_error=True", + "?error=Could%20not%20validate%20credentials&state=azerty", ) # Valid user response def test_authorization_code_flow_with_group_permission_and_user_member_of_an_allowed_group( client: TestClient, + auth_token_of_an_allowed_group: str, ) -> None: # For an user that is a member of a required group # data_with_invalid_client_id = { @@ -519,8 +617,7 @@ def test_authorization_code_flow_with_group_permission_and_user_member_of_an_all "response_type": "code", "scope": "API openid", "state": "azerty", - "email": "email@etu.ec-lyon.fr", - "password": "azerty", + "auth_access_token": auth_token_of_an_allowed_group, } response = client.post( "/auth/authorization-flow/authorize-validation", @@ -537,7 +634,9 @@ def test_authorization_code_flow_with_group_permission_and_user_member_of_an_all def test_authorization_code_flow_with_group_permission_and_user_not_member_of_an_allowed_group( client: TestClient, + auth_token_of_an_external: str, ) -> None: + # For an user that is not a member of a required group # data_with_invalid_client_id = { "client_id": "GroupPermissionAuthClient", @@ -546,8 +645,7 @@ def test_authorization_code_flow_with_group_permission_and_user_not_member_of_an "response_type": "code", "scope": "API openid", "state": "azerty", - "email": "external@myecl.fr", - "password": "azerty", + "auth_access_token": auth_token_of_an_external, } response = client.post( "/auth/authorization-flow/authorize-validation", @@ -586,7 +684,9 @@ def test_authorization_code_flow_with_group_permission_and_user_not_member_of_an def test_authorization_code_flow_with_account_type_permission_and_wrong_account_type( client: TestClient, + auth_token_of_an_external: str, ) -> None: + # For an user that is not a member of a required group # data_with_invalid_client_id = { "client_id": "AccountTypePermissionAuthClient", @@ -595,8 +695,7 @@ def test_authorization_code_flow_with_account_type_permission_and_wrong_account_ "response_type": "code", "scope": "API openid", "state": "azerty", - "email": "external@myecl.fr", - "password": "azerty", + "auth_access_token": auth_token_of_an_external, } response = client.post( "/auth/authorization-flow/authorize-validation",