Sécurisation de certains endpoint (à continuer)

This commit is contained in:
Erwann PHILIPPE 2026-09-20 15:21:31 +02:00
parent cd00395039
commit b367735351
3 changed files with 62 additions and 15 deletions

37
CHANGELOG.md Normal file
View file

@ -0,0 +1,37 @@
# 📝 Changelog
Toutes les modifications notables apportées à ce projet sont documentées dans ce fichier.
Le format est basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/) et ce projet adhère au [Semantic Versioning](https://semver.org/lang/fr/).
---
## [1.1.0] - 2026-09-20
### 🔒 Sécurité
- **Privatisation de l'endpoint `GET /cars`** :
- L'accès à la liste complète des véhicules du parc automobile est désormais strictement restreint aux utilisateurs ayant le rôle `admin`.
- Une requête non authentifiée reçoit une réponse HTTP `401 Unauthorized`.
- Une requête authentifiée avec un compte utilisateur standard (`user`) reçoit une réponse HTTP `403 Forbidden`.
- **Privatisation de l'endpoint `GET /cars/immatriculation/{immatriculation}`** :
- La recherche et l'identification de véhicule par plaque d'immatriculation sont désormais réservées exclusivement aux utilisateurs ayant le rôle `admin`.
- Contrôle d'accès identique : code `401` si aucun jeton n'est fourni, code `403` si l'utilisateur n'a pas les privilèges `admin`.
- **Sécurisation des points d'accès annexes liés à l'immatriculation** :
- Sécurisation de l'alias direct `GET /immatriculation/{immatriculation}` (exige le rôle `admin` pour prévenir tout contournement de sécurité).
- Sécurisation du filtre `GET /cars?immatriculation=...` désormais protégé au même titre que `GET /cars`.
### 🔄 Modifié
- **Séparation des droits de consultation** :
- Les utilisateurs standards (`role: user`) doivent dorénavant utiliser le point d'accès dédié `GET /cars/mes-voitures` (ou `GET /cars?mine=true` réservé admin) pour consulter la liste de leurs propres véhicules.
- La documentation interactive exposée à la racine (`GET /`) a été mise à jour avec les nouveaux tags de droits `[ADMIN]`.
- Le fichier [`README.md`](./README.md) a été actualisé (tableaux d'accès, permissions et exemples cURL intégrant le jeton `admin`).
---
## [1.0.0] - 2026-09-16
### ✨ Initialisation
- Création de l'API REST Voitures en PHP / MySQL.
- Authentification par jeton Bearer (`users`, login, register, me, logout).
- Liaison des véhicules avec leurs propriétaires (`user_id`).
- Gestion des relevés kilométriques, historiques d'entretien et notes confidentielles avec contrôle des droits propriétaires.

View file

@ -26,8 +26,8 @@ Authorization: Bearer <token>
### Comptes de démonstration préconfigurés :
| Rôle | Utilisateur | Mot de passe | Jeton direct (`api_token`) | Droits |
|---|---|---|---|---|
| **Admin** | `admin` | `adminpassword` | `admin-token-secret-12345` | **Accès total** : consultation, modification et suppression de tout véhicule et contenu |
| **Utilisateur** | `user` | `userpassword` | `user-token-secret-67890` | **Propriétaire** : gestion de ses propres véhicules, kilométrages, entretiens et notes |
| **Admin** | `admin` | `adminpassword` | `admin-token-secret-12345` | **Accès total** : consultation de l'ensemble du parc (/cars, immatriculation), modification et suppression de tout véhicule et contenu |
| **Utilisateur** | `user` | `userpassword` | `user-token-secret-67890` | **Propriétaire** : gestion de ses propres véhicules (/cars/mes-voitures), kilométrages, entretiens et notes |
---
@ -46,10 +46,10 @@ Authorization: Bearer <token>
### 2. Voitures (`/cars`)
| Méthode | Endpoint | Accès | Description |
|---|---|---|---|
| `GET` | `/cars` | **Public** | Liste toutes les voitures *(filtrable par `?immatriculation=...`, `?user_id=...`, `?mine=true`)* |
| `GET` | `/cars` | **Admin** | Liste toutes les voitures *(filtrable par `?immatriculation=...`, `?user_id=...`, `?mine=true`)* |
| `GET` | `/cars/mes-voitures` | **Authentifié** | Liste uniquement les voitures appartenant à l'utilisateur connecté |
| `GET` | `/cars/{id}` | **Public** | Fiche d'une voiture avec son dernier km et son propriétaire |
| `GET` | `/cars/immatriculation/{plaque}` | **Public** | Identification par plaque *(insensible à la casse, espaces et tirets, ex: `AB-123-CD`)* |
| `GET` | `/cars/immatriculation/{plaque}` | **Admin** | Identification par plaque *(insensible à la casse, espaces et tirets, ex: `AB-123-CD`)* |
| `GET` | `/cars/{id}/etat` | **Propriétaire ou Admin** | État complet *(voiture, dernier km, historique entretiens et notes de suivi)* |
| `POST` | `/cars` | **Authentifié** | Créer une voiture *(attribuée automatiquement à l'utilisateur connecté)* |
| `PUT` | `/cars/{id}` | **Propriétaire ou Admin** | Mettre à jour les paramètres d'une voiture *(marque, modèle, année, immatriculation...)* |
@ -102,12 +102,19 @@ Authorization: Bearer <token>
## 🧪 Exemples rapides de requêtes (cURL)
#### 1. Identification par plaque (Public) :
#### 1. Identification par plaque (Admin requis) :
```bash
curl -X GET "http://localhost/voitureAPI/cars/immatriculation/AB-123-CD"
curl -X GET "http://localhost/voitureAPI/cars/immatriculation/AB-123-CD" \
-H "Authorization: Bearer admin-token-secret-12345"
```
#### 2. Connexion :
#### 2. Liste de toutes les voitures (Admin requis) :
```bash
curl -X GET "http://localhost/voitureAPI/cars" \
-H "Authorization: Bearer admin-token-secret-12345"
```
#### 3. Connexion :
```bash
curl -X POST "http://localhost/voitureAPI/auth/login" \
-H "Content-Type: application/json" \

View file

@ -262,7 +262,7 @@ try {
'regles_droits' => [
'Admins' => 'Accès total à toutes les voitures, détails confidentiels, modifications et suppressions.',
'Propriétaires' => 'Peuvent modifier/supprimer leurs propres voitures et gérer leurs entretiens, kilométrages et notes.',
'Public' => 'Consultation générale des voitures et recherche par immatriculation.'
'Public' => 'Consultation de la fiche d\'une voiture par son identifiant (/cars/{id}).'
],
'endpoints' => [
'Authentification' => [
@ -272,10 +272,10 @@ try {
'POST /auth/logout' => '[AUTHENTIFIÉ] Révoquer le jeton de session'
],
'Voitures' => [
'GET /cars' => '[PUBLIC] Liste des voitures (filtrable par ?immatriculation=..., ?user_id=..., ?mine=true)',
'GET /cars' => '[ADMIN] Liste de toutes les voitures (filtrable par ?immatriculation=..., ?user_id=..., ?mine=true)',
'GET /cars/mes-voitures' => '[AUTHENTIFIÉ] Liste uniquement les voitures de l\'utilisateur connecté',
'GET /cars/{id}' => '[PUBLIC] Détails d\'une voiture avec son propriétaire',
'GET /cars/immatriculation/{plaque}' => '[PUBLIC] Identifier une voiture par sa plaque',
'GET /cars/immatriculation/{plaque}' => '[ADMIN] Identifier une voiture par sa plaque',
'GET /cars/{id}/etat' => '[PROPRIÉTAIRE ou ADMIN] État complet (voiture, dernier km, entretiens, notes)',
'POST /cars' => '[AUTHENTIFIÉ] Créer une voiture (attribuée automatiquement à l\'utilisateur connecté)',
'PUT /cars/{id}' => '[PROPRIÉTAIRE ou ADMIN] Modifier les paramètres d\'une voiture',
@ -415,9 +415,10 @@ try {
}
// =========================================================================
// ENDPOINT DIRECT: /immatriculation/{plaque}
// ENDPOINT DIRECT: /immatriculation/{plaque} [ADMIN REQUIS]
// =========================================================================
if ($resource === 'immatriculation' && $method === 'GET') {
authenticate($db, true, 'admin');
$plaque = $segments[1] ?? null;
if (empty($plaque)) {
sendJson(400, ['success' => false, 'error' => 'Numéro d\'immatriculation manquant dans l\'URL']);
@ -447,8 +448,9 @@ try {
sendJson(200, ['success' => true, 'data' => $list]);
}
// GET /cars/immatriculation/{plaque} (Public)
// GET /cars/immatriculation/{plaque} [ADMIN REQUIS]
if (isset($segments[1]) && strtolower($segments[1]) === 'immatriculation' && $method === 'GET') {
authenticate($db, true, 'admin');
$plaque = $segments[2] ?? null;
if (empty($plaque)) {
sendJson(400, ['success' => false, 'error' => 'Numéro d\'immatriculation manquant dans l\'URL']);
@ -695,19 +697,20 @@ try {
// --- ACTIONS PRINCIPALES SUR LES VOITURES ---
// GET /cars : Liste toutes les voitures (Public / Filtrable)
// GET /cars : Liste toutes les voitures [ADMIN REQUIS]
if ($carId === null && $subResource === null && $method === 'GET') {
$currentUser = authenticate($db, true, 'admin');
// Filtre par immatriculation
if (!empty($_GET['immatriculation'])) {
findCarByPlate($db, (string)$_GET['immatriculation']);
}
$currentUser = authenticate($db, false);
$where = [];
$params = [];
// Filtre mes voitures (?mine=true)
if (!empty($_GET['mine']) && $currentUser) {
if (!empty($_GET['mine'])) {
$where[] = 'c.user_id = ?';
$params[] = $currentUser['id'];
} elseif (!empty($_GET['user_id'])) {