feat(admin): enforce monitoring page permissions
This commit is contained in:
@@ -44,17 +44,78 @@ def operator_token() -> str:
|
||||
return _token("r_operator", "operator")
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def tech_token() -> str:
|
||||
return _token("r_tech", "tech")
|
||||
|
||||
|
||||
def _auth(t: str) -> dict:
|
||||
return {"Authorization": f"Bearer {t}"}
|
||||
|
||||
|
||||
def test_super_pages_all_operator_limited(admin_client, super_token, operator_token) -> None:
|
||||
su = admin_client.get("/admin/api/auth/me", headers=_auth(super_token)).json()
|
||||
assert "admins" in su["pages"] and "dashboard" in su["pages"] # 超管全页
|
||||
assert "admins" in su["pages"] and "analytics-health" in su["pages"] # 超管全页
|
||||
op = admin_client.get("/admin/api/auth/me", headers=_auth(operator_token)).json()
|
||||
assert "dashboard" in op["pages"] and "admins" not in op["pages"] # 运营看不到管理员页
|
||||
|
||||
|
||||
def test_monitoring_audit_catalog_and_api_permissions(
|
||||
admin_client, super_token, operator_token, tech_token
|
||||
) -> None:
|
||||
catalog = admin_client.get(
|
||||
"/admin/api/roles/catalog", headers=_auth(super_token)
|
||||
).json()
|
||||
monitoring = next(group for group in catalog if group["group"] == "监控审计")
|
||||
assert [page["key"] for page in monitoring["pages"]] == [
|
||||
"device-liveness", "analytics-health", "event-logs", "audit-logs",
|
||||
]
|
||||
|
||||
# 运营默认只能查设备存活,不能绕过导航直调技术/审计接口。
|
||||
assert admin_client.get(
|
||||
"/admin/api/device-liveness/stats", headers=_auth(operator_token)
|
||||
).status_code == 200
|
||||
for path in (
|
||||
"/admin/api/analytics-health/overview?date_from=2026-07-01T00:00:00Z&date_to=2026-07-02T00:00:00Z",
|
||||
"/admin/api/event-logs",
|
||||
"/admin/api/audit-logs",
|
||||
):
|
||||
assert admin_client.get(path, headers=_auth(operator_token)).status_code == 403
|
||||
|
||||
# 技术角色默认拥有监控审计组全部四项权限。
|
||||
for path in (
|
||||
"/admin/api/device-liveness/stats",
|
||||
"/admin/api/analytics-health/overview?date_from=2026-07-01T00:00:00Z&date_to=2026-07-02T00:00:00Z",
|
||||
"/admin/api/event-logs",
|
||||
"/admin/api/audit-logs",
|
||||
):
|
||||
assert admin_client.get(path, headers=_auth(tech_token)).status_code == 200
|
||||
|
||||
|
||||
def test_custom_admin_api_permission_uses_pages_override(admin_client) -> None:
|
||||
db = SessionLocal()
|
||||
try:
|
||||
admin = admin_repo.get_by_username(db, "r_monitoring_custom")
|
||||
if admin is None:
|
||||
admin = admin_repo.create_admin(
|
||||
db, username="r_monitoring_custom", password="pass1234", role="custom"
|
||||
)
|
||||
admin.password_hash = hash_password("pass1234")
|
||||
admin.role = "custom"
|
||||
admin.pages_override = ["event-logs"]
|
||||
admin.status = "active"
|
||||
db.commit()
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
token = admin_client.post(
|
||||
"/admin/api/auth/login",
|
||||
json={"username": "r_monitoring_custom", "password": "pass1234"},
|
||||
).json()["access_token"]
|
||||
assert admin_client.get("/admin/api/event-logs", headers=_auth(token)).status_code == 200
|
||||
assert admin_client.get("/admin/api/audit-logs", headers=_auth(token)).status_code == 403
|
||||
|
||||
|
||||
def test_roles_endpoints_super_only(admin_client, super_token, operator_token) -> None:
|
||||
assert admin_client.get("/admin/api/roles", headers=_auth(super_token)).status_code == 200
|
||||
assert admin_client.get("/admin/api/roles", headers=_auth(operator_token)).status_code == 403
|
||||
@@ -123,7 +184,7 @@ def test_builtin_roles_labels_and_pages(admin_client, super_token) -> None:
|
||||
# 页集对齐 Prototypes/dashboard/permissions.md 的 ROLES
|
||||
assert set(roles["finance"]["pages"]) == {"dashboard", "ad-revenue-report", "cps", "withdraws"}
|
||||
assert set(roles["tech"]["pages"]) == {
|
||||
"dashboard", "device-liveness", "config", "ad-revenue", "huawei-review",
|
||||
"dashboard", "device-liveness", "analytics-health", "config", "ad-revenue", "huawei-review",
|
||||
"event-logs", "audit-logs",
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user