fix: tenant RBAC — 补充 owner.*/reseller.* 管理角色的 rolepermission 关联
This commit is contained in:
parent
54055980dd
commit
a08b1c5cdb
@ -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)
|
||||||
|
cnt = 0
|
||||||
async with DBPools().sqlorContext('sage') as sor:
|
async with DBPools().sqlorContext('sage') as sor:
|
||||||
cnt = 0
|
# 1. 查出所有角色 ID
|
||||||
for path, role in paths:
|
role_ids = {}
|
||||||
r = await sor.sqlExe(
|
for orgtypeid, name in ROLES_NEEDED:
|
||||||
'select * from permission where path = ${path}$ and permtype = ${role}$',
|
recs = await sor.sqlExe(
|
||||||
{'path': path, 'role': role}
|
'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(),
|
|
||||||
'path': path,
|
|
||||||
'name': path,
|
|
||||||
'permtype': role,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
cnt += 1
|
perm_ids[path] = pid
|
||||||
print(f'tenant: {cnt} new permissions inserted (total {len(paths)} paths)')
|
print(f" Created permission: {path}")
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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__':
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user