From 27c1d69ae83b22ed9068d045b434070b49e3a3a4 Mon Sep 17 00:00:00 2001 From: Louis Mazin Date: Tue, 15 Sep 2026 01:33:45 +0200 Subject: [PATCH] test --- .../commands/check_and_create_admin.py | 32 ------------------- backend/users/urls.py | 6 ++-- backend/users/views.py | 18 ++++++----- frontend/src/App.jsx | 10 +++--- frontend/src/components/AdminRoute.jsx | 26 +++++++++++++++ frontend/src/pages/AdminUsersPage.jsx | 6 +++- 6 files changed, 49 insertions(+), 49 deletions(-) delete mode 100644 backend/users/management/commands/check_and_create_admin.py create mode 100644 frontend/src/components/AdminRoute.jsx diff --git a/backend/users/management/commands/check_and_create_admin.py b/backend/users/management/commands/check_and_create_admin.py deleted file mode 100644 index 2fec55a..0000000 --- a/backend/users/management/commands/check_and_create_admin.py +++ /dev/null @@ -1,32 +0,0 @@ -from django.core.management.base import BaseCommand -from django.contrib.auth.models import User -from decouple import config -from django.db import transaction - -class Command(BaseCommand): - help = 'Check if any users exist and create admin if none exist' - - def handle(self, *args, **options): - # Check if any users exist - if User.objects.exists(): - self.stdout.write( - self.style.WARNING('Users already exist, skipping admin creation') - ) - return - - # Get credentials from environment variables or use defaults - username = config('ADMIN_USERNAME', default='admin') - password = config('ADMIN_PASSWORD', default='admin123') - email = config('ADMIN_EMAIL', default='admin@boulangerie.fr') - - # Create the admin user - with transaction.atomic(): - user = User.objects.create_superuser( - username=username, - email=email, - password=password - ) - - self.stdout.write( - self.style.SUCCESS(f'Successfully created admin user "{username}"') - ) \ No newline at end of file diff --git a/backend/users/urls.py b/backend/users/urls.py index 740465e..ae4810b 100644 --- a/backend/users/urls.py +++ b/backend/users/urls.py @@ -5,8 +5,8 @@ urlpatterns = [ path('register/', RegisterView.as_view(), name='register'), path('me/', UserMeView.as_view(), name='me'), path('', UserListView.as_view(), name='user-list'), - path('/', UserDetailView.as_view(), name='user-detail'), - path('/promote/', UserPromoteView.as_view(), name='user-promote'), - path('/delete/', UserDeleteView.as_view(), name='user-delete'), + path('/', UserDetailView.as_view(), name='user-detail'), + path('/promote/', UserPromoteView.as_view(), name='user-promote'), + path('/delete/', UserDeleteView.as_view(), name='user-delete'), path('invitations/', InvitationCreateView.as_view(), name='invitation-create'), ] diff --git a/backend/users/views.py b/backend/users/views.py index 6c1c471..9bd4dd5 100644 --- a/backend/users/views.py +++ b/backend/users/views.py @@ -35,6 +35,8 @@ class UserListView(generics.ListAPIView): 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): @@ -61,14 +63,14 @@ class UserDetailView(generics.RetrieveUpdateDestroyAPIView): class UserPromoteView(APIView): permission_classes = (IsAuthenticated,) - def post(self, request, user_id): + 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 = User.objects.get(id=user_id) - user.is_staff = True - user.save() + user_obj = User.objects.get(id=user) + 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) @@ -77,17 +79,17 @@ class UserPromoteView(APIView): class UserDeleteView(APIView): permission_classes = (IsAuthenticated,) - def delete(self, request, user_id): + def delete(self, request, user): if not (request.user.is_staff or request.user.is_superuser): raise PermissionDenied('Seuls les administrateurs peuvent supprimer des utilisateurs.') try: - user = User.objects.get(id=user_id) + user_obj = User.objects.get(id=user) # Ne pas permettre de supprimer l'utilisateur courant - if user == request.user: + if user_obj == request.user: return Response({'error': 'Vous ne pouvez pas supprimer votre propre compte'}, status=400) - user.delete() + user_obj.delete() return Response({'message': 'Utilisateur supprimé avec succès'}, status=200) except User.DoesNotExist: return Response({'error': 'Utilisateur non trouvé'}, status=404) diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 0b3fc29..cf75b62 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,7 +1,7 @@ import { Routes, Route, Navigate } from 'react-router-dom'; import LoginPage from './pages/LoginPage'; import HomePage from './pages/HomePage'; -import ProtectedRoute from './components/ProtectedRoute'; +import AdminRoute from './components/AdminRoute'; import Header from './components/Header'; import AdminUsersPage from './pages/AdminUsersPage'; import AdminInvitePage from './pages/AdminInvitePage'; @@ -31,14 +31,14 @@ function App() { } /> + - + } /> + - + } /> } /> diff --git a/frontend/src/components/AdminRoute.jsx b/frontend/src/components/AdminRoute.jsx new file mode 100644 index 0000000..82b0cf3 --- /dev/null +++ b/frontend/src/components/AdminRoute.jsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { Navigate, useLocation } from 'react-router-dom'; +import { useAuth } from '../context/AuthContext'; + +const AdminRoute = ({ children }) => { + const { user, loading, isAdmin } = useAuth(); + const location = useLocation(); + + if (loading) { + return
Loading...
; + } + + if (!user) { + // Redirect them to the /login page, but save the current location they were trying to go to. + return ; + } + + // If user is not admin, redirect to profile page + if (!isAdmin) { + return ; + } + + return children; +}; + +export default AdminRoute; \ No newline at end of file diff --git a/frontend/src/pages/AdminUsersPage.jsx b/frontend/src/pages/AdminUsersPage.jsx index f42f8a5..8339e43 100644 --- a/frontend/src/pages/AdminUsersPage.jsx +++ b/frontend/src/pages/AdminUsersPage.jsx @@ -41,10 +41,14 @@ const AdminUsersPage = () => { }; const handleMakeAdmin = async (userId) => { + if (!window.confirm('Êtes-vous sûr de vouloir promouvoir cet utilisateur ?')) { + return; + } + try { await userApi.promoteUser(userId); setUsers(users.map(user => - user.id === userId ? { ...user, is_staff: true } : user + user.id === userId ? { ...user, is_admin: true } : user )); } catch (err) { setError('Erreur lors de la promotion de l\'utilisateur');