83 lines
3.8 KiB
Python
83 lines
3.8 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""pbl_agent_runtime RBAC 路径注册清单。
|
||
|
||
铁律:PATHS 必须与 wwwroot/ 下**实际存在的文件一一对应**(QC 退回 #4)。
|
||
本文件由 scripts/check_contract_sync.py 机械核验:多一条(指向不存在文件)或少一条
|
||
(文件未注册)都会失败。
|
||
|
||
角色约定
|
||
--------
|
||
* ``any`` :登录前可访问(本模块无此类文件)
|
||
* ``logined`` :普通登录用户(只读查询类)
|
||
* ``admin`` :租户管理员(写类 / 审批裁决 / 注册表变更)
|
||
|
||
角色名必须是**平台可解析口径**,不得自造
|
||
--------------------------------------
|
||
写入工具 ``set_role_perm.py`` 的角色解析规则(pipeline-app/set_role_perm.py):
|
||
|
||
* ``any`` / ``anonymous`` / ``logined`` 是特殊角色,直接用字面 id;
|
||
* 其余角色按 ``[orgtypeid.]name`` 查 role 表,缺省 ``orgtypeid='*'``;查不到即
|
||
``exit(1)``,宿主 ``load_path.py register()`` 记为 PENDING,端点上线即 403。
|
||
|
||
本模块原用自造词 ``user``(语义即「普通登录用户」),但 role 表里 ``user`` 只有
|
||
``orgtypeid='customer'`` 一行、**没有 ``orgtypeid='*'``**,故按缺省口径查零命中 →
|
||
8 条路径恒 PENDING(2026-09-29 build_run9 实测:total=308 ok=300 pending=8)。
|
||
平台表达「普通登录用户」的既有词就是 ``logined``(role 表有 id='logined' 与
|
||
orgtypeid='*' 两行),故归一到 ``logined``,语义不变且可解析。
|
||
|
||
注意:``admin`` 之所以能注册成功,是因为 role 表恰好存在 ``orgtypeid='*'`` 的
|
||
admin 行(id=zxje5CL8jCroLL35piNXG)。角色是运行时可增删的(role/orgtypes 有
|
||
CRUD),所以**任何模块都不应依赖某个具体角色行恰好存在**——只读的普通登录态
|
||
统一用特殊角色 ``logined``,写类/管理类若要用具名角色,必须带 orgtype 前缀
|
||
(如 ``owner.superuser``)并确认该行由种子保证存在。
|
||
"""
|
||
|
||
# (路径, 角色) —— 路径相对模块 wwwroot,运行时前缀 /pbl_agent_runtime/
|
||
PATHS = [
|
||
# 模块入口页
|
||
("/pbl_agent_runtime/index.ui", "logined"),
|
||
# 10 个契约端点(与 pbl_agent_runtime.m4a_contract.CONTRACT_FUNCTIONS 同源)
|
||
("/pbl_agent_runtime/api/pbl_agent_designer_run.dspy", "admin"),
|
||
("/pbl_agent_runtime/api/pbl_agent_critic_run.dspy", "logined"),
|
||
("/pbl_agent_runtime/api/pbl_agent_trace_write.dspy", "logined"),
|
||
("/pbl_agent_runtime/api/pbl_agent_trace_list.dspy", "logined"),
|
||
("/pbl_agent_runtime/api/pbl_tool_registry_list.dspy", "logined"),
|
||
("/pbl_agent_runtime/api/pbl_tool_registry_save.dspy", "admin"),
|
||
("/pbl_agent_runtime/api/pbl_tool_adjudicate.dspy", "logined"),
|
||
("/pbl_agent_runtime/api/pbl_approval_create.dspy", "logined"),
|
||
("/pbl_agent_runtime/api/pbl_approval_decide.dspy", "admin"),
|
||
("/pbl_agent_runtime/api/pbl_approval_list.dspy", "logined"),
|
||
]
|
||
|
||
MODULE_NAME = "pbl_agent_runtime"
|
||
|
||
|
||
def paths():
|
||
"""返回 [(path, role), ...],供宿主应用 RBAC 批量注册。"""
|
||
return list(PATHS)
|
||
|
||
|
||
def register(env=None):
|
||
"""把 PATHS 注册到 ServerEnv 的 RBAC 表(平台可用时)。"""
|
||
target = env
|
||
if target is None:
|
||
try:
|
||
from ahserver.serverenv import ServerEnv # noqa: WPS433
|
||
|
||
target = ServerEnv()
|
||
except Exception: # noqa: BLE001
|
||
return {"registered": 0, "offline": True, "paths": list(PATHS)}
|
||
count = 0
|
||
for path, role in PATHS:
|
||
setter = getattr(target, "add_path", None) or getattr(target, "register_path", None)
|
||
if callable(setter):
|
||
setter(path, role)
|
||
count += 1
|
||
return {"registered": count, "offline": count == 0, "paths": list(PATHS)}
|
||
|
||
|
||
if __name__ == "__main__":
|
||
for item_path, item_role in PATHS:
|
||
print("%-64s %s" % (item_path, item_role))
|
||
print("total: %d paths" % len(PATHS))
|