Files
Aegis/backend/tests/test_multi_role_switch.py
T
kitos 3cd0f6fd99
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
fix(users): admin can never strip their own admin permission
Both backend (PATCH /users/{id}) and frontend (Edit User modal) now block
an admin from changing their own primary role away from admin or removing
admin from their own extra_roles, closing off a self-lockout scenario.
2026-07-22 10:52:46 +02:00

133 lines
4.4 KiB
Python

"""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_cannot_remove_own_admin_role(api, auth_headers, admin_user):
resp = api(
"patch", f"/api/v1/users/{admin_user.id}", auth_headers,
json={"role": "viewer"},
)
assert resp.status_code == 400
assert "admin" in resp.text.lower()
def test_admin_cannot_drop_admin_via_extra_roles_either(api, auth_headers, admin_user):
# Give themselves a second role first, then try to swap the primary
# role away from admin without admin anywhere in extra_roles.
resp = api(
"patch", f"/api/v1/users/{admin_user.id}", auth_headers,
json={"role": "red_lead", "extra_roles": ["viewer"]},
)
assert resp.status_code == 400
def test_admin_can_switch_primary_role_if_admin_kept_in_extra_roles(api, auth_headers, admin_user):
resp = api(
"patch", f"/api/v1/users/{admin_user.id}", auth_headers,
json={"role": "red_lead", "extra_roles": ["admin"]},
)
assert resp.status_code == 200, resp.text
def test_admin_can_edit_own_other_fields_without_touching_role(api, auth_headers, admin_user):
resp = api(
"patch", f"/api/v1/users/{admin_user.id}", auth_headers,
json={"full_name": "Renamed Admin"},
)
assert resp.status_code == 200, resp.text
assert resp.json()["role"] == "admin"
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