========================================= Authorization — PEP et Décorateurs ========================================= Le PEP (Policy Enforcement Point) intègre le moteur ABAC dans les vues DRF via des permissions et des décorateurs. Module : ``src.module.authorization.infrastructure.permissions`` .. module:: src.module.authorization.infrastructure.permissions :synopsis: Permissions DRF pour l'enforcement ABAC Permissions DRF =============== .. class:: ABACPermission(BasePermission) Permission DRF qui évalue les politiques ABAC pour chaque requête. À ajouter dans ``permission_classes`` d'un ViewSet : .. code-block:: python from src.module.authorization.infrastructure.permissions import ABACPermission class InvoiceViewSet(ModelViewSet): permission_classes = [IsAuthenticated, ABACPermission] queryset = Invoice.objects.all() .. method:: has_permission(request, view) -> bool 1. Résout l'action DRF → ActionType ABAC via ``DRF_ACTION_MAPPING`` 2. Appelle ``evaluate_abac()`` 3. Retourne ``True`` (allow) ou lève une exception (deny/approval) .. class:: IsTenantMember(BasePermission) Vérifie que l'utilisateur a une membership active dans le tenant courant. .. class:: IsTenantAdmin(BasePermission) Vérifie que l'utilisateur a le rôle ``"admin"`` dans le tenant courant. .. class:: IsApprover(BasePermission) Vérifie que l'utilisateur est un approbateur autorisé. Fonctions d'évaluation ======================== .. function:: evaluate_abac(action, resource_type, resource_id=None, subject_attributes=None, resource_attributes=None, environment_attributes=None) -> EvaluationResult Évalue une requête d'accès contre les politiques ABAC. :param action: Action ABAC (``"read"``, ``"create"``, ``"update"``, ``"delete"``) :param resource_type: Type de ressource (ex: ``"Invoice"``) :param resource_id: ID de la ressource (optionnel, pour les politiques object-level) :returns: ``EvaluationResult`` avec la décision et les détails .. function:: check_abac(action, resource_type, resource_id=None) -> None Raccourci qui lève ``AccessDeniedError`` si l'accès est refusé. .. code-block:: python from src.module.authorization.infrastructure.permissions import check_abac def transfer_funds(source, destination, amount): check_abac("update", "BankAccount", str(source.id)) # Si on arrive ici, l'accès est autorisé source.transfer(destination, amount) Décorateur @abac_required ========================== Module : ``src.module.authorization.infrastructure.decorators`` .. module:: src.module.authorization.infrastructure.decorators :synopsis: Décorateur ABAC pour vues et méthodes de service .. function:: abac_required(action: str, resource_type: str) Décorateur pour protéger des vues ou méthodes de service avec ABAC. :param action: Action ABAC requise :param resource_type: Type de ressource protégé **Sur une vue DRF :** .. code-block:: python from src.module.authorization.infrastructure.decorators import abac_required class ReportViewSet(ViewSet): @abac_required("read", "FinancialReport") def list(self, request): reports = FinancialReport.objects.all() return Response(ReportSerializer(reports, many=True).data) @abac_required("create", "FinancialReport") def create(self, request): ... **Sur une méthode de service :** .. code-block:: python class InvoiceService: @abac_required("delete", "Invoice") def delete_invoice(self, invoice_id): invoice = Invoice.objects.get(id=invoice_id) invoice.delete() Si l'accès est refusé, lève ``AccessDeniedError`` (→ HTTP 403). Si une approbation est requise, lève ``ApprovalRequiredError`` (→ HTTP 202). Value Objects d'évaluation ============================ Module : ``src.module.authorization.domain.value_objects`` .. module:: src.module.authorization.domain.value_objects :synopsis: Value Objects pour l'évaluation ABAC .. class:: EvaluationRequest Requête d'évaluation ABAC. :Champs: ``action``, ``resource_type``, ``resource_id``, ``subject_attributes``, ``resource_attributes``, ``environment_attributes`` .. class:: EvaluationResult Résultat d'une évaluation ABAC. :Champs: ``decision`` (``"allow"``/``"deny"``/``"approval_required"``), ``matched_policy_id``, ``matched_policy_name``, ``reason`` .. class:: PolicyData Snapshot immuable d'une politique pour l'évaluation. :Champs: ``id``, ``name``, ``effect``, ``priority``, ``actions``, ``resource_type``, ``subject_conditions``, ``resource_conditions``, ``environment_conditions``, ``requires_approval``, ``approval_config``