import logging from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout from django.views.decorators.csrf import ensure_csrf_cookie from rest_framework import status, viewsets from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import AllowAny from rest_framework.response import Response from plugins import services from .models import ( Activiteit, Afwezigheid, BlokUitzondering, Functie, Groep, KalenderDag, Locatie, Persoon, Roosterblok, Schooljaar, Subgroep, Tijdslot, ) from .serializers import ( ActiviteitSerializer, AfwezigheidSerializer, BlokUitzonderingSerializer, FunctieSerializer, GroepSerializer, KalenderDagSerializer, LocatieSerializer, PersoonSerializer, RoosterblokSerializer, SchooljaarSerializer, SubgroepSerializer, TijdslotSerializer, ) logger = logging.getLogger("roosterwijs.auth") @api_view(["GET"]) @permission_classes([AllowAny]) def health(request): """Anonieme gezondheidscheck: bewust zonder inhoudelijke informatie.""" return Response({"naam": "Roosterwijs", "status": "ok"}) @api_view(["GET"]) def info(request): """Systeeminfo + welke modules actief zijn (alleen voor ingelogde gebruikers).""" services.sync_states() modules = services.describe_all() return Response( { "naam": "Roosterwijs", "fase": "1 - kerndomein (personen, groepen, subgroepen)", "modules_totaal": len(modules), "modules_actief": sum(1 for m in modules if m["enabled"]), } ) # --- Authenticatie ---------------------------------------------------------- def _user_payload(user): return { "authenticated": True, "username": user.get_username(), "is_staff": user.is_staff, } @api_view(["GET"]) @permission_classes([AllowAny]) @ensure_csrf_cookie def auth_me(request): """Wie ben ik? Zet tegelijk de CSRF-cookie voor de frontend.""" if request.user.is_authenticated: return Response(_user_payload(request.user)) return Response({"authenticated": False}) @api_view(["POST"]) @permission_classes([AllowAny]) def auth_login_view(request): """Inloggen met gebruikersnaam + wachtwoord (sessie-cookie).""" username = str(request.data.get("username", "")).strip() password = str(request.data.get("password", "")) if not username or not password: return Response( {"detail": "Vul gebruikersnaam en wachtwoord in."}, status=status.HTTP_400_BAD_REQUEST, ) user = authenticate(request, username=username, password=password) if user is None: logger.warning("Mislukte inlogpoging voor gebruiker %r", username) return Response( {"detail": "Onjuiste gebruikersnaam of wachtwoord."}, status=status.HTTP_401_UNAUTHORIZED, ) auth_login(request, user) logger.info("Gebruiker %r ingelogd", username) return Response(_user_payload(user)) @api_view(["POST"]) def auth_logout_view(request): """Uitloggen: sessie beƫindigen.""" logger.info("Gebruiker %r uitgelogd", request.user.get_username()) auth_logout(request) return Response({"authenticated": False}) class GroepViewSet(viewsets.ModelViewSet): queryset = Groep.objects.all() serializer_class = GroepSerializer class PersoonViewSet(viewsets.ModelViewSet): serializer_class = PersoonSerializer def get_queryset(self): qs = Persoon.objects.select_related("groep").prefetch_related("functies").all() rol = self.request.query_params.get("rol") if rol: qs = qs.filter(rol=rol) return qs class SubgroepViewSet(viewsets.ModelViewSet): queryset = Subgroep.objects.prefetch_related("leden").all() serializer_class = SubgroepSerializer class FunctieViewSet(viewsets.ModelViewSet): queryset = Functie.objects.all() serializer_class = FunctieSerializer # --- Fase 2 --------------------------------------------------------------- class SchooljaarViewSet(viewsets.ModelViewSet): queryset = Schooljaar.objects.all() serializer_class = SchooljaarSerializer class KalenderDagViewSet(viewsets.ModelViewSet): serializer_class = KalenderDagSerializer def get_queryset(self): qs = KalenderDag.objects.all() schooljaar = self.request.query_params.get("schooljaar") if schooljaar: qs = qs.filter(schooljaar_id=schooljaar) return qs class TijdslotViewSet(viewsets.ModelViewSet): queryset = Tijdslot.objects.all() serializer_class = TijdslotSerializer class ActiviteitViewSet(viewsets.ModelViewSet): queryset = Activiteit.objects.all() serializer_class = ActiviteitSerializer class LocatieViewSet(viewsets.ModelViewSet): queryset = Locatie.objects.all() serializer_class = LocatieSerializer class RoosterblokViewSet(viewsets.ModelViewSet): serializer_class = RoosterblokSerializer def get_queryset(self): qs = ( Roosterblok.objects .select_related("tijdslot", "activiteit", "locatie", "groep", "subgroep", "leerling") .prefetch_related("begeleiders") .all() ) for veld in ("schooljaar", "groep", "subgroep", "leerling"): waarde = self.request.query_params.get(veld) if waarde: qs = qs.filter(**{f"{veld}_id": waarde}) return qs class AfwezigheidViewSet(viewsets.ModelViewSet): serializer_class = AfwezigheidSerializer def get_queryset(self): qs = Afwezigheid.objects.select_related("persoon").all() persoon = self.request.query_params.get("persoon") if persoon: qs = qs.filter(persoon_id=persoon) # Overlap met een periode [van, tot]: start <= tot EN eind >= van. van = self.request.query_params.get("van") tot = self.request.query_params.get("tot") if van: qs = qs.filter(eind_datum__gte=van) if tot: qs = qs.filter(start_datum__lte=tot) return qs class BlokUitzonderingViewSet(viewsets.ModelViewSet): serializer_class = BlokUitzonderingSerializer def get_queryset(self): qs = BlokUitzondering.objects.select_related("vervanger", "roosterblok").all() blok = self.request.query_params.get("roosterblok") if blok: qs = qs.filter(roosterblok_id=blok) van = self.request.query_params.get("van") tot = self.request.query_params.get("tot") if van: qs = qs.filter(datum__gte=van) if tot: qs = qs.filter(datum__lte=tot) schooljaar = self.request.query_params.get("schooljaar") if schooljaar: qs = qs.filter(roosterblok__schooljaar_id=schooljaar) return qs