"""Connexion par mot de passe (admins) et séparation des deux systèmes.""" from sqlmodel import select from app.models import MagicLinkToken, Role PASSWORD = "coordination-2026" def _url(edition, suffix): return f"/editions/{edition.id}/auth/{suffix}" def test_login_with_correct_password(raw_client, edition, make_account): make_account(Role.COORDINATOR, email="admin@e.fr", password=PASSWORD) resp = raw_client.post( _url(edition, "login"), json={"email": "ADMIN@e.fr", "password": PASSWORD}, ) assert resp.status_code == 200 body = resp.json() assert body["token_type"] == "bearer" assert body["account"]["role"] == "COORDINATOR" assert body["account"]["auth_method"] == "password" def test_login_rejects_wrong_password(raw_client, edition, make_account): make_account(Role.COORDINATOR, email="admin@e.fr", password=PASSWORD) resp = raw_client.post( _url(edition, "login"), json={"email": "admin@e.fr", "password": "faux"}, ) assert resp.status_code == 401 assert resp.json()["detail"]["code"] == "auth.invalid_credentials" def test_login_rejects_unknown_email(raw_client, edition): resp = raw_client.post( _url(edition, "login"), json={"email": "personne@e.fr", "password": PASSWORD}, ) assert resp.status_code == 401 def test_login_fails_for_magic_link_account(raw_client, edition, make_account): make_account(Role.LEAD, email="ref@e.fr") # sans mot de passe resp = raw_client.post( _url(edition, "login"), json={"email": "ref@e.fr", "password": "peu importe"}, ) assert resp.status_code == 401 def test_magic_link_ignored_for_password_account( raw_client, session, edition, make_account ): make_account(Role.COORDINATOR, email="admin@e.fr", password=PASSWORD) resp = raw_client.post( _url(edition, "magic-link"), json={"email": "admin@e.fr"} ) assert resp.status_code == 202 assert session.exec(select(MagicLinkToken)).all() == [] def test_change_password(raw_client, edition, make_account): make_account(Role.COORDINATOR, email="admin@e.fr", password=PASSWORD) jwt = raw_client.post( _url(edition, "login"), json={"email": "admin@e.fr", "password": PASSWORD}, ).json()["access_token"] headers = {"Authorization": f"Bearer {jwt}"} changed = raw_client.post( _url(edition, "change-password"), json={"current_password": PASSWORD, "new_password": "nouveau-mdp-2026"}, headers=headers, ) assert changed.status_code == 204 assert ( raw_client.post( _url(edition, "login"), json={"email": "admin@e.fr", "password": PASSWORD}, ).status_code == 401 ) assert ( raw_client.post( _url(edition, "login"), json={"email": "admin@e.fr", "password": "nouveau-mdp-2026"}, ).status_code == 200 ) def test_change_password_rejects_wrong_current( raw_client, edition, make_account ): make_account(Role.COORDINATOR, email="admin@e.fr", password=PASSWORD) jwt = raw_client.post( _url(edition, "login"), json={"email": "admin@e.fr", "password": PASSWORD}, ).json()["access_token"] resp = raw_client.post( _url(edition, "change-password"), json={"current_password": "faux", "new_password": "nouveau-mdp-2026"}, headers={"Authorization": f"Bearer {jwt}"}, ) assert resp.status_code == 401 # --------------------------------------------------------------------------- # # Création de compte : mot de passe selon le rôle # # --------------------------------------------------------------------------- # def test_create_coordinator_requires_password(client, edition): resp = client.post( f"/editions/{edition.id}/accounts", json={"email": "admin2@e.fr", "role": "COORDINATOR"}, ) assert resp.status_code == 422 assert resp.json()["detail"]["code"] == "account.password_required" def test_create_coordinator_with_password_can_log_in( client, raw_client, edition ): created = client.post( f"/editions/{edition.id}/accounts", json={ "email": "admin2@e.fr", "role": "COORDINATOR", "password": "un-mot-de-passe-solide", }, ) assert created.status_code == 201 assert created.json()["auth_method"] == "password" assert ( raw_client.post( f"/editions/{edition.id}/auth/login", json={"email": "admin2@e.fr", "password": "un-mot-de-passe-solide"}, ).status_code == 200 ) def test_create_lead_rejects_password(client, edition): resp = client.post( f"/editions/{edition.id}/accounts", json={ "email": "ref2@e.fr", "role": "LEAD", "password": "pas-permis", }, ) assert resp.status_code == 422 assert resp.json()["detail"]["code"] == "account.password_not_allowed"