- init_any_permissions.py: import PATHS_ANY from rbac/scripts/load_path.py to register /rbac/user/login.ui etc as anonymous-accessible - init_superuser_permissions.py: add all rbac logined paths for superuser - Fixes frontend loop caused by login.ui lacking any permission
115 lines
3.8 KiB
Python
115 lines
3.8 KiB
Python
"""
|
||
Portal RBAC权限初始化 — any (匿名) 角色
|
||
扫描 wwwroot 和 bricks 下的公开页面,授予 any 角色权限
|
||
|
||
规则:
|
||
- wwwroot/* → /<file> (公开页面和API)
|
||
- bricks/* → /bricks/<file>
|
||
- /cms/* 由 cms/scripts/load_path.py 管理(需要登录)
|
||
|
||
用法: cd ~/repos/portal && py3/bin/python init_any_permissions.py
|
||
"""
|
||
import os, sys, subprocess
|
||
|
||
def find_app_root():
|
||
return os.path.dirname(os.path.abspath(__file__))
|
||
|
||
app_root = find_app_root()
|
||
sage_root = None
|
||
for c in [os.path.expanduser("~/repos/sage"), os.path.expanduser("~/sage")]:
|
||
if os.path.isdir(os.path.join(c, "py3", "bin")):
|
||
sage_root = c
|
||
break
|
||
if not sage_root:
|
||
print("ERROR: 找不到Sage,无法初始化权限")
|
||
sys.exit(1)
|
||
|
||
py = os.path.join(sage_root, "py3", "bin", "python")
|
||
sp = os.path.join(sage_root, "set_role_perm.py")
|
||
if not os.path.exists(sp):
|
||
print("ERROR: 找不到set_role_perm.py")
|
||
sys.exit(1)
|
||
|
||
SKIP_DIRS = {".git", "__pycache__", "node_modules", ".svn"}
|
||
SKIP_EXTS = {".pyc", ".pyo", ".swp", ".swo", ".bak", ".orig", ".log", ".pid", ".lock"}
|
||
|
||
def scan_dir(base_dir, url_prefix):
|
||
paths = []
|
||
if not os.path.isdir(base_dir):
|
||
return paths
|
||
for root, dirs, files in os.walk(base_dir):
|
||
dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
|
||
for f in sorted(files):
|
||
_, ext = os.path.splitext(f)
|
||
if ext.lower() in SKIP_EXTS or f.startswith("."):
|
||
continue
|
||
full_path = os.path.join(root, f)
|
||
if os.path.islink(full_path):
|
||
link_target = os.path.realpath(full_path)
|
||
if not link_target.startswith(app_root):
|
||
continue
|
||
rel_path = os.path.relpath(full_path, base_dir)
|
||
url = url_prefix + "/" + rel_path.replace(os.sep, "/")
|
||
paths.append(url)
|
||
return paths
|
||
|
||
def set_any_perms(paths):
|
||
count = 0
|
||
env = os.environ.copy()
|
||
env['SAGE_RBAC_DB'] = 'ocai_cms'
|
||
for p in paths:
|
||
result = subprocess.run(
|
||
[py, sp, "any", p],
|
||
cwd=sage_root, capture_output=True, text=True, env=env
|
||
)
|
||
status = "✓" if result.returncode == 0 else "✗"
|
||
print(f" {status} any {p}")
|
||
count += 1
|
||
return count
|
||
|
||
print("=== Portal RBAC权限初始化 — any (匿名访问) ===")
|
||
print(f"Sage: {sage_root}")
|
||
print()
|
||
|
||
# 1. wwwroot/ 公开页面和API
|
||
wwwroot_dir = os.path.join(app_root, "wwwroot")
|
||
root_paths = scan_dir(wwwroot_dir, "")
|
||
root_paths.append("/") # 根路径
|
||
print(f"--- wwwroot/ → / ({len(root_paths)} 个路径) ---")
|
||
n1 = set_any_perms(root_paths)
|
||
|
||
# 2. bricks/
|
||
bricks_dir = os.path.join(app_root, "bricks")
|
||
bricks_paths = scan_dir(bricks_dir, "/bricks")
|
||
if bricks_paths:
|
||
print(f"\n--- bricks → /bricks ({len(bricks_paths)} 个文件) ---")
|
||
n2 = set_any_perms(bricks_paths)
|
||
else:
|
||
n2 = 0
|
||
print(f"\n--- bricks → /bricks (未构建,跳过) ---")
|
||
|
||
# 3. rbac模块公开路径 (登录页、注册、验证码等)
|
||
# 从rbac的load_path.py导入PATHS_ANY列表
|
||
rbac_load_path = os.path.join(os.path.dirname(app_root), "rbac", "scripts", "load_path.py")
|
||
rbac_any_paths = []
|
||
if os.path.exists(rbac_load_path):
|
||
import importlib.util
|
||
spec = importlib.util.spec_from_file_location("rbac_load_path", rbac_load_path)
|
||
mod = importlib.util.module_from_spec(spec)
|
||
# 阻止register_paths自动执行
|
||
mod.__name__ = "rbac_load_path"
|
||
spec.loader.exec_module(mod)
|
||
rbac_any_paths = getattr(mod, 'PATHS_ANY', [])
|
||
else:
|
||
print("WARNING: 找不到rbac/scripts/load_path.py,跳过rbac路径注册")
|
||
|
||
if rbac_any_paths:
|
||
print(f"\n--- rbac模块 → any ({len(rbac_any_paths)} 个路径) ---")
|
||
n3 = set_any_perms(rbac_any_paths)
|
||
else:
|
||
n3 = 0
|
||
print("\n--- rbac模块 → any (无路径,跳过) ---")
|
||
|
||
total = n1 + n2 + n3
|
||
print(f"\n=== 完成: 共设置 {total} 个any权限 ===")
|