from django.core.exceptions import PermissionDenied from django.utils.translation import gettext as _ from functools import wraps from common.models import UserConfig from .models import ComplementaryPoliceRegulation def user_can_manage_regulations(user): """ Vérifie qu'un utilisateur peut gérer les règlements complémentaires de police. Nécessite un rôle 'admin' ou 'manager', ou la permission esign_can_manage_rcp. """ if not user or not user.is_authenticated: return False if user.is_superuser: return True try: user_config = UserConfig.objects.get(user=user) except UserConfig.DoesNotExist: return False # Admin et managers peuvent gérer les RCP, ou si permission spécifique esign_can_manage_rcp est active return ( user_config.esign_can_manage_rcp or user_config.roles.filter(name__in=['admin', 'manager']).exists() ) def user_can_view_regulation(user, regulation): """ Vérifie qu'un utilisateur peut visualiser un RCP. L'utilisateur doit disposer de la permission sur le gestionnaire de ce RCP, ou être superutilisateur. """ if not user or not user.is_authenticated: return False if user.is_superuser: return True try: user_config = UserConfig.objects.get(user=user) except UserConfig.DoesNotExist: return False if not regulation.organization: return False return user_config.esign_organizations.filter(id=regulation.organization.id).exists() def user_can_edit_regulation(user, regulation): """ Vérifie qu'un utilisateur peut éditer un RCP. L'édition n'est possible que si le RCP est en statut 'in_preparation', et si l'utilisateur a accès au gestionnaire de ce RCP. """ if not user_can_manage_regulations(user): return False if not user.is_superuser: try: user_config = UserConfig.objects.get(user=user) except UserConfig.DoesNotExist: return False if not regulation.organization or not user_config.esign_organizations.filter(id=regulation.organization.id).exists(): return False # Ne peut éditer que si le RCP est en préparation return regulation.status == 'in_preparation' def user_can_submit_regulation(user, regulation): """ Vérifie qu'un utilisateur peut soumettre un RCP pour approbation. Le RCP doit être en statut 'in_preparation', et l'utilisateur doit avoir accès au gestionnaire de ce RCP. """ if not user_can_manage_regulations(user): return False if not user.is_superuser: try: user_config = UserConfig.objects.get(user=user) except UserConfig.DoesNotExist: return False if not regulation.organization or not user_config.esign_organizations.filter(id=regulation.organization.id).exists(): return False # Peut soumettre que si le RCP est en préparation return regulation.status == 'in_preparation' def user_can_approve_regulation(user): """ Vérifie qu'un utilisateur peut approuver les RCP. Nécessite un rôle 'admin' ou la permission esign_can_validate_rcp. """ if not user or not user.is_authenticated: return False if user.is_superuser: return True try: user_config = UserConfig.objects.get(user=user) except UserConfig.DoesNotExist: return False return ( user_config.esign_can_validate_rcp or user_config.roles.filter(name='admin').exists() ) def user_can_edit_esign_assets(user): """ Vérifie qu'un utilisateur peut créer/modifier/déplacer des poteaux et des panneaux. L'utilisateur doit disposer de la permission esign_can_edit sur sa configuration, ou disposer des droits Django intégrés correspondants, ou être superutilisateur. """ if not user or not user.is_authenticated: return False if user.is_superuser: return True try: user_config = UserConfig.objects.get(user=user) except UserConfig.DoesNotExist: return False return ( user_config.esign_can_edit or user.has_perm('sign.change_signpole') or user.has_perm('sign.add_signpole') or user.has_perm('sign.change_signpanel') or user.has_perm('sign.add_signpanel') ) def regulation_management_required(view_func): """ Décorateur pour vérifier que l'utilisateur peut gérer les RCP. """ @wraps(view_func) def _wrapped_view(request, *args, **kwargs): if not user_can_manage_regulations(request.user): raise PermissionDenied(_("Vous n'avez pas la permission de gérer les règlements.")) return view_func(request, *args, **kwargs) return _wrapped_view