#!/usr/bin/env python # -*- coding: utf-8 -*- """ Export Script: Generate Access Rules per Role Report Usage: python script_export_accessrules.py > output.md python script_export_accessrules.py --file ../docs/reports/access-rules.md """ import sys import os from datetime import datetime # Add parent directory to path for imports sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from modules.interfaces.interfaceDbApp import getRootInterface from modules.datamodels.datamodelRbac import Role, AccessRule def main(): rootInterface = getRootInterface() db = rootInterface.db # Get all roles and rules roles = db.getRecordset(Role, recordFilter=None) rules = db.getRecordset(AccessRule, recordFilter=None) # Group rules by role rulesByRole = {} for rule in rules: roleId = rule.get('roleId') if roleId not in rulesByRole: rulesByRole[roleId] = [] rulesByRole[roleId].append(rule) # Build markdown lines = [] lines.append('# Access Rules per Role') lines.append('') lines.append(f'Generated: {datetime.now().isoformat()}') lines.append('') lines.append(f'Total Roles: {len(roles)}') lines.append(f'Total Rules: {len(rules)}') lines.append('') lines.append('---') lines.append('') for role in sorted(roles, key=lambda r: (r.get('featureCode') or '', r.get('code') or '')): roleId = role.get('id') roleName = role.get('name') or role.get('code') featureCode = role.get('featureCode') or 'system' roleRules = rulesByRole.get(roleId, []) lines.append(f'## {featureCode} / {roleName}') lines.append('') lines.append(f'- **Role ID:** `{roleId}`') lines.append(f'- **Code:** `{role.get("code")}`') lines.append(f'- **Feature:** `{featureCode}`') lines.append(f'- **Rules Count:** {len(roleRules)}') lines.append('') if roleRules: lines.append('| Context | Item | Access |') lines.append('|---------|------|--------|') for rule in sorted(roleRules, key=lambda r: (r.get('context') or '', r.get('item') or '')): ctx = rule.get('context') or '*' item = rule.get('item') or '*' access = rule.get('access') or 'allow' lines.append(f'| {ctx} | `{item}` | {access} |') lines.append('') else: lines.append('*No rules defined*') lines.append('') lines.append('---') lines.append('') md = '\n'.join(lines) # Check for --file argument if '--file' in sys.argv: idx = sys.argv.index('--file') if idx + 1 < len(sys.argv): filePath = sys.argv[idx + 1] with open(filePath, 'w', encoding='utf-8') as f: f.write(md) print(f'Written to {filePath}') return # Output to stdout sys.stdout.reconfigure(encoding='utf-8') print(md) if __name__ == "__main__": main()