Louis Mazin 707d70888b test
2026-09-25 10:31:29 +02:00

130 lines
4.8 KiB
Python

from rest_framework import generics
from rest_framework.response import Response
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.views import APIView
from rest_framework.exceptions import PermissionDenied, ValidationError
from django.utils import timezone
from datetime import timedelta
from .models import Invitation, User
from .serializers import UserSerializer, RegisterSerializer
from django.contrib.auth import password_validation
class RegisterView(generics.CreateAPIView):
queryset = User.objects.all()
permission_classes = (AllowAny,)
serializer_class = RegisterSerializer
class UserMeView(generics.RetrieveAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = UserSerializer
def get_object(self):
return self.request.user
class UserListView(generics.ListAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = UserSerializer
def get_queryset(self):
if not (self.request.user.is_staff or self.request.user.is_superuser):
raise PermissionDenied('Seuls les administrateurs peuvent consulter les comptes.')
return User.objects.order_by('-date_joined')
class UserDetailView(generics.RetrieveUpdateDestroyAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = UserSerializer
lookup_field = 'id'
lookup_url_kwarg = 'user'
def get_queryset(self):
if not (self.request.user.is_staff or self.request.user.is_superuser):
raise PermissionDenied('Seuls les administrateurs peuvent modifier les comptes.')
return User.objects.all()
def update(self, request, *args, **kwargs):
if not (request.user.is_staff or request.user.is_superuser):
raise PermissionDenied('Seuls les administrateurs peuvent modifier les comptes.')
return super().update(request, *args, **kwargs)
def perform_destroy(self, instance):
if instance.pk == self.request.user.pk:
raise ValidationError({'error': 'Vous ne pouvez pas supprimer votre propre compte.'})
if instance.is_superuser and not self.request.user.is_superuser:
raise PermissionDenied('Seul un superutilisateur peut supprimer ce compte.')
instance.delete()
class UserPromoteView(APIView):
permission_classes = (IsAuthenticated,)
def post(self, request, user):
if not (request.user.is_staff or request.user.is_superuser):
raise PermissionDenied('Seuls les administrateurs peuvent promouvoir des utilisateurs.')
try:
user_obj = User.objects.get(id=user)
if user_obj.is_superuser and not request.user.is_superuser:
raise PermissionDenied('Seul un superutilisateur peut modifier ce compte.')
user_obj.is_staff = True
user_obj.save()
return Response({'message': 'Utilisateur promu avec succès'}, status=200)
except User.DoesNotExist:
return Response({'error': 'Utilisateur non trouvé'}, status=404)
class ChangePasswordView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
current_password = request.data.get("current_password", "")
new_password = request.data.get("new_password", "")
confirm_password = request.data.get("confirm_password", "")
if not request.user.check_password(current_password):
return Response(
{"current_password": ["Mot de passe actuel incorrect."]},
status=400,
)
if new_password != confirm_password:
return Response(
{"confirm_password": ["Les mots de passe ne correspondent pas."]},
status=400,
)
try:
password_validation.validate_password(
new_password,
user=request.user,
)
except ValidationError as error:
return Response(
{"new_password": error.messages},
status=400,
)
request.user.set_password(new_password)
request.user.save(update_fields=["password"])
return Response({"detail": "Mot de passe modifié."})
class UserDeleteView(UserDetailView):
http_method_names = ['delete', 'options']
class InvitationCreateView(APIView):
permission_classes = (IsAuthenticated,)
def post(self, request):
if not (request.user.is_staff or request.user.is_superuser):
raise PermissionDenied('Seuls les administrateurs peuvent créer une invitation.')
invitation = Invitation.objects.create(
created_by=request.user,
expires_at=timezone.now() + timedelta(days=7),
)
return Response({
'token': str(invitation.token),
'expires_at': invitation.expires_at,
}, status=201)