"""Gedeelde permissies voor roltoegang en module-gating.""" from rest_framework.permissions import BasePermission, SAFE_METHODS def _profile(user): return getattr(user, "gebruikersprofiel", None) def user_role(user): profile = _profile(user) return getattr(profile, "rol", None) def linked_person(user): profile = _profile(user) return getattr(profile, "persoon", None) def is_admin_user(user): return bool( user and user.is_authenticated and (user.is_staff or user_role(user) == "beheerder") ) INTERNAL_READ_ROLES = { "medewerker", "roostermaker", "directie", "zorgcoordinator", "stagebegeleider", "kijker", } def has_view_write_role(user, view): write_roles = set(getattr(view, "write_roles", ())) return user_role(user) in write_roles class CoreDataPermission(BasePermission): """Kerngegevens: schrijven per rol, lezen rolbewust.""" message = "Je hebt geen rechten voor deze roostergegevens." def has_permission(self, request, view): if not request.user or not request.user.is_authenticated: return False if is_admin_user(request.user): return True if request.method in SAFE_METHODS: return True return has_view_write_role(request.user, view) def has_object_permission(self, request, view, obj): if is_admin_user(request.user): return True if request.method not in SAFE_METHODS: return has_view_write_role(request.user, view) role = user_role(request.user) person = linked_person(request.user) if role in ("leerling", "ouder") and person is not None: if obj.__class__.__name__ == "Persoon": return obj.pk == person.pk if hasattr(obj, "persoon_id"): return obj.persoon_id == person.pk return role in INTERNAL_READ_ROLES class StaffDataPermission(BasePermission): """Rapportages: interne rollen mogen lezen, beheerders/rolhouders schrijven.""" message = "Je hebt geen rechten voor deze rapportage." def has_permission(self, request, view): if not request.user or not request.user.is_authenticated: return False if is_admin_user(request.user): return True if request.method in SAFE_METHODS: return user_role(request.user) in INTERNAL_READ_ROLES return has_view_write_role(request.user, view) class AdminRolePermission(BasePermission): """Beheerder via Django staff of via de applicatierol beheerder.""" message = "Je hebt beheerdersrechten nodig." def has_permission(self, request, view): return is_admin_user(request.user) def restrict_core_queryset(request, queryset): """Filter gevoelige lijsten voor leerling/ouderaccounts met gekoppelde persoon.""" user = request.user if is_admin_user(user) or user_role(user) in INTERNAL_READ_ROLES: return queryset person = linked_person(user) if person is None: return queryset.none() model_name = queryset.model.__name__ if model_name == "Groep": return queryset.filter(pk=person.groep_id) if getattr(person, "groep_id", None) else queryset.none() if model_name == "Subgroep": return queryset.filter(leden=person).distinct() if model_name == "Persoon": return queryset.filter(pk=person.pk) if model_name == "Afwezigheid": return queryset.filter(persoon=person) if model_name == "Roosterblok": qs = queryset.filter(leerling=person) if getattr(person, "groep_id", None): qs = qs | queryset.filter(groep_id=person.groep_id) qs = qs | queryset.filter(subgroep__leden=person) return qs.distinct() if model_name == "BlokUitzondering": qs = queryset.filter(roosterblok__leerling=person) if getattr(person, "groep_id", None): qs = qs | queryset.filter(roosterblok__groep_id=person.groep_id) qs = qs | queryset.filter(roosterblok__subgroep__leden=person) return qs.distinct() return queryset def module_permission_class(module_key): """Maak een DRF-permissieklasse die een module-aan/uit vlag afdwingt.""" class IsModuleEnabled(BasePermission): message = f"Module '{module_key}' is uitgeschakeld." def has_permission(self, request, view): from plugins import services return services.is_enabled(module_key) IsModuleEnabled.__name__ = f"IsModuleEnabled_{module_key}" return IsModuleEnabled