- infrasynth.configs: typed multi-tenant config store (registry, service, secrets, cache) + public config_changed/config_reset signals and API - emit the declared-but-dead signals (features flags/overrides, scheduler task_completed/task_failed, tenancy tenant_updated, audit model_changed) and per-model audit field exclusions - security: permission catalog (security_permission), Django-style model-derived AutoPermission, PermissionRegistry, RoleAssignment, global-or-tenant Grant/Revoke, catalog API - consolidate the permission surface: PermissionRegistry only (drop the settings dict), IsAuthenticatedAndPermitted aliases HybridPermission, require_permission replaced by required_permissions + require_all - packaging: add [build-system]; add Forgejo publish workflow (.forgejo)
44 lines
1.4 KiB
Python
44 lines
1.4 KiB
Python
"""Kit base viewsets with model-derived permissions wired in.
|
|
|
|
Subclass one of these in a consuming app and CRUD/view endpoints require the
|
|
auto-derived codename (``{app}.{verb}_{model}``) with no per-view configuration::
|
|
|
|
from infrasynth.security.viewsets import InfraSynthModelViewSet
|
|
|
|
class TicketViewSet(InfraSynthModelViewSet):
|
|
queryset = Ticket.objects.all()
|
|
serializer_class = TicketSerializer # needs view/add/change/delete_ticket
|
|
|
|
An explicit ``required_permissions`` still wins, and custom actions can name
|
|
their own codename with ``action_permissions = {"resolve": "helpdesk.resolve_ticket"}``.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from rest_framework import viewsets
|
|
|
|
from .permissions import IsAuthenticatedAndPermitted
|
|
|
|
__all__ = [
|
|
"InfraSynthModelViewSet",
|
|
"InfraSynthReadOnlyModelViewSet",
|
|
"AutoPermissionMixin",
|
|
]
|
|
|
|
|
|
class AutoPermissionMixin:
|
|
"""Marks a viewset as opting into auto-derived model permissions."""
|
|
|
|
auto_permissions = True
|
|
|
|
|
|
class InfraSynthModelViewSet(AutoPermissionMixin, viewsets.ModelViewSet):
|
|
"""Full CRUD viewset: derives view/add/change/delete permissions."""
|
|
|
|
permission_classes = [IsAuthenticatedAndPermitted]
|
|
|
|
|
|
class InfraSynthReadOnlyModelViewSet(AutoPermissionMixin, viewsets.ReadOnlyModelViewSet):
|
|
"""Read-only viewset: derives the view permission."""
|
|
|
|
permission_classes = [IsAuthenticatedAndPermitted]
|