"""A user can be granted more than one role but only ever acts under a single active one at a time — switching swaps which role is active instead of ever mixing permissions from more than one. """ def test_admin_can_grant_extra_roles(api, auth_headers): created = api( "post", "/api/v1/users", auth_headers, json={"full_name": "Multi Role User", "email": "multirole@test.com", "role": "red_tech"}, ) assert created.status_code == 201, created.text user_id = created.json()["id"] resp = api( "patch", f"/api/v1/users/{user_id}", auth_headers, json={"extra_roles": ["blue_tech", "red_lead"]}, ) assert resp.status_code == 200, resp.text assert resp.json()["role"] == "red_tech" assert set(resp.json()["extra_roles"]) == {"blue_tech", "red_lead"} def test_admin_cannot_grant_invalid_extra_role(api, auth_headers): created = api( "post", "/api/v1/users", auth_headers, json={"full_name": "Bad Extra Role", "email": "badextrarole@test.com", "role": "viewer"}, ) user_id = created.json()["id"] resp = api( "patch", f"/api/v1/users/{user_id}", auth_headers, json={"extra_roles": ["superuser"]}, ) assert resp.status_code == 400 def test_user_can_switch_to_a_granted_extra_role(api, db, auth_headers): from app.auth import hash_password from app.models.user import User user = User( username="switcher@test.com", email="switcher@test.com", full_name="Switcher", hashed_password=hash_password("SwitcherPass123!@#"), role="red_tech", extra_roles=["blue_tech"], must_change_password=False, ) db.add(user) db.commit() login = api( "post", "/api/v1/auth/login", {}, data={"username": "switcher@test.com", "password": "SwitcherPass123!@#"}, ) assert login.status_code == 200, login.text token = login.json()["access_token"] headers = {"Authorization": f"Bearer {token}"} resp = api("post", "/api/v1/users/me/switch-role", headers, json={"role": "blue_tech"}) assert resp.status_code == 200, resp.text body = resp.json() assert body["role"] == "blue_tech" assert body["extra_roles"] == ["red_tech"] me = api("get", "/api/v1/auth/me", headers) assert me.json()["role"] == "blue_tech" def test_user_cannot_switch_to_an_ungranted_role(api, db, auth_headers): from app.auth import hash_password from app.models.user import User user = User( username="switcher2@test.com", email="switcher2@test.com", full_name="Switcher Two", hashed_password=hash_password("SwitcherPass123!@#"), role="red_tech", extra_roles=["blue_tech"], must_change_password=False, ) db.add(user) db.commit() login = api( "post", "/api/v1/auth/login", {}, data={"username": "switcher2@test.com", "password": "SwitcherPass123!@#"}, ) token = login.json()["access_token"] headers = {"Authorization": f"Bearer {token}"} resp = api("post", "/api/v1/users/me/switch-role", headers, json={"role": "admin"}) assert resp.status_code == 400