fix(d3): ARCH-055/056/057 — errors.py error.user_agent statt nicht existierendem userAgent (AttributeError zur Laufzeit); roles.py SYSTEM_PERMISSIONS aus CORE_PERMISSIONS abgeleitet (47 statt 36 Permissions, Drift behoben, category→system für Frontend-Gruppierung); registry._plugins→öffentliche API list_discovered()+get_plugin()
This commit is contained in:
@@ -114,7 +114,7 @@ async def report_error(error: ErrorReport, request: Request) -> Response:
|
|||||||
"error_stack": error.stack,
|
"error_stack": error.stack,
|
||||||
"error_context": sanitized_context,
|
"error_context": sanitized_context,
|
||||||
"error_url": error.url,
|
"error_url": error.url,
|
||||||
"error_user_agent": error.userAgent,
|
"error_user_agent": error.user_agent,
|
||||||
"client_ip": client_ip,
|
"client_ip": client_ip,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -128,7 +128,7 @@ async def report_error(error: ErrorReport, request: Request) -> Response:
|
|||||||
"message": error.message,
|
"message": error.message,
|
||||||
"stack": error.stack,
|
"stack": error.stack,
|
||||||
"url": error.url,
|
"url": error.url,
|
||||||
"userAgent": error.userAgent,
|
"userAgent": error.user_agent,
|
||||||
"timestamp": error.timestamp,
|
"timestamp": error.timestamp,
|
||||||
"context": sanitized_context,
|
"context": sanitized_context,
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-39
@@ -12,7 +12,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|||||||
from app.core.audit import log_audit
|
from app.core.audit import log_audit
|
||||||
from app.core.auth import get_redis
|
from app.core.auth import get_redis
|
||||||
from app.core.db import get_db
|
from app.core.db import get_db
|
||||||
from app.core.permission_registry import get_permission_registry
|
from app.core.permission_registry import CORE_PERMISSIONS, get_permission_registry
|
||||||
from app.core.permissions import invalidate_all_user_permissions
|
from app.core.permissions import invalidate_all_user_permissions
|
||||||
from app.deps import require_permission
|
from app.deps import require_permission
|
||||||
from app.models.plugin import Plugin as PluginModel
|
from app.models.plugin import Plugin as PluginModel
|
||||||
@@ -24,44 +24,16 @@ from app.services.role_service import role_service
|
|||||||
router = APIRouter(prefix="/api/v1/roles", tags=["roles"])
|
router = APIRouter(prefix="/api/v1/roles", tags=["roles"])
|
||||||
|
|
||||||
|
|
||||||
|
# Derived from CORE_PERMISSIONS so changes in permission_registry are reflected
|
||||||
|
# automatically. ``category`` is remapped to "system" because the frontend groups
|
||||||
|
# permissions by that value (SettingsGroups.tsx).
|
||||||
SYSTEM_PERMISSIONS: list[dict[str, str]] = [
|
SYSTEM_PERMISSIONS: list[dict[str, str]] = [
|
||||||
# Plugin permissions are loaded dynamically from the permission registry.
|
{
|
||||||
{"key": "users:read", "label": "Users: Read", "category": "system"},
|
"key": perm["key"],
|
||||||
{"key": "users:write", "label": "Users: Write", "category": "system"},
|
"label": perm["label"],
|
||||||
{"key": "users:delete", "label": "Users: Delete", "category": "system"},
|
"category": "system",
|
||||||
{"key": "roles:read", "label": "Roles: Read", "category": "system"},
|
}
|
||||||
{"key": "roles:write", "label": "Roles: Write", "category": "system"},
|
for perm in CORE_PERMISSIONS
|
||||||
{"key": "roles:delete", "label": "Roles: Delete", "category": "system"},
|
|
||||||
{"key": "groups:read", "label": "Groups: Read", "category": "system"},
|
|
||||||
{"key": "groups:write", "label": "Groups: Write", "category": "system"},
|
|
||||||
{"key": "groups:delete", "label": "Groups: Delete", "category": "system"},
|
|
||||||
{"key": "audit:read", "label": "Audit Log: Read", "category": "system"},
|
|
||||||
{"key": "settings:read", "label": "Settings: Read", "category": "system"},
|
|
||||||
{"key": "settings:write", "label": "Settings: Write", "category": "system"},
|
|
||||||
{"key": "plugins:read", "label": "Plugins: Read", "category": "system"},
|
|
||||||
{"key": "plugins:install", "label": "Plugins: Install", "category": "system"},
|
|
||||||
{"key": "plugins:configure", "label": "Plugins: Configure", "category": "system"},
|
|
||||||
{"key": "tenants:read", "label": "Tenants: Read", "category": "system"},
|
|
||||||
{"key": "tenants:write", "label": "Tenants: Write", "category": "system"},
|
|
||||||
{"key": "tenants:delete", "label": "Tenants: Delete", "category": "system"},
|
|
||||||
{"key": "notifications:read", "label": "Notifications: Read", "category": "system"},
|
|
||||||
{"key": "notifications:write", "label": "Notifications: Write", "category": "system"},
|
|
||||||
{"key": "attachments:read", "label": "Attachments: Read", "category": "system"},
|
|
||||||
{"key": "attachments:write", "label": "Attachments: Write", "category": "system"},
|
|
||||||
{"key": "attachments:delete", "label": "Attachments: Delete", "category": "system"},
|
|
||||||
{"key": "workflows:read", "label": "Workflows: Read", "category": "system"},
|
|
||||||
{"key": "workflows:write", "label": "Workflows: Write", "category": "system"},
|
|
||||||
{"key": "sequences:read", "label": "Sequences: Read", "category": "system"},
|
|
||||||
{"key": "sequences:write", "label": "Sequences: Write", "category": "system"},
|
|
||||||
{"key": "addresses:read", "label": "Addresses: Read", "category": "system"},
|
|
||||||
{"key": "addresses:write", "label": "Addresses: Write", "category": "system"},
|
|
||||||
{"key": "addresses:delete", "label": "Addresses: Delete", "category": "system"},
|
|
||||||
{"key": "taxes:read", "label": "Taxes: Read", "category": "system"},
|
|
||||||
{"key": "taxes:write", "label": "Taxes: Write", "category": "system"},
|
|
||||||
{"key": "currencies:read", "label": "Currencies: Read", "category": "system"},
|
|
||||||
{"key": "currencies:write", "label": "Currencies: Write", "category": "system"},
|
|
||||||
{"key": "import_export:read", "label": "Import/Export: Read", "category": "system"},
|
|
||||||
{"key": "import_export:write", "label": "Import/Export: Write", "category": "system"},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -87,9 +59,12 @@ async def list_permissions(
|
|||||||
|
|
||||||
# Collect permissions from active plugins' manifests
|
# Collect permissions from active plugins' manifests
|
||||||
seen_keys: set[str] = set()
|
seen_keys: set[str] = set()
|
||||||
for name, plugin in registry._plugins.items():
|
for name in registry.list_discovered():
|
||||||
if name not in active_records:
|
if name not in active_records:
|
||||||
continue
|
continue
|
||||||
|
plugin = registry.get_plugin(name)
|
||||||
|
if plugin is None:
|
||||||
|
continue
|
||||||
for perm in plugin.manifest.permissions:
|
for perm in plugin.manifest.permissions:
|
||||||
if perm in seen_keys:
|
if perm in seen_keys:
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in New Issue
Block a user