65 lines
2.5 KiB
Python
65 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""RBAC 单条权限登记 CLI(M9-收口C,QC 退回意见 #10 方案 a)。
|
||
|
||
接口(与 scripts/load_path.py register() 的 subprocess 调用契约严格一致):
|
||
|
||
python3 scripts/rbac_set_perm.py <role> <path>
|
||
例:python3 scripts/rbac_set_perm.py logined /pbl_scense_ext/api/pbl_overlay_bootstrap.dspy
|
||
|
||
退出码:rc=0 表示该 (role, path) 已幂等落库 permission + rolepermission;
|
||
rc!=0 表示未落库(参数非法 / 路径不在种子清单 / DB 不可达)。
|
||
**不猜、不静默成功**——DB 不可达时返回 2,由 load_path.py 计入 pending,
|
||
使 `total=26 ok=26 pending=0` 只在真实落库时才成立。
|
||
|
||
实现下沉到 scripts/m9c_rbac_seed.py 的 --upsert-one(幂等 upsert,id 由
|
||
path/role 的 md5 派生,重复执行零差异),本文件只做 CLI 适配与参数校验,
|
||
不重复实现导入逻辑。
|
||
|
||
被 apps/pbls/build.sh 第 9 步(import_rp)经 load_path.register() 调用;
|
||
RBAC_SET_PERM 环境变量可覆盖本工具路径(保持向后兼容)。
|
||
"""
|
||
import os
|
||
import re
|
||
import subprocess
|
||
import sys
|
||
|
||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||
SEED_TOOL = os.path.join(HERE, 'm9c_rbac_seed.py')
|
||
MODULE = 'pbl_scense_ext'
|
||
PSEUDO_ROLES = ('logined', 'any')
|
||
WILDCARD_RE = re.compile(r'[%*?]')
|
||
|
||
|
||
def main(argv):
|
||
if len(argv) != 3:
|
||
print('usage: rbac_set_perm.py <role> <path> (role in %s)' % (PSEUDO_ROLES,))
|
||
return 64
|
||
role, path = argv[1], argv[2]
|
||
# 参数硬校验:与 module-development-spec 硬门禁 6.6 一致,通配符零容忍
|
||
if role not in PSEUDO_ROLES:
|
||
print('FAIL 角色必须是伪角色 %s(rbac userperm.py 语义),收到 %s' % (PSEUDO_ROLES, role))
|
||
return 64
|
||
if WILDCARD_RE.search(path):
|
||
print('FAIL 禁止通配符(硬政策): %s' % path)
|
||
return 64
|
||
if not path.startswith('/%s' % MODULE):
|
||
print('FAIL 路径必须落在模块自动路由 /%s 下: %s' % (MODULE, path))
|
||
return 64
|
||
if not os.path.isfile(SEED_TOOL):
|
||
print('FAIL 缺少导入器 %s' % SEED_TOOL)
|
||
return 66
|
||
cmd = [sys.executable, SEED_TOOL, '--upsert-one', role, path]
|
||
if os.environ.get('PBL_SCENSE_EXT_DBNAME'):
|
||
cmd += ['--dbname', os.environ['PBL_SCENSE_EXT_DBNAME']]
|
||
rc = subprocess.call(cmd)
|
||
if rc == 0:
|
||
print('OK %-8s %s' % (role, path))
|
||
else:
|
||
print('PENDING(rc=%d) %-8s %s' % (rc, role, path))
|
||
return rc
|
||
|
||
|
||
if __name__ == '__main__':
|
||
sys.exit(main(sys.argv))
|