feat: add init_perm.py for permission initialization
This commit is contained in:
parent
469255afe7
commit
dc8db76a52
104
customer_management/init_perm.py
Normal file
104
customer_management/init_perm.py
Normal file
@ -0,0 +1,104 @@
|
||||
"""Permission initialization utility for business modules.
|
||||
|
||||
Scans wwwroot directory for .ui and .dspy files, registers them in
|
||||
the permission table, and grants access to convention roles.
|
||||
|
||||
Convention roles:
|
||||
- any: anyone (no auth required)
|
||||
- logined: any logged-in user
|
||||
- customer.*: customer org arbitrary role
|
||||
- owner.*: owner org arbitrary role
|
||||
- owner.superuser: superuser for initialization
|
||||
"""
|
||||
import os
|
||||
from appPublic.uniqueID import getID
|
||||
from appPublic.log import debug
|
||||
from sqlor.dbpools import DBPools
|
||||
|
||||
|
||||
def collect_ui_dspy_paths(wwwroot_dir):
|
||||
"""Scan wwwroot directory and return list of URL paths for .ui/.dspy files."""
|
||||
paths = []
|
||||
for dirpath, _, filenames in os.walk(wwwroot_dir):
|
||||
for fn in sorted(filenames):
|
||||
if fn.endswith(('.ui', '.dspy')):
|
||||
full = os.path.join(dirpath, fn)
|
||||
rel = os.path.relpath(full, wwwroot_dir)
|
||||
# Convert to URL path: module_name/relative/path
|
||||
url = '/' + rel.replace(os.sep, '/')
|
||||
# Skip base.ui (layout template, not a standalone page)
|
||||
if fn == 'base.ui':
|
||||
continue
|
||||
paths.append(url)
|
||||
return paths
|
||||
|
||||
|
||||
async def ensure_permission(sor, path, permtype='page'):
|
||||
"""Ensure permission exists in database, return permid."""
|
||||
recs = await sor.R('permission', {'path': path})
|
||||
if recs:
|
||||
return recs[0].id
|
||||
permid = getID()
|
||||
await sor.C('permission', {
|
||||
'id': permid,
|
||||
'name': path.split('/')[-1],
|
||||
'path': path,
|
||||
'permtype': permtype,
|
||||
})
|
||||
return permid
|
||||
|
||||
|
||||
async def ensure_role(sor, orgtypeid, name):
|
||||
"""Ensure role exists in database, return roleid."""
|
||||
recs = await sor.R('role', {'orgtypeid': orgtypeid, 'name': name})
|
||||
if recs:
|
||||
return recs[0].id
|
||||
roleid = getID()
|
||||
await sor.C('role', {
|
||||
'id': roleid,
|
||||
'orgtypeid': orgtypeid,
|
||||
'name': name,
|
||||
})
|
||||
return roleid
|
||||
|
||||
|
||||
async def grant_permission(sor, roleid, permid):
|
||||
"""Grant permission to role if not already granted."""
|
||||
recs = await sor.R('rolepermission', {'roleid': roleid, 'permid': permid})
|
||||
if not recs:
|
||||
await sor.C('rolepermission', {
|
||||
'id': getID(),
|
||||
'roleid': roleid,
|
||||
'permid': permid,
|
||||
})
|
||||
|
||||
|
||||
async def init_module_permissions(dbname, module_name, wwwroot_dir):
|
||||
"""Initialize permissions for a business module.
|
||||
|
||||
Scans wwwroot for .ui/.dspy files, registers paths in permission table,
|
||||
and grants access to convention roles (logined, customer.*, owner.superuser).
|
||||
"""
|
||||
paths = collect_ui_dspy_paths(wwwroot_dir)
|
||||
if not paths:
|
||||
debug(f'{module_name}: no UI/DSPY paths found, skipping permission init')
|
||||
return
|
||||
|
||||
db = DBPools()
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
# Ensure convention roles exist
|
||||
role_logined = await ensure_role(sor, '*', 'logined')
|
||||
role_customer = await ensure_role(sor, 'customer', '*')
|
||||
role_superuser = await ensure_role(sor, 'owner', 'superuser')
|
||||
|
||||
# Register paths and grant permissions
|
||||
for path in paths:
|
||||
permid = await ensure_permission(sor, path)
|
||||
# Grant to logined users
|
||||
await grant_permission(sor, role_logined, permid)
|
||||
# Grant to customer org users
|
||||
await grant_permission(sor, role_customer, permid)
|
||||
# Grant to superuser
|
||||
await grant_permission(sor, role_superuser, permid)
|
||||
|
||||
debug(f'{module_name}: registered {len(paths)} permissions')
|
||||
Loading…
x
Reference in New Issue
Block a user