fix: tenant RBAC — 补充 owner.*/reseller.* 管理角色的 rolepermission 关联

This commit is contained in:
yumoqing 2026-07-14 16:04:38 +08:00
parent 54055980dd
commit a08b1c5cdb

View File

@ -1,5 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""RBAC 权限注册 — tenant 模块""" """RBAC 权限注册 — tenant 模块
tenant 路径补充 owner.* *.admin 等管理角色的 rolepermission 关联
"""
import os, sys, asyncio import os, sys, asyncio
MOD = "tenant" MOD = "tenant"
@ -24,54 +26,93 @@ from appPublic.jsonConfig import getConfig
from appPublic.dictObject import DictObject from appPublic.dictObject import DictObject
from appPublic.uniqueID import getID from appPublic.uniqueID import getID
paths = [ # tenant 所有需要权限的路径
# 模块入口 TENANT_PATHS = [
(f"/{MOD}", "logined"), f"/{MOD}",
(f"/{MOD}/index.ui", "logined"), f"/{MOD}/index.ui",
(f"/{MOD}/menu.ui", "any"), f"/{MOD}/tenant_domain",
# CRUD 列表页 f"/{MOD}/tenant_domain/index.ui",
(f"/{MOD}/tenant_domain", "logined"), f"/{MOD}/tenant_domain/get_tenant_domain.dspy",
(f"/{MOD}/tenant_domain/index.ui", "logined"), f"/{MOD}/tenant_domain/add_tenant_domain.dspy",
(f"/{MOD}/tenant_domain/get_tenant_domain.dspy", "logined"), f"/{MOD}/tenant_domain/update_tenant_domain.dspy",
(f"/{MOD}/tenant_domain/add_tenant_domain.dspy", "logined"), f"/{MOD}/tenant_domain/delete_tenant_domain.dspy",
(f"/{MOD}/tenant_domain/update_tenant_domain.dspy", "logined"), f"/{MOD}/api/tenant_domain_list.dspy",
(f"/{MOD}/tenant_domain/delete_tenant_domain.dspy", "logined"), f"/{MOD}/api/tenant_domain_get.dspy",
# API 端点(之前漏掉的) f"/{MOD}/api/tenant_domain_create.dspy",
(f"/{MOD}/api/tenant_domain_list.dspy", "logined"), f"/{MOD}/api/tenant_domain_update.dspy",
(f"/{MOD}/api/tenant_domain_get.dspy", "logined"), f"/{MOD}/api/tenant_domain_delete.dspy",
(f"/{MOD}/api/tenant_domain_create.dspy", "logined"), f"/{MOD}/api/get_org_list.dspy",
(f"/{MOD}/api/tenant_domain_update.dspy", "logined"), f"/{MOD}/api/tenant_domain.json",
(f"/{MOD}/api/tenant_domain_delete.dspy", "logined"), ]
(f"/{MOD}/api/get_org_list.dspy", "logined"),
# 管理角色 # 需要授权的角色: (orgtypeid, name) → 用于匹配 role 表
(f"/{MOD}", "*.admin"), ROLES_NEEDED = [
(f"/{MOD}", "owner.superuser"), ("owner", "superuser"),
("owner", "developer"),
("owner", "admin"),
("reseller", "superuser"),
("reseller", "developer"),
("reseller", "admin"),
] ]
async def main(): async def main():
config = getConfig('.') config = getConfig('.')
DBPools(config.databases) DBPools(config.databases)
async with DBPools().sqlorContext('sage') as sor:
cnt = 0 cnt = 0
for path, role in paths: async with DBPools().sqlorContext('sage') as sor:
r = await sor.sqlExe( # 1. 查出所有角色 ID
'select * from permission where path = ${path}$ and permtype = ${role}$', role_ids = {}
{'path': path, 'role': role} for orgtypeid, name in ROLES_NEEDED:
recs = await sor.sqlExe(
'SELECT id FROM role WHERE orgtypeid=${oid}$ AND name=${name}$',
{'oid': orgtypeid, 'name': name}
) )
if len(r) == 0: if recs:
role_ids[f'{orgtypeid}.{name}'] = recs[0].id
print(f"Found {len(role_ids)} roles: {list(role_ids.keys())}")
# 2. 查出 tenant 路径的 permission ID
perm_ids = {}
for path in TENANT_PATHS:
recs = await sor.sqlExe(
'SELECT id FROM permission WHERE path=${path}$',
{'path': path}
)
if recs:
perm_ids[path] = recs[0].id
else:
# 创建缺失的 permission
pid = getID()
await sor.sqlExe( await sor.sqlExe(
'''insert into permission (id, path, name, permtype) 'INSERT INTO permission (id, path, name) VALUES (${id}$, ${path}$, ${name}$)',
values (${id}$, ${path}$, ${name}$, ${permtype}$)''', {'id': pid, 'path': path, 'name': path}
{ )
'id': getID(), perm_ids[path] = pid
'path': path, print(f" Created permission: {path}")
'name': path,
'permtype': role, print(f"Found {len(perm_ids)} permission paths")
}
# 3. 补充缺失的 rolepermission 关联
for role_key, role_id in role_ids.items():
for path, perm_id in perm_ids.items():
existing = await sor.sqlExe(
'SELECT id FROM rolepermission WHERE roleid=${rid}$ AND permid=${pid}$',
{'rid': role_id, 'pid': perm_id}
)
if not existing:
await sor.sqlExe(
'INSERT INTO rolepermission (id, roleid, permid) VALUES (${id}$, ${rid}$, ${pid}$)',
{'id': getID(), 'rid': role_id, 'pid': perm_id}
) )
cnt += 1 cnt += 1
print(f'tenant: {cnt} new permissions inserted (total {len(paths)} paths)')
if cnt > 0:
print(f"tenant: {cnt} new rolepermission links inserted")
print(" Clear RBAC cache needed: restart Sage or wait for TTL")
else:
print("tenant: all rolepermission links already exist")
if __name__ == '__main__': if __name__ == '__main__':