From a4a885f63822b3dfea1d1079ee5b67c892e6d6b3 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Wed, 3 Jun 2026 16:06:33 +0800 Subject: [PATCH] feat: add init_any_permissions.py for auto-discovering wwwroot and bricks files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Auto-scan entcms/wwwroot → / (recursive) - Auto-scan dingdingflow/wwwroot → /dingdingflow (recursive) - Auto-scan bricks/ → /bricks (recursive) - Skip symlinks to external modules - Skip .pyc, __pycache__, .git, .bak etc. - Set 'any' role for all discovered files --- init_any_permissions.py | 138 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 init_any_permissions.py diff --git a/init_any_permissions.py b/init_any_permissions.py new file mode 100644 index 0000000..74f8725 --- /dev/null +++ b/init_any_permissions.py @@ -0,0 +1,138 @@ +""" +CMS RBAC权限初始化 — any (匿名) 角色 +自动扫描 wwwroot 和 bricks 下所有文件,授予 any 角色权限 + +规则: +- entcms/wwwroot/* → / +- dingdingflow/wwwroot/* → /dingdingflow/ +- bricks/* → /bricks/ +- 排除: .pyc, __pycache__, .git, 指向其他模块的符号链接 + +用法: cd ~/repos/cms && py3/bin/python init_any_permissions.py +""" +import os, sys, subprocess, re + +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_wwwroot(wwwroot_dir, url_prefix): + """扫描wwwroot目录下所有文件,返回URL路径列表""" + paths = [] + if not os.path.isdir(wwwroot_dir): + return paths + for root, dirs, files in os.walk(wwwroot_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: + continue + if f.startswith("."): + continue + # 计算相对路径 + rel_path = os.path.relpath(os.path.join(root, f), wwwroot_dir) + # 检查是否是符号链接指向其他模块 + full_path = os.path.join(root, f) + if os.path.islink(full_path): + link_target = os.path.realpath(full_path) + # 如果链接目标不在CMS目录下,跳过 + if not link_target.startswith(app_root): + print(f" SKIP (外部链接): {rel_path} -> {link_target}") + continue + url = url_prefix + "/" + rel_path.replace(os.sep, "/") + paths.append(url) + return paths + +def scan_bricks(bricks_dir): + """扫描bricks目录下所有文件,返回URL路径列表""" + paths = [] + if not os.path.isdir(bricks_dir): + return paths + # 检查bricks是否为符号链接 + real_bricks = os.path.realpath(bricks_dir) + for root, dirs, files in os.walk(bricks_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: + continue + if 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(real_bricks) and not link_target.startswith(app_root): + continue + rel_path = os.path.relpath(full_path, bricks_dir) + url = "/bricks/" + rel_path.replace(os.sep, "/") + paths.append(url) + return paths + +def set_any_perms(paths): + """为路径列表设置any权限""" + count = 0 + for p in paths: + result = subprocess.run( + [py, sp, "any", p], + cwd=sage_root, + capture_output=True, + text=True + ) + status = "✓" if result.returncode == 0 else "✗" + print(f" {status} any {p}") + count += 1 + return count + +print("=== CMS RBAC权限初始化 — any (匿名访问) ===") +print(f"Sage: {sage_root}") +print() + +# 1. entcms/wwwroot → / +entcms_paths = scan_wwwroot( + os.path.join(app_root, "entcms", "wwwroot"), + "" +) +print(f"--- entcms/wwwroot → / ({len(entcms_paths)} 个文件) ---") +n1 = set_any_perms(entcms_paths) + +# 2. dingdingflow/wwwroot → /dingdingflow +dd_paths = scan_wwwroot( + os.path.join(app_root, "dingdingflow", "wwwroot"), + "/dingdingflow" +) +print(f"\n--- dingdingflow/wwwroot → /dingdingflow ({len(dd_paths)} 个文件) ---") +n2 = set_any_perms(dd_paths) + +# 3. bricks → /bricks +bricks_dir = os.path.join(app_root, "bricks") +bricks_paths = scan_bricks(bricks_dir) +if bricks_paths: + print(f"\n--- bricks → /bricks ({len(bricks_paths)} 个文件) ---") + n3 = set_any_perms(bricks_paths) +else: + n3 = 0 + print(f"\n--- bricks → /bricks (目录不存在或未构建,跳过) ---") + +total = n1 + n2 + n3 +print(f"\n=== 完成: 共设置 {total} 个any权限 ===")