清理全局角色残留并修复项目权限判断

This commit is contained in:
Cheng Zhou
2026-05-29 10:20:42 +08:00
parent 63457aab11
commit 44d69c2d7b
63 changed files with 739 additions and 443 deletions
+34 -30
View File
@@ -18,6 +18,10 @@ class FakeIpInfo:
self.location = f"中国 / {province} / {city} / {isp}"
class AdminUserStub:
is_admin = True
async def _seed_permission_log(db_session, study_id: uuid.UUID, user_id: uuid.UUID, *, allowed: bool, elapsed_ms: float) -> None:
study_exists = (
await db_session.execute(text("SELECT id FROM studies WHERE id = :id"), {"id": str(study_id)})
@@ -48,8 +52,8 @@ async def _seed_permission_log(db_session, study_id: uuid.UUID, user_id: uuid.UU
await db_session.execute(
text(
"""
INSERT INTO users (id, email, password_hash, full_name, role, clinical_department, status)
VALUES (:id, :email, :password_hash, :full_name, :role, :clinical_department, :status)
INSERT INTO users (id, email, password_hash, full_name, clinical_department, is_admin, status)
VALUES (:id, :email, :password_hash, :full_name, :clinical_department, :is_admin, :status)
"""
),
{
@@ -57,8 +61,8 @@ async def _seed_permission_log(db_session, study_id: uuid.UUID, user_id: uuid.UU
"email": f"{user_id.hex}@example.com",
"password_hash": "hash",
"full_name": "Permission Monitoring User",
"role": "PM",
"clinical_department": "临床运营",
"is_admin": False,
"status": "ACTIVE",
},
)
@@ -97,7 +101,7 @@ async def test_get_permission_metrics(db_session):
await _seed_permission_log(db_session, study_id, user_id, allowed=True, elapsed_ms=5)
await _seed_permission_log(db_session, study_id, user_id, allowed=False, elapsed_ms=3)
data = await permission_monitoring.get_permission_metrics(db=db_session, _=object(), hours=24)
data = await permission_monitoring.get_permission_metrics(db=db_session, _=AdminUserStub(), hours=24)
assert "check_metrics" in data
assert "cache_metrics" in data
assert data["check_metrics"]["total_checks"] == 2
@@ -115,7 +119,7 @@ async def test_get_cache_statistics(db_session):
monitor.record_cache_hit()
monitor.record_cache_miss()
data = await permission_monitoring.get_cache_statistics(_=object(), db=db_session)
data = await permission_monitoring.get_cache_statistics(_=AdminUserStub(), db=db_session)
assert "cache_metrics" in data
assert data["cache_metrics"]["total_accesses"] == 3
assert data["cache_metrics"]["cache_hits"] == 2
@@ -129,7 +133,7 @@ async def test_get_alerts(db_session):
monitor.record_slow_check_alert(100)
data = await permission_monitoring.get_alerts(_=object(), db=db_session)
data = await permission_monitoring.get_alerts(_=AdminUserStub(), db=db_session)
assert "alerts" in data
assert data["total"] > 0
@@ -143,7 +147,7 @@ async def test_get_alerts_with_level_filter(db_session):
monitor.record_slow_check_alert(100)
monitor.record_error_alert(ValueError("test error"))
data = await permission_monitoring.get_alerts(level="warning", _=object(), db=db_session)
data = await permission_monitoring.get_alerts(level="warning", _=AdminUserStub(), db=db_session)
assert "alerts" in data
assert all(alert["level"] == "warning" for alert in data["alerts"])
@@ -157,7 +161,7 @@ async def test_get_alerts_with_limit(db_session):
for _ in range(20):
monitor.record_slow_check_alert(100)
data = await permission_monitoring.get_alerts(limit=5, _=object(), db=db_session)
data = await permission_monitoring.get_alerts(limit=5, _=AdminUserStub(), db=db_session)
assert len(data["alerts"]) <= 5
@@ -170,7 +174,7 @@ async def test_reset_metrics(db_session):
monitor.record_cache_hit()
assert monitor.metrics.cache_metrics.total_accesses == 1
result = await permission_monitoring.reset_metrics(_=object(), db=db_session)
result = await permission_monitoring.reset_metrics(_=AdminUserStub(), db=db_session)
assert result["message"] == "指标已重置"
assert monitor.metrics.cache_metrics.total_accesses == 0
@@ -185,7 +189,7 @@ async def test_clear_alerts(db_session):
monitor.record_slow_check_alert(100)
assert len(monitor.get_alerts()) > 0
result = await permission_monitoring.clear_alerts(_=object(), db=db_session)
result = await permission_monitoring.clear_alerts(_=AdminUserStub(), db=db_session)
assert result["message"] == "告警已清除"
assert len(monitor.get_alerts()) == 0
@@ -200,7 +204,7 @@ async def test_permission_system_health_healthy(db_session):
for _ in range(100):
monitor.record_cache_hit()
data = await permission_monitoring.permission_system_health(db=db_session, _=object())
data = await permission_monitoring.permission_system_health(db=db_session, _=AdminUserStub())
assert data["status"] == "healthy"
assert data["health_score"] >= 80
@@ -218,7 +222,7 @@ async def test_permission_system_health_degraded(db_session):
for _ in range(100):
monitor.record_cache_miss()
data = await permission_monitoring.permission_system_health(db=db_session, _=object())
data = await permission_monitoring.permission_system_health(db=db_session, _=AdminUserStub())
assert "status" in data
assert "health_score" in data
assert "issues" in data
@@ -233,7 +237,7 @@ async def test_permission_system_health_includes_metrics(db_session):
monitor = PermissionMonitor()
set_permission_monitor(monitor)
data = await permission_monitoring.permission_system_health(db=db_session, _=object())
data = await permission_monitoring.permission_system_health(db=db_session, _=AdminUserStub())
assert "last_hour" in data
assert "cache_stats" in data
assert "total_checks" in data["last_hour"]
@@ -271,8 +275,8 @@ async def test_ip_locations_counts_unique_users_per_location(db_session, monkeyp
await db_session.execute(
text(
"""
INSERT INTO users (id, email, password_hash, full_name, role, clinical_department, status)
VALUES (:id, :email, :password_hash, :full_name, :role, :clinical_department, :status)
INSERT INTO users (id, email, password_hash, full_name, clinical_department, is_admin, status)
VALUES (:id, :email, :password_hash, :full_name, :clinical_department, :is_admin, :status)
"""
),
{
@@ -280,8 +284,8 @@ async def test_ip_locations_counts_unique_users_per_location(db_session, monkeyp
"email": email,
"password_hash": "hash",
"full_name": email,
"role": "PM",
"clinical_department": "临床运营",
"is_admin": False,
"status": "ACTIVE",
},
)
@@ -323,7 +327,7 @@ async def test_ip_locations_counts_unique_users_per_location(db_session, monkeyp
lambda ip: FakeIpInfo("广东省", "深圳市"),
)
result = await permission_monitoring.get_ip_locations(db=db_session, _=object(), days=7, limit=10)
result = await permission_monitoring.get_ip_locations(db=db_session, _=AdminUserStub(), days=7, limit=10)
assert result["items"][0]["province"] == "广东省"
assert result["items"][0]["total_count"] == 3
@@ -363,8 +367,8 @@ async def test_ip_locations_merges_same_region_with_different_isp(db_session, mo
await db_session.execute(
text(
"""
INSERT INTO users (id, email, password_hash, full_name, role, clinical_department, status)
VALUES (:id, :email, :password_hash, :full_name, :role, :clinical_department, :status)
INSERT INTO users (id, email, password_hash, full_name, clinical_department, is_admin, status)
VALUES (:id, :email, :password_hash, :full_name, :clinical_department, :is_admin, :status)
"""
),
{
@@ -372,8 +376,8 @@ async def test_ip_locations_merges_same_region_with_different_isp(db_session, mo
"email": "region-merge@example.com",
"password_hash": "hash",
"full_name": "属地合并用户",
"role": "PM",
"clinical_department": "临床运营",
"is_admin": False,
"status": "ACTIVE",
},
)
@@ -410,7 +414,7 @@ async def test_ip_locations_merges_same_region_with_different_isp(db_session, mo
lambda ip: ip_info_by_address[ip],
)
result = await permission_monitoring.get_ip_locations(db=db_session, _=object(), days=7, limit=10)
result = await permission_monitoring.get_ip_locations(db=db_session, _=AdminUserStub(), days=7, limit=10)
assert len(result["items"]) == 1
assert result["items"][0]["province"] == "重庆"
@@ -448,8 +452,8 @@ async def test_ip_locations_keeps_private_network_location_label(db_session, mon
await db_session.execute(
text(
"""
INSERT INTO users (id, email, password_hash, full_name, role, clinical_department, status)
VALUES (:id, :email, :password_hash, :full_name, :role, :clinical_department, :status)
INSERT INTO users (id, email, password_hash, full_name, clinical_department, is_admin, status)
VALUES (:id, :email, :password_hash, :full_name, :clinical_department, :is_admin, :status)
"""
),
{
@@ -457,8 +461,8 @@ async def test_ip_locations_keeps_private_network_location_label(db_session, mon
"email": "private-network@example.com",
"password_hash": "hash",
"full_name": "局域网用户",
"role": "PM",
"clinical_department": "临床运营",
"is_admin": False,
"status": "ACTIVE",
},
)
@@ -484,7 +488,7 @@ async def test_ip_locations_keeps_private_network_location_label(db_session, mon
)
await db_session.commit()
result = await permission_monitoring.get_ip_locations(db=db_session, _=object(), days=7, limit=10)
result = await permission_monitoring.get_ip_locations(db=db_session, _=AdminUserStub(), days=7, limit=10)
assert result["items"][0]["location"] == "局域网"
assert result["items"][0]["province"] == ""
@@ -525,8 +529,8 @@ async def test_access_logs_include_user_behavior_summary(db_session):
await db_session.execute(
text(
"""
INSERT INTO users (id, email, password_hash, full_name, role, clinical_department, status)
VALUES (:id, :email, :password_hash, :full_name, :role, :clinical_department, :status)
INSERT INTO users (id, email, password_hash, full_name, clinical_department, is_admin, status)
VALUES (:id, :email, :password_hash, :full_name, :clinical_department, :is_admin, :status)
"""
),
{
@@ -534,8 +538,8 @@ async def test_access_logs_include_user_behavior_summary(db_session):
"email": email,
"password_hash": "hash",
"full_name": name,
"role": role,
"clinical_department": "临床运营",
"is_admin": False,
"status": "ACTIVE",
},
)
@@ -573,7 +577,7 @@ async def test_access_logs_include_user_behavior_summary(db_session):
result = await permission_monitoring.get_access_logs(
db=db_session,
_=object(),
_=AdminUserStub(),
study_id=None,
user_id=None,
endpoint_key=None,
@@ -621,7 +625,7 @@ async def test_security_access_logs_include_anonymous_ip_attempts(db_session):
result = await permission_monitoring.get_security_access_logs(
db=db_session,
_=object(),
_=AdminUserStub(),
status_min=400,
auth_status=None,
page=1,