74 lines
3.0 KiB
Python
74 lines
3.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""T08/F11 权限底座自测(纯逻辑叠加规则 + 权限矩阵)"""
|
|
import json, sys
|
|
|
|
def _json_loads(raw, default):
|
|
if not raw: return default
|
|
try: return json.loads(raw)
|
|
except (TypeError, ValueError): return default
|
|
|
|
def expand_org_tree(parent_map, org_ids):
|
|
if not org_ids: return []
|
|
result = set(org_ids); frontier = list(org_ids); seen = set(org_ids)
|
|
while frontier:
|
|
children = []
|
|
for oid in frontier:
|
|
for child in parent_map.get(oid, []):
|
|
if child not in seen:
|
|
seen.add(child); result.add(child); children.append(child)
|
|
frontier = children
|
|
return sorted(result)
|
|
|
|
def test_org_expand():
|
|
out = expand_org_tree({"A":["B"],"B":["C"]}, ["A"])
|
|
assert out == ["A","B","C"], out
|
|
return "PASS: 组织维度子树展开"
|
|
|
|
def test_scope_overlay():
|
|
scopes = [{"scope_type":"org","org_ids":["A","B"],"field_ids":[]},{"scope_type":"field","org_ids":[],"field_ids":["f1","f2"]}]
|
|
org_union, field_union, field_restricted = set(), set(), False
|
|
for s in scopes:
|
|
if s["scope_type"] in ("org","all") and s["org_ids"]: org_union.update(s["org_ids"])
|
|
if s["scope_type"] in ("field","all"): field_restricted = True; field_union.update(s["field_ids"])
|
|
assert org_union == {"A","B"}
|
|
assert field_union == {"f1","f2"}
|
|
assert field_restricted is True
|
|
return "PASS: 双维度叠加并集"
|
|
|
|
def test_field_all_when_unrestricted():
|
|
scopes = [{"scope_type":"org","org_ids":["A"],"field_ids":[]}]
|
|
field_restricted = False
|
|
field_union = set()
|
|
for s in scopes:
|
|
if s["scope_type"] in ("field","all"): field_restricted = True; field_union.update(s["field_ids"])
|
|
assert field_restricted is False
|
|
return "PASS: 未配置字段维度 -> 字段不受限"
|
|
|
|
def test_admin_full():
|
|
role_codes = ["manager","sys_admin"]
|
|
assert ("sys_admin" in role_codes or "admin" in role_codes) is True
|
|
return "PASS: sys_admin/admin 全量数据范围"
|
|
|
|
def main():
|
|
tests = [test_org_expand, test_scope_overlay, test_field_all_when_unrestricted, test_admin_full]
|
|
passed = 0
|
|
for t in tests:
|
|
try:
|
|
print(t()); passed += 1
|
|
except AssertionError as e:
|
|
print("FAIL:", t.__name__, e)
|
|
print("\n权限矩阵自测结果:{}/{} 通过".format(passed, len(tests)))
|
|
print("""
|
|
权限矩阵(自测基线):
|
|
| 角色 | 路径级功能权限(rbac) | 组织数据范围 | 花名册字段范围 |
|
|
| 员工自助 | 个人档案/自助申请 | 仅本人 | 本人可见字段白名单 |
|
|
| 经理 | 本部门入转调离管理+审批 | 本部门+子树 | 经理视角字段白名单 |
|
|
| HR管理员 | 全公司人事业务 | 按 sys_data_scope 并集 | 按 sys_data_scope 并集 |
|
|
| 系统管理员 | 系统配置+权限+审计 | org_all=True | field_all=True |
|
|
| admin | 全量(等价 sys_admin) | org_all=True | field_all=True |
|
|
""")
|
|
return 0 if passed == len(tests) else 1
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|