2026-11-02 22:20:55 -05:00
|
|
|
"""权限覆盖守卫:新接口未登记时必须明确失败。"""
|
|
|
|
|
from fastapi.routing import APIRoute
|
|
|
|
|
|
|
|
|
|
from app.services.authorization_policy import permission_for
|
|
|
|
|
from app.services.permission_catalog import CATALOG
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_全部受保护接口都有权限映射():
|
|
|
|
|
from app.main import app
|
|
|
|
|
|
|
|
|
|
missing=[]
|
|
|
|
|
checked = 0
|
|
|
|
|
def routes(items):
|
|
|
|
|
for item in items:
|
|
|
|
|
if isinstance(item, APIRoute):
|
|
|
|
|
yield item
|
|
|
|
|
elif hasattr(item, 'original_router'):
|
|
|
|
|
yield from routes(item.original_router.routes)
|
|
|
|
|
for route in routes(app.routes):
|
|
|
|
|
if not route.endpoint.__module__.startswith('app.api.v1.'):
|
|
|
|
|
continue
|
|
|
|
|
checked += 1
|
|
|
|
|
module=route.endpoint.__module__.removeprefix('app.api.v1.')
|
|
|
|
|
for method in route.methods:
|
|
|
|
|
code=permission_for(module,route.endpoint.__name__,method,
|
|
|
|
|
params={'code':'personal-detail'},body={'kind':'MASTER_PREVIEW'})
|
|
|
|
|
if code is None or (code and code not in CATALOG):
|
|
|
|
|
missing.append((method,route.path,code))
|
|
|
|
|
assert checked >= 100, '路由枚举未覆盖全部业务接口'
|
|
|
|
|
assert not missing, missing
|
|
|
|
|
|
|
|
|
|
|
2026-11-05 06:31:01 -05:00
|
|
|
def test_业务接入预览只需要预览权限():
|
|
|
|
|
assert permission_for(
|
|
|
|
|
'system.tplus_workbench',
|
|
|
|
|
'business_sync_preview',
|
|
|
|
|
'POST',
|
|
|
|
|
body={},
|
|
|
|
|
) == 'tplus:preview'
|
|
|
|
|
|
|
|
|
|
|
2026-11-02 22:20:55 -05:00
|
|
|
def test_未知接口没有默认放行():
|
|
|
|
|
assert permission_for('future_module','new_action','GET') is None
|