diff --git a/CLAUDE.md b/CLAUDE.md index 529dd4c..c2acfe0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -15,17 +15,33 @@ Outil d'audit infrastructure et sécurité pour clients MSP. Permet de lancer de ## Structure ``` frontend/ - app/ # Next.js App Router - components/ # Composants réutilisables - lib/ # Utilitaires, API client + app/ + (auth)/login/ # Page login (pas de layout dashboard) + (dashboard)/ # Pages protégées avec sidebar + layout.tsx # Guard auth + layout sidebar+main + dashboard/ # Stats globales + clients/ # CRUD clients + audits/ # CRUD audits + components/ + layout/ # Sidebar, Header + ui/ # shadcn/ui : Button, Card, Input, Badge, Label + lib/ + api.ts # Client fetch typé (authApi, clientsApi, auditsApi) + auth.ts # Helpers JWT localStorage + utils.ts # cn() (tailwind-merge + clsx) backend/ - api/ # Routes FastAPI - scanners/ # Orchestration Nmap, OpenVAS, Metasploit, AD - models/ # Modèles SQLAlchemy - reports/ # Génération PDF + api/ # Routes FastAPI (auth, clients, audits) + core/ # config.py, database.py, security.py + models/ # SQLAlchemy ORM (base.py + TimestampMixin) + schemas/ # Pydantic v2 (séparés des modèles) + scanners/ # Placeholder Phase 2 (Nmap, OpenVAS...) + reports/ # Placeholder Phase 4 (WeasyPrint PDF) + tests/ # pytest async avec SQLite in-memory + alembic/ # Migrations (env.py configuré) + main.py # App FastAPI : CORS, rate limiting, routers docker/ - docker-compose.yml - docker-compose.prod.yml + docker-compose.yml # Dev : postgres, redis, backend, frontend + docker-compose.prod.yml # Prod : images registry + labels Traefik ``` ## Commandes @@ -33,17 +49,23 @@ docker/ # Frontend cd frontend && npm install && npm run dev -# Backend -cd backend && pip install -r requirements.txt && uvicorn main:app --reload +# Backend (lancer depuis la racine du projet, pas depuis backend/) +pip install -r backend/requirements.txt +uvicorn backend.main:app --reload # Docker complet docker compose -f docker/docker-compose.yml up -d -# Migrations BDD -cd backend && alembic upgrade head +# Migrations BDD (depuis la racine, pas depuis backend/) +alembic -c backend/alembic.ini upgrade head +# Créer une migration : +alembic -c backend/alembic.ini revision --autogenerate -m "description" # Tests pytest backend/tests/ + +# Typecheck frontend +cd frontend && npm run typecheck ``` ## Modèle de données @@ -77,8 +99,49 @@ Gitea Actions → Docker → NAS ou VPS selon le client Voir @docker/docker-compose.yml et @.gitea/workflows/deploy.yml ## Ce que Claude doit savoir sur CE projet + +### Domaine métier - Les scans sont des opérations longues → utiliser des jobs asynchrones (Celery ou BackgroundTasks FastAPI) - Le rapport PDF doit être compréhensible par un dirigeant non-technique - Toujours traduire les CVE en langage clair dans les rapports - La BDD utilise snake_case, le frontend TypeScript utilise camelCase -- Les criticités : critique (CVSS 9-10), important (7-8.9), modéré (4-6.9), faible (0-3.9) \ No newline at end of file +- Les criticités : critique (CVSS 9-10), important (7-8.9), modéré (4-6.9), faible (0-3.9) +- Un scan ne peut se lancer que sur des cibles dont `validee = True` (sécurité obligatoire) + +### Conventions de code établies en Phase 1 + +**Backend :** +- Imports toujours en `backend.xxx` (ex: `from backend.models.user import User`), jamais en relatif — le module s'appelle `backend` +- Uvicorn se lance avec `uvicorn backend.main:app`, pas `uvicorn main:app` +- Alembic se lance depuis la racine avec `-c backend/alembic.ini` +- Les enums Python sont aussi `str` (`class Criticite(str, enum.Enum)`) pour sérialisation JSON automatique +- Pydantic v2 : utiliser `model_dump()` (pas `.dict()`), `model_config = {"from_attributes": True}` (pas `orm_mode`) +- Pattern PATCH : `payload.model_dump(exclude_unset=True)` pour ne pas écraser les champs non fournis +- `get_current_user` est une dépendance FastAPI — toujours l'injecter sur les routes protégées +- `selectinload()` pour les relations dans les endpoints "detail" (évite le N+1) +- `TimestampMixin` à hériter sur tous les nouveaux modèles +- `pool_pre_ping=True` sur l'engine SQLAlchemy pour les connexions longues durée + +**Frontend :** +- Les types TypeScript sont en camelCase même si l'API renvoie du snake_case (mapping à faire côté fetch) +- `"use client"` obligatoire sur toutes les pages/composants utilisant des hooks React ou des effets +- Guard auth dans `(dashboard)/layout.tsx` via `useEffect` + `getToken()` — pas de middleware Next.js +- Le client API (`lib/api.ts`) passe toujours le token en paramètre explicite — pas de contexte global +- Les nouvelles pages du dashboard vont dans `app/(dashboard)/[section]/page.tsx` +- Les nouveaux composants UI shadcn vont dans `components/ui/`, les composants métier dans `components/` +- Les rewrites `next.config.ts` proxifient `/api/*` vers le backend — en dev, définir `NEXT_PUBLIC_API_URL=http://localhost:8000` +- JWT stocké dans localStorage (simple pour MVP, à migrer vers HttpOnly cookie plus tard) + +**Infrastructure :** +- Le service `backend` dans docker-compose dépend de `postgres` avec `condition: service_healthy` +- Le build frontend Next.js utilise `output: "standalone"` → le Dockerfile copie `.next/standalone` +- Les variables d'env préfixées `NEXT_PUBLIC_` sont embarquées au build (pas au runtime) +- `docker-compose.prod.yml` attend des images pré-buildées depuis `${REGISTRY}` — pas de build local + +### Pièges à éviter +- Ne pas lancer `uvicorn main:app` depuis `backend/` — toujours depuis la racine avec le module complet +- Ne pas oublier `"use client"` sur les pages avec `useEffect`, `useState`, `useRouter` +- Ne pas utiliser `.dict()` Pydantic v1 — c'est `.model_dump()` en v2 +- Ne pas faire de scans sans vérifier `cible.validee == True` côté backend +- Ne pas commiter `.env` — seulement `.env.example` +- Alembic `env.py` importe les modèles depuis `backend.models` — ajouter tout nouveau modèle dans `backend/models/__init__.py` \ No newline at end of file diff --git a/plan.md b/plan.md new file mode 100644 index 0000000..084e530 --- /dev/null +++ b/plan.md @@ -0,0 +1,211 @@ +# AuditShield — Plan de développement + +## Vue d'ensemble + +Outil d'audit infrastructure et sécurité pour clients MSP. +Scans réseau + vulnérabilités + pentest → rapports PDF compréhensibles pour non-techniciens. + +--- + +## ✅ Phase 1 — Socle (terminée) + +> Branche : `feature/phase-1-socle` → mergée dans `dev` + +### Ce qui a été créé + +**Backend (FastAPI + SQLAlchemy)** +- `backend/core/` — config (pydantic-settings), database (SQLAlchemy 2.0), security (JWT + bcrypt) +- `backend/models/` — 7 modèles : User, Client, Audit, Cible, Vulnérabilité, Action + TimestampMixin +- `backend/schemas/` — Pydantic v2 : UserCreate/Read, ClientCreate/Update/Read, AuditCreate/Update/Read/Detail, CibleCreate/Read, VulnerabiliteCreate/Read, ActionCreate/Update/Read +- `backend/api/auth.py` — POST /register, POST /login (OAuth2), GET /me +- `backend/api/clients.py` — CRUD complet (GET list, POST, GET/{id}, PATCH/{id}, DELETE/{id}) +- `backend/api/audits.py` — CRUD audit + nested : cibles (add/valider), vulnérabilités (add), actions (add/update) +- `backend/main.py` — FastAPI app, CORS (localhost:3000), rate limiting (slowapi), docs /api/docs en DEBUG +- `backend/alembic/` — migrations configurées (env.py prêt avec models importés) +- `backend/tests/test_auth.py` — test async register + login avec SQLite in-memory + +**Frontend (Next.js 14 App Router)** +- Route groups : `(auth)` pour login, `(dashboard)` pour pages protégées +- `app/(auth)/login/page.tsx` — formulaire login avec gestion JWT +- `app/(dashboard)/layout.tsx` — guard auth (redirect /login), layout sidebar + main +- `app/(dashboard)/dashboard/page.tsx` — 4 stat cards + 5 audits récents +- `app/(dashboard)/clients/page.tsx` — grille clients avec recherche +- `app/(dashboard)/audits/page.tsx` — liste audits avec badges statut + recherche +- `components/layout/sidebar.tsx` — navigation (Dashboard, Clients, Audits) + déconnexion +- `components/ui/` — Button (CVA variants), Card, Input, Label, Badge (+ variantes criticité) +- `lib/api.ts` — client fetch générique typé : authApi, clientsApi, auditsApi +- `lib/auth.ts` — helpers localStorage pour token JWT + +**Infrastructure** +- `docker/docker-compose.yml` — 4 services : postgres:16, redis:7, backend, frontend +- `docker/docker-compose.prod.yml` — images registry + labels Traefik + Let's Encrypt +- `backend/Dockerfile` — Python 3.11-slim + WeasyPrint deps + alembic upgrade +- `frontend/Dockerfile` — multi-stage Node 20 (deps → builder → runner standalone) +- `.env.example` — toutes les variables documentées + +### Décisions techniques + +| Décision | Raison | +|----------|--------| +| SQLAlchemy 2.0 avec type hints Mapped[] | API moderne, meilleure inference TypeScript équivalente côté Python | +| Pydantic v2 séparé des modèles ORM | Découplage validation/persistance, évite circular imports | +| JWT HS256 + 24h expiration | Simple à implémenter, stateless, suffisant pour MVP | +| slowapi pour rate limiting | Compatible FastAPI/Starlette, minimal | +| TimestampMixin | DRY pour created_at/updated_at sur tous les modèles | +| Cascade delete | Intégrité référentielle (supprimer client → supprime tout) | +| Celery + Redis (infra seulement) | Prêt pour les jobs asynchrones de scan (Phase 2) | +| Next.js App Router + route groups | Layouts différents auth/dashboard sans duplication | +| shadcn/ui + Radix | Accessibilité, composants non-opinionnés, facilement personnalisables | +| JWT dans localStorage | Simple pour MVP — à migrer vers HttpOnly cookie en Phase 3 | +| camelCase pour types TS, snake_case en DB | Convention JS vs convention Python/SQL | +| Rewrites next.config.ts vers backend | Pas de CORS en prod, tout passe par Next.js | + +### État fonctionnel +- ✅ Register/Login utilisateur avec JWT +- ✅ CRUD clients complet +- ✅ CRUD audits + cibles + vulnérabilités + actions +- ✅ Dashboard avec stats temps réel +- ✅ Pages liste clients et audits avec recherche +- ✅ Guard auth côté frontend +- ✅ Docker dev + prod prêt +- ⏳ Pages de formulaire (création/édition) non créées +- ⏳ Pages détail client et audit non créées +- ⏳ Scanners : dossier vide (placeholder Phase 2) +- ⏳ Génération PDF : dossier vide (placeholder Phase 4) + +--- + +## 🔲 Phase 2 — Scanners réseau (Nmap) + +> Branche : `feature/phase-2-nmap` + +### Objectif +Permettre le lancement d'un scan Nmap sur des cibles validées, afficher les résultats en temps réel, et les persister en base. + +### Tâches backend + +- [ ] **Celery worker** — configurer `backend/celery_app.py`, worker Docker dans docker-compose +- [ ] **Scanner Nmap** — `backend/scanners/nmap.py` + - Wrapper autour de `python-nmap` + - Parse les résultats : ports ouverts, services, OS + - Vérification que la cible est `validee = True` avant tout scan + - Log de chaque scan en BDD (model `ScanLog`) +- [ ] **Model ScanLog** — `backend/models/scan_log.py` + - audit_id, cible_id, type_scan, statut, résultat (JSON), durée +- [ ] **Tâche Celery** — `backend/scanners/tasks.py` + - `task_scan_nmap(audit_id, cible_ids)` — async, met à jour statut + - Retour des résultats via polling ou WebSocket +- [ ] **Routes scan** — `backend/api/scans.py` + - `POST /audits/{audit_id}/scans/nmap` — lance le scan (en background) + - `GET /audits/{audit_id}/scans` — liste les scans passés + - `GET /audits/{audit_id}/scans/{scan_id}` — détail d'un scan +- [ ] **Parsing Nmap → Vulnérabilités** — déduire des vulnérabilités simples (ports dangereux, services obsolètes) + +### Tâches frontend + +- [ ] **Page détail audit** — `app/(dashboard)/audits/[id]/page.tsx` + - Affiche : infos audit, liste cibles (avec bouton "Valider"), liste vulnérabilités, liste actions + - Bouton "Lancer un scan Nmap" + - Statut du scan en temps réel (polling GET /scans) +- [ ] **Page détail client** — `app/(dashboard)/clients/[id]/page.tsx` + - Infos client + liste des audits du client + - Bouton "Nouvel audit" +- [ ] **Formulaire nouveau client** — `app/(dashboard)/clients/nouveau/page.tsx` +- [ ] **Formulaire nouvel audit** — `app/(dashboard)/audits/nouveau/page.tsx` +- [ ] **Formulaire ajout cible** — Modal ou inline dans détail audit +- [ ] **Composant ScanStatus** — affiche statut scan (en cours / terminé / erreur) +- [ ] **Toast notifications** — feedback utilisateur (succès, erreur) + +### Tâches infra + +- [ ] Ajouter service `worker` dans docker-compose (image backend + command: celery worker) +- [ ] Ajouter `python-nmap` dans requirements.txt +- [ ] Première migration Alembic : `alembic revision --autogenerate -m "init"` + +--- + +## 🔲 Phase 3 — Vulnérabilités avancées + Actions + +> Branche : `feature/phase-3-vulnerabilites` + +### Objectif +Enrichissement des vulnérabilités avec CVE, scoring CVSS automatique, workflow de gestion des actions, et calcul du score global d'audit. + +### Tâches backend + +- [ ] **Intégration CVE/NVD** — `backend/scanners/cve.py` + - Lookup CVE via NVD API (gratuit) + - Traduction automatique en langage clair (résumé simplifié) + - Auto-remplissage criticité depuis CVSS score +- [ ] **Calcul score global audit** — méthode sur le model Audit + - Pondération : critique × 4, important × 3, modéré × 2, faible × 1 + - Normalisé sur 10, mis à jour à chaque vulnérabilité ajoutée +- [ ] **OpenVAS optionnel** — `backend/scanners/openvas.py` + - Wrapper GVM (Greenbone Vulnerability Management) + - Si disponible, scan plus profond +- [ ] **Notifications** — model `Notification`, endpoint SSE ou WebSocket + - Alertes nouvelles vulnérabilités critiques + - Changements de statut d'action + +### Tâches frontend + +- [ ] **Page détail vulnérabilité** — `app/(dashboard)/audits/[id]/vulnerabilites/[vulnId]/page.tsx` + - Affiche : titre, criticité (badge coloré), CVE, CVSS, description, recommandation + - Liste des actions liées + bouton "Ajouter une action" + - Formulaire d'action inline +- [ ] **Composant CriticiteBar** — représentation visuelle du score global +- [ ] **Page gestion des actions** — tableau kanban simple (Ouvert → En cours → Résolu) +- [ ] **Filtres et tri** — sur les listes de vulnérabilités (par criticité, statut) +- [ ] **Pagination** — composant `` réutilisable + +--- + +## 🔲 Phase 4 — Rapports PDF + Dashboard avancé + +> Branche : `feature/phase-4-rapports` + +### Objectif +Génération de rapports PDF professionnels compréhensibles par un dirigeant non-technique, et dashboard enrichi avec graphiques. + +### Tâches backend + +- [ ] **Moteur PDF** — `backend/reports/pdf.py` + - WeasyPrint + Jinja2 templates HTML + - Template rapport : page de garde, résumé exécutif, score global, vulnérabilités par criticité, recommandations, plan d'actions + - Langage client : pas de jargon technique, CVE traduits en langage clair +- [ ] **Templates HTML** — `backend/reports/templates/` + - `rapport_audit.html` — template principal + - `_vulnerabilite.html` — bloc par vulnérabilité + - CSS intégré (compatible WeasyPrint) +- [ ] **Route export** — `GET /audits/{audit_id}/rapport.pdf` + - Génère et streame le PDF + - Header `Content-Disposition: attachment` +- [ ] **Tâche Celery** — génération PDF asynchrone pour audits longs + +### Tâches frontend + +- [ ] **Bouton "Exporter PDF"** — dans la page détail audit +- [ ] **Dashboard avancé** — graphiques : + - Répartition vulnérabilités par criticité (donut chart) + - Évolution des audits dans le temps (line chart) + - Taux de résolution des actions (progress bar) + - Utiliser `recharts` ou `chart.js` +- [ ] **Page rapports** — `app/(dashboard)/rapports/page.tsx` + - Liste des rapports générés, téléchargement +- [ ] **Mode impression** — CSS @media print pour la page détail audit + +--- + +## Prochaine étape + +```bash +git checkout dev +git checkout -b feature/phase-2-nmap +``` + +Commencer par : +1. Configurer Celery dans `docker-compose.yml` (service worker) +2. Créer `backend/models/scan_log.py` +3. Créer `backend/scanners/nmap.py` +4. Générer la première migration Alembic +5. Créer les pages frontend manquantes (détail audit, formulaires)