146 lines
4.5 KiB
Python
146 lines
4.5 KiB
Python
"""scripts/load_path.py —— pbl_blueprint 模块 RBAC 路径注册。
|
||
|
||
规则(module-development-spec):
|
||
- 禁止任何通配符(% / *),每条路径显式列出;
|
||
- 角色分层:any(无需登录)/ logined(登录即可)/ owner.superuser(管理);
|
||
- CRUD 子目录标准 5 条一组:目录 + index.ui + get_/add_/update_/delete_.dspy。
|
||
|
||
用法:cd <宿主应用根> && ./py3/bin/python <repo>/modules/pbl_blueprint/scripts/load_path.py
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
|
||
MODULE = 'pbl_blueprint'
|
||
|
||
# 契约 API(登录可用)
|
||
PATHS_LOGINED = [
|
||
'/pbl_blueprint',
|
||
'/pbl_blueprint/index.ui',
|
||
'/pbl_blueprint/api/pbl_blueprint_create.dspy',
|
||
'/pbl_blueprint/api/pbl_blueprint_read.dspy',
|
||
'/pbl_blueprint/api/pbl_blueprint_update.dspy',
|
||
'/pbl_blueprint/api/pbl_blueprint_delete.dspy',
|
||
'/pbl_blueprint/api/pbl_blueprint_list.dspy',
|
||
'/pbl_blueprint/api/pbl_blueprint_tree.dspy',
|
||
'/pbl_blueprint/api/pbl_blueprint_fork.dspy',
|
||
'/pbl_blueprint/api/pbl_blueprint_subobject_save.dspy',
|
||
'/pbl_blueprint/api/pbl_blueprint_subobject_list.dspy',
|
||
'/pbl_blueprint/api/pbl_blueprint_subobject_delete.dspy',
|
||
'/pbl_blueprint/api/pbl_blueprint_version_create.dspy',
|
||
'/pbl_blueprint/api/pbl_blueprint_version_diff.dspy',
|
||
'/pbl_blueprint/api/pbl_template_list.dspy',
|
||
'/pbl_blueprint/api/pbl_template_instantiate.dspy',
|
||
'/pbl_blueprint/api/pbl_template_save.dspy',
|
||
'/pbl_blueprint/api/pbl_template_delete.dspy',
|
||
]
|
||
|
||
# 静态资源(无需登录)
|
||
PATHS_ANY = [
|
||
'/pbl_blueprint/menu.ui',
|
||
]
|
||
|
||
# 管理级操作(删除/模板维护)
|
||
PATHS_SUPERUSER = [
|
||
'/pbl_blueprint/api/pbl_template_delete.dspy',
|
||
]
|
||
|
||
# CRUD 生成目录(每个 alias 5 条)
|
||
CRUD_ALIASES = [
|
||
'pbl_blueprint',
|
||
'pbl_blueprint_learning_goal',
|
||
'pbl_blueprint_role',
|
||
'pbl_blueprint_mission',
|
||
'pbl_blueprint_task',
|
||
'pbl_blueprint_artifact_spec',
|
||
'pbl_blueprint_evidence_spec',
|
||
'pbl_blueprint_reflection_spec',
|
||
'pbl_blueprint_version',
|
||
'pbl_template',
|
||
]
|
||
|
||
|
||
def _crud_paths():
|
||
out = []
|
||
for alias in CRUD_ALIASES:
|
||
base = '/%s/%s' % (MODULE, alias)
|
||
out.append((base, 'logined'))
|
||
out.append((base + '/index.ui', 'logined'))
|
||
out.append((base + '/get_%s.dspy' % alias, 'logined'))
|
||
out.append((base + '/add_%s.dspy' % alias, 'logined'))
|
||
out.append((base + '/update_%s.dspy' % alias, 'logined'))
|
||
out.append((base + '/delete_%s.dspy' % alias, 'logined'))
|
||
return out
|
||
|
||
|
||
def all_paths():
|
||
"""返回 [(path, role), ...] 全量显式路径清单。"""
|
||
items = [(p, 'logined') for p in PATHS_LOGINED]
|
||
items += [(p, 'any') for p in PATHS_ANY]
|
||
items += [(p, 'owner.superuser') for p in PATHS_SUPERUSER]
|
||
items += _crud_paths()
|
||
# 去重保序
|
||
seen = set()
|
||
out = []
|
||
for p, r in items:
|
||
if p in seen:
|
||
continue
|
||
seen.add(p)
|
||
out.append((p, r))
|
||
return out
|
||
|
||
|
||
def _find_app_root():
|
||
"""向上查找宿主应用根(含 load_path.py / set_role_perm.py 的目录)。"""
|
||
here = os.path.dirname(os.path.abspath(__file__))
|
||
cur = here
|
||
for _ in range(8):
|
||
for cand in (os.path.join(cur, 'set_role_perm.py'),
|
||
os.path.join(cur, 'load_path.py')):
|
||
if os.path.exists(cand):
|
||
return cur
|
||
nxt = os.path.dirname(cur)
|
||
if nxt == cur:
|
||
break
|
||
cur = nxt
|
||
for env_key in ('SAGE_ROOT', 'PBL_APP_ROOT'):
|
||
v = os.environ.get(env_key)
|
||
if v and os.path.isdir(v):
|
||
return v
|
||
return None
|
||
|
||
|
||
def main():
|
||
paths = all_paths()
|
||
root = _find_app_root()
|
||
if root is None:
|
||
print('[pbl_blueprint] 未找到宿主应用根(set_role_perm.py),'
|
||
'仅打印待注册路径 %d 条:' % len(paths))
|
||
for p, r in paths:
|
||
print('%s %s' % (p, r))
|
||
return 0
|
||
sys.path.insert(0, root)
|
||
try:
|
||
import set_role_perm
|
||
except Exception as e:
|
||
print('[pbl_blueprint] 导入 set_role_perm 失败: %s' % e)
|
||
for p, r in paths:
|
||
print('%s %s' % (p, r))
|
||
return 1
|
||
fn = getattr(set_role_perm, 'set_role_perm', None) or \
|
||
getattr(set_role_perm, 'main', None)
|
||
ok = 0
|
||
for p, r in paths:
|
||
try:
|
||
if fn is not None:
|
||
fn(p, r)
|
||
ok += 1
|
||
except Exception as e:
|
||
print('[pbl_blueprint] 注册失败 %s %s: %s' % (p, r, e))
|
||
print('[pbl_blueprint] RBAC 路径注册完成 %d/%d' % (ok, len(paths)))
|
||
return 0
|
||
|
||
|
||
if __name__ == '__main__':
|
||
sys.exit(main())
|