Add the get_permissions plugin hook (contract 0.10.0)
Plugins declare their own RBAC permissions instead of core accumulating them: 36 permissions moved out of the core catalog into the 9 owning plugins (core keeps the 19 its own blueprints enforce). The catalog is resolved dynamically (core + enabled plugins) and feeds the roles grid, the token scope picker and ceiling, and flask seed permissions; installing or enabling a plugin seeds its permissions automatically. A disabled plugin drops out of the assignable catalog while existing role links keep working. New plugins - bundled or external - now bring their permissions with zero core edits. 781 tests pass; live-verified with a machines.edit-scoped token. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,8 @@ from flask_jwt_extended import jwt_required, current_user
|
||||
from werkzeug.security import generate_password_hash
|
||||
|
||||
from shopdb.extensions import db
|
||||
from shopdb.core.models import User, Role, Permission, AuditLog
|
||||
from shopdb.core.models import (
|
||||
User, Role, Permission, AuditLog, full_permission_catalog)
|
||||
from shopdb.utils.responses import success_response, error_response, ErrorCodes
|
||||
from shopdb.utils.authz import require_role
|
||||
|
||||
@@ -179,29 +180,29 @@ def delete_user(userid: int):
|
||||
@users_bp.route('/permissions', methods=['GET'])
|
||||
@jwt_required()
|
||||
def list_permissions():
|
||||
"""List all permissions grouped by category."""
|
||||
permissions = Permission.query.order_by(Permission.category, Permission.name).all()
|
||||
"""List assignable permissions grouped by category.
|
||||
|
||||
Driven by full_permission_catalog() (core plus ENABLED plugins) so a
|
||||
disabled plugin's permissions drop out of the role grid. Roles assign by
|
||||
name; the permissionid comes from the seeded Permission row when present.
|
||||
"""
|
||||
idbyname = {p.name: p.permissionid for p in Permission.query.all()}
|
||||
|
||||
catalog = full_permission_catalog()
|
||||
catalog.sort(key=lambda e: (e[2], e[0]))
|
||||
|
||||
# Group by category
|
||||
grouped = {}
|
||||
for p in permissions:
|
||||
if p.category not in grouped:
|
||||
grouped[p.category] = []
|
||||
grouped[p.category].append({
|
||||
'permissionid': p.permissionid,
|
||||
'name': p.name,
|
||||
'description': p.description
|
||||
})
|
||||
flat = []
|
||||
for name, description, category in catalog:
|
||||
entry = {
|
||||
'permissionid': idbyname.get(name),
|
||||
'name': name,
|
||||
'description': description,
|
||||
}
|
||||
grouped.setdefault(category, []).append(entry)
|
||||
flat.append({**entry, 'category': category})
|
||||
|
||||
return success_response({
|
||||
'permissions': [{
|
||||
'permissionid': p.permissionid,
|
||||
'name': p.name,
|
||||
'description': p.description,
|
||||
'category': p.category
|
||||
} for p in permissions],
|
||||
'grouped': grouped
|
||||
})
|
||||
return success_response({'permissions': flat, 'grouped': grouped})
|
||||
|
||||
|
||||
# Roles endpoints
|
||||
|
||||
Reference in New Issue
Block a user