roosterwijs/backend/core/views.py

210 lines
6.7 KiB
Python

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