revert: remove scripts moved to rbac module
This commit is contained in:
parent
b589e9f155
commit
9ac5ae0830
@ -1,184 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
遍历 wwwroot 下所有通过 ln -s 链接进来的目录,
|
||||
找出没有任何角色拥有权限的文件。
|
||||
|
||||
用法:
|
||||
./py3/bin/python find_unauth_files.py [wwwroot_path]
|
||||
|
||||
示例:
|
||||
# 默认 sage/wwwroot
|
||||
./py3/bin/python find_unauth_files.py
|
||||
|
||||
# 指定路径
|
||||
./py3/bin/python find_unauth_files.py /home/hermesai/repos/sage/wwwroot
|
||||
|
||||
说明:
|
||||
- 只扫描 wwwroot 下直接子目录中是符号链接的目录(ln -s 指向的)
|
||||
- 跟随符号链接遍历(followlinks=True),防环
|
||||
- 检查每个文件是否在 permission 表中有任意角色关联
|
||||
- 输出未授权文件清单
|
||||
|
||||
注意:此脚本只读数据库,不做任何修改。
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import asyncio
|
||||
|
||||
sage_root = os.environ.get('SAGE_ROOT')
|
||||
if sage_root and sage_root not in sys.path:
|
||||
sys.path.insert(0, sage_root)
|
||||
|
||||
from sqlor.dbpools import DBPools
|
||||
from appPublic.jsonConfig import getConfig
|
||||
|
||||
|
||||
def find_symlink_dirs(wwwroot):
|
||||
"""找出 wwwroot 下直接子目录中是符号链接的目录。"""
|
||||
symlinks = []
|
||||
for entry in sorted(os.listdir(wwwroot)):
|
||||
full = os.path.join(wwwroot, entry)
|
||||
if os.path.islink(full) and os.path.isdir(full):
|
||||
target = os.readlink(full)
|
||||
symlinks.append((entry, full, target))
|
||||
return symlinks
|
||||
|
||||
|
||||
def walk_symlink_dirs(wwwroot, symlinks):
|
||||
"""
|
||||
遍历所有符号链接目录下的文件,返回 (relative_path, absolute_path) 列表。
|
||||
relative_path 是相对于 wwwroot 的路径,格式如 /harnessed_agent/index.ui
|
||||
防环:跟踪已访问的真实路径。
|
||||
"""
|
||||
real_wwwroot = os.path.realpath(wwwroot)
|
||||
visited_real = set()
|
||||
files = []
|
||||
|
||||
for name, link_path, target in symlinks:
|
||||
for root, dirs, filenames in os.walk(link_path, followlinks=True):
|
||||
real_root = os.path.realpath(root)
|
||||
|
||||
# 防环:回到 wwwroot 自身或其他已访问路径
|
||||
if real_root in visited_real:
|
||||
dirs.clear()
|
||||
continue
|
||||
visited_real.add(real_root)
|
||||
|
||||
# 排除指向 wwwroot 自身的子目录
|
||||
dirs[:] = [d for d in dirs if os.path.realpath(os.path.join(root, d)) != real_wwwroot]
|
||||
|
||||
for fname in sorted(filenames):
|
||||
abs_path = os.path.join(root, fname)
|
||||
# 相对于 wwwroot 的路径,带前导 /
|
||||
rel = '/' + os.path.relpath(abs_path, wwwroot)
|
||||
files.append((rel, abs_path))
|
||||
|
||||
return files
|
||||
|
||||
|
||||
async def main():
|
||||
wwwroot = sys.argv[1] if len(sys.argv) > 1 else None
|
||||
if not wwwroot:
|
||||
# 默认: sage_root/wwwroot
|
||||
if sage_root:
|
||||
wwwroot = os.path.join(sage_root, 'wwwroot')
|
||||
else:
|
||||
# 尝试从当前目录推断
|
||||
wwwroot = os.path.join(os.getcwd(), 'wwwroot')
|
||||
|
||||
wwwroot = os.path.abspath(wwwroot)
|
||||
if not os.path.isdir(wwwroot):
|
||||
print(f"错误: wwwroot 目录不存在: {wwwroot}")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"wwwroot: {wwwroot}")
|
||||
print(f"SAGE_ROOT: {sage_root or '(未设置)'}")
|
||||
|
||||
# 1. 找符号链接目录
|
||||
symlinks = find_symlink_dirs(wwwroot)
|
||||
if not symlinks:
|
||||
print("\n未发现任何符号链接目录。")
|
||||
sys.exit(0)
|
||||
|
||||
print(f"\n发现 {len(symlinks)} 个符号链接目录:")
|
||||
for name, full, target in symlinks:
|
||||
print(f" {name}/ -> {target}")
|
||||
|
||||
# 2. 遍历所有文件
|
||||
all_files = walk_symlink_dirs(wwwroot, symlinks)
|
||||
print(f"\n共 {len(all_files)} 个文件,开始检查权限...\n")
|
||||
|
||||
# 3. 批量加载所有 permission + rolepermission 记录到内存
|
||||
config = getConfig('.')
|
||||
db = DBPools(config.databases)
|
||||
|
||||
async with db.sqlorContext('sage') as sor:
|
||||
# 加载所有 permission 记录
|
||||
perm_recs = await sor.sqlExe("SELECT id, path FROM permission", {})
|
||||
# 构建 path -> perm_id 映射
|
||||
path_to_permid = {}
|
||||
for r in perm_recs:
|
||||
path_to_permid[r.path] = r.id
|
||||
|
||||
# 加载所有 rolepermission 记录
|
||||
rp_recs = await sor.sqlExe("SELECT permid FROM rolepermission", {})
|
||||
# 构建 perm_id -> 有权限 的标记
|
||||
perms_with_roles = set()
|
||||
for r in rp_recs:
|
||||
perms_with_roles.add(r.permid)
|
||||
|
||||
print(f" permission 表共 {len(path_to_permid)} 条记录")
|
||||
print(f" 有角色关联的 permission 共 {len(perms_with_roles)} 条")
|
||||
|
||||
# 4. 检查每个文件
|
||||
unauth_files = []
|
||||
authed_files = []
|
||||
|
||||
for rel_path, abs_path in all_files:
|
||||
permid = path_to_permid.get(rel_path)
|
||||
if permid is None:
|
||||
# 路径完全未注册
|
||||
unauth_files.append((rel_path, abs_path, "路径未注册"))
|
||||
elif permid not in perms_with_roles:
|
||||
# 路径有 permission 记录但没有任何角色关联
|
||||
unauth_files.append((rel_path, abs_path, "有记录但无角色"))
|
||||
else:
|
||||
authed_files.append(rel_path)
|
||||
|
||||
# 5. 输出结果
|
||||
print(f"\n{'='*80}")
|
||||
print(f"结果汇总:")
|
||||
print(f" 已授权文件: {len(authed_files)}")
|
||||
print(f" 未授权文件: {len(unauth_files)}")
|
||||
print(f"{'='*80}")
|
||||
|
||||
if not unauth_files:
|
||||
print("\n所有文件均有权限覆盖,无需处理。")
|
||||
return
|
||||
|
||||
print(f"\n未授权文件清单 ({len(unauth_files)} 个):\n")
|
||||
|
||||
# 按模块目录分组
|
||||
from collections import defaultdict
|
||||
by_module = defaultdict(list)
|
||||
for rel_path, abs_path, reason in unauth_files:
|
||||
# 提取模块名: /harnessed_agent/xxx -> harnessed_agent
|
||||
parts = rel_path.strip('/').split('/')
|
||||
module = parts[0] if parts else 'root'
|
||||
by_module[module].append((rel_path, abs_path, reason))
|
||||
|
||||
for module in sorted(by_module.keys()):
|
||||
items = by_module[module]
|
||||
print(f"\n--- {module}/ ({len(items)} 个文件) ---")
|
||||
for rel_path, abs_path, reason in items:
|
||||
print(f" [{reason}] {rel_path}")
|
||||
|
||||
# 也输出纯路径列表(方便管道处理)
|
||||
print(f"\n{'='*80}")
|
||||
print("纯路径列表(方便复制):")
|
||||
for rel_path, abs_path, reason in unauth_files:
|
||||
print(f" {rel_path}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.get_event_loop().run_until_complete(main())
|
||||
@ -1,92 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
列出指定路径拥有权限的所有角色。
|
||||
|
||||
用法:
|
||||
./py3/bin/python list_path_roles.py <path>
|
||||
|
||||
示例:
|
||||
./py3/bin/python list_path_roles.py /harnessed_agent/index.ui
|
||||
./py3/bin/python list_path_roles.py /bricks/css/bricks.css
|
||||
|
||||
说明:
|
||||
- 精确匹配路径
|
||||
- 如果路径未注册,会提示
|
||||
- 显示角色 id、orgtypeid、name
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import asyncio
|
||||
|
||||
sage_root = os.environ.get('SAGE_ROOT')
|
||||
if sage_root and sage_root not in sys.path:
|
||||
sys.path.insert(0, sage_root)
|
||||
|
||||
from sqlor.dbpools import DBPools
|
||||
from appPublic.jsonConfig import getConfig
|
||||
|
||||
|
||||
async def main():
|
||||
if len(sys.argv) < 2:
|
||||
print(f"用法: {sys.argv[0]} <path>")
|
||||
print(f"示例: {sys.argv[0]} /harnessed_agent/index.ui")
|
||||
sys.exit(1)
|
||||
|
||||
target_path = sys.argv[1]
|
||||
if not target_path.startswith('/'):
|
||||
target_path = '/' + target_path
|
||||
|
||||
config = getConfig('.')
|
||||
db = DBPools(config.databases)
|
||||
|
||||
async with db.sqlorContext('sage') as sor:
|
||||
# 1. 查找 permission 记录
|
||||
perm_recs = await sor.R('permission', {'path': target_path})
|
||||
if not perm_recs:
|
||||
print(f"[未找到] 路径 '{target_path}' 未在 permission 表中注册。")
|
||||
|
||||
# 尝试 LIKE 模糊匹配
|
||||
like_path = target_path.rstrip('/') + '/%'
|
||||
like_recs = await sor.sqlExe("SELECT path FROM permission WHERE path LIKE %s", (like_path,))
|
||||
if like_recs:
|
||||
print(f"\n模糊匹配到 {len(like_recs)} 个子路径(LIKE '{like_path}'):")
|
||||
for r in like_recs[:20]:
|
||||
print(f" {r.path}")
|
||||
if len(like_recs) > 20:
|
||||
print(f" ... 共 {len(like_recs)} 条")
|
||||
sys.exit(0)
|
||||
|
||||
perm = perm_recs[0]
|
||||
print(f"路径: {perm.path}")
|
||||
print(f"perm_id: {perm.id}")
|
||||
|
||||
# 2. 查找 rolepermission 关联
|
||||
rp_recs = await sor.R('rolepermission', {'permid': perm.id})
|
||||
if not rp_recs:
|
||||
print(" [无角色] 该路径没有任何角色权限记录。")
|
||||
sys.exit(0)
|
||||
|
||||
print(f"\n共 {len(rp_recs)} 个角色有权限:\n")
|
||||
print(f"{'角色ID':<30} {'orgtypeid':<20} {'名称':<30}")
|
||||
print("-" * 80)
|
||||
|
||||
for rp in rp_recs:
|
||||
roleid = rp.roleid
|
||||
# 特殊角色直接显示
|
||||
if roleid in ('any', 'anonymous', 'logined'):
|
||||
print(f"{roleid:<30} {'*':<20} {roleid:<30}")
|
||||
continue
|
||||
|
||||
# 普通角色查 role 表
|
||||
role_recs = await sor.R('role', {'id': roleid})
|
||||
if role_recs:
|
||||
r = role_recs[0]
|
||||
orgtypeid = getattr(r, 'orgtypeid', '*')
|
||||
name = getattr(r, 'name', roleid)
|
||||
print(f"{roleid:<30} {orgtypeid:<20} {name:<30}")
|
||||
else:
|
||||
print(f"{roleid:<30} {'(未知)':<20} {'(role表中不存在)':<30}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.get_event_loop().run_until_complete(main())
|
||||
Loading…
x
Reference in New Issue
Block a user