diff --git a/backend/common/tests.py b/backend/common/tests.py index a7516ca..fa567d3 100644 --- a/backend/common/tests.py +++ b/backend/common/tests.py @@ -1,7 +1,8 @@ """Régressions des droits admin. Lancer avec : python manage.py test common.""" +from django.conf import settings from django.contrib.auth import get_user_model from django.test import Client, TestCase -from django.urls import reverse +from django.urls import Resolver404, resolve, reverse class AdminApiTests(TestCase): @@ -52,3 +53,13 @@ class AdminApiTests(TestCase): response = self.client.post(reverse("auth-login"), data='{"username":"member", "password":"TestPassword2026!"}', content_type="application/json") self.assertEqual(response.status_code, 403) self.assertNotIn("_auth_user_id", self.client.session) + + +class NoDjangoAdminTests(TestCase): + def test_native_django_admin_is_absent(self): + self.assertNotIn("django.contrib.admin", settings.INSTALLED_APPS) + with self.assertRaises(Resolver404): + resolve("/django-admin/") + + def test_custom_admin_api_still_exists(self): + self.assertEqual(reverse("admin-dashboard"), "/api/admin/dashboard/") diff --git a/backend/core/settings.py b/backend/core/settings.py index 776c35e..479124b 100644 --- a/backend/core/settings.py +++ b/backend/core/settings.py @@ -28,11 +28,10 @@ _csrf_backend = effective_origins( auto_port=config("AUTO_PORT_CSRF", default=True, cast=bool), ) # Ajoute également l'origine du frontend : nécessaire aux requêtes CSRF -# de l'interface (par exemple lorsque Django Admin est exposé via le proxy). +# du tableau de bord React utilisant les sessions Django. CSRF_TRUSTED_ORIGINS = list(dict.fromkeys([*_csrf_backend, *CORS_ALLOWED_ORIGINS])) INSTALLED_APPS = [ - "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", diff --git a/backend/core/urls.py b/backend/core/urls.py index 71a4969..2fd32dd 100644 --- a/backend/core/urls.py +++ b/backend/core/urls.py @@ -1,13 +1,7 @@ -from django.contrib import admin from django.urls import include, path -admin.site.site_header = "Administration avancée" -admin.site.site_title = "Administration Django" -admin.site.index_title = "Gestion technique" - +# L'administration est une interface React (/admin/) servie par le frontend. +# Le backend n'expose que l'API, y compris les routes administrateur sécurisées. urlpatterns = [ - # /admin/ est le tableau de bord React basé sur shadcn/ui. - # Django Admin reste accessible pour les fonctions avancées. - path("django-admin/", admin.site.urls), path("api/", include("common.urls")), ] diff --git a/frontend/nginx.conf b/frontend/nginx.conf index 4f65a60..dd23168 100644 --- a/frontend/nginx.conf +++ b/frontend/nginx.conf @@ -12,13 +12,6 @@ server { proxy_set_header X-Forwarded-Proto $scheme; } - location /django-admin/ { - proxy_pass http://backend:8000; - proxy_set_header Host $http_host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } - location /static/ { proxy_pass http://backend:8000; proxy_set_header Host $http_host; diff --git a/frontend/src/pages/AdminPage.jsx b/frontend/src/pages/AdminPage.jsx index 403883f..44d3b4e 100644 --- a/frontend/src/pages/AdminPage.jsx +++ b/frontend/src/pages/AdminPage.jsx @@ -1,5 +1,5 @@ import { useCallback, useEffect, useMemo, useState } from "react" -import { Activity, ArrowUpRight, Database, LayoutDashboard, LogOut, RefreshCw, Search, ShieldCheck, Users } from "lucide-react" +import { Activity, LayoutDashboard, LogOut, RefreshCw, Search, ShieldCheck, Users } from "lucide-react" import { AppShell } from "@/components/layout/AppShell" import { LoginForm } from "@/components/admin/LoginForm" import { CreateUserDialog } from "@/components/admin/CreateUserDialog" @@ -118,7 +118,6 @@ export default function AdminPage() {
Administration Django avancée
Groupes, permissions et modèles Django
Docker Compose, Django REST Framework, React avec shadcn/ui, MySQL 8 et Oxlint. Une architecture modulaire, prête à être personnalisée.