Contrat API - 0x485254/brief-26 GitHub Wiki
📡 Contrat d'API – EasyGroup (Backend → Frontend)
Ce document décrit l’ensemble des endpoints RESTful exposés par l’API backend d’EasyGroup, y compris les routes utilisateur et admin.
Documentation de l'API EasyGroup
Ce document fournit des informations sur les points de terminaison REST API disponibles dans l'application EasyGroup pour la création intelligente de groupes d'apprenants.
URL de Base
Lors de l'exécution en local, l'URL de base est :
http://localhost:8080
Authentification et Sécurité
EasyGroup utilise une authentification basée sur des cookies HTTP-only contenant des tokens JWT (JSON Web Tokens) pour sécuriser l'API. Cette approche offre une meilleure protection contre les attaques XSS (Cross-Site Scripting) par rapport aux tokens stockés dans le localStorage ou sessionStorage.
Architecture de Sécurité
L'application implémente une architecture de sécurité robuste avec les caractéristiques suivantes :
- Cookies HTTP-only : Les tokens JWT sont stockés dans des cookies HTTP-only, inaccessibles via JavaScript
- Protection CSRF : Mise en œuvre via CookieCsrfTokenRepository
- Sessions stateless : Aucune session n'est stockée côté serveur
- Hachage de mot de passe Argon2id : Algorithme de hachage résistant aux attaques par GPU et par canal auxiliaire
- Filtres de sécurité : Validation des tokens JWT à chaque requête
Points de Terminaison d'Authentification
Inscription d'un Utilisateur
Permet de créer un nouveau compte utilisateur et de définir un cookie HTTP-only contenant un token JWT.
- URL :
/api/auth/register
- Méthode :
POST
- Authentification requise : Non
- Permissions requises : Aucune
- Corps de la Requête :
{
"email": "[email protected]",
"password": "motdepasse123",
"firstName": "Prénom",
"lastName": "Nom"
}
Réponse en Cas de Succès
- Code : 201 Created
- Cookies définis :
JWT_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
(HTTP-only) - Exemple de contenu :
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]",
"firstName": "Prénom",
"lastName": "Nom",
"role": "USER",
"isActivated": true
}
Connexion d'un Utilisateur
Permet à un utilisateur de se connecter et de recevoir un cookie HTTP-only contenant un token JWT.
- URL :
/api/auth/login
- Méthode :
POST
- Authentification requise : Non
- Permissions requises : Aucune
- Corps de la Requête :
{
"email": "[email protected]",
"password": "motdepasse123"
}
Réponse en Cas de Succès
- Code : 200 OK
- Cookies définis :
JWT_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
(HTTP-only) - Exemple de contenu :
{
"userId": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]",
"firstName": "Prénom",
"lastName": "Nom",
"role": "USER",
"isActivated": true
}
Déconnexion d'un Utilisateur
Permet à un utilisateur de se déconnecter en supprimant le cookie d'authentification.
- URL :
/api/auth/logout
- Méthode :
POST
- Authentification requise : Non
- Permissions requises : Aucune
Réponse en Cas de Succès
- Code : 200 OK
- Cookies supprimés :
JWT_TOKEN
(valeur vide, Max-Age=0)
Flux d'Authentification
-
Inscription :
- L'utilisateur envoie ses informations d'inscription
- Le serveur valide les données et crée un nouvel utilisateur
- Le mot de passe est haché avec Argon2id avant d'être stocké
- Un token JWT est généré et placé dans un cookie HTTP-only
- Les détails de l'utilisateur sont renvoyés dans la réponse (sans le token)
-
Connexion :
- L'utilisateur envoie ses identifiants
- Le serveur authentifie l'utilisateur en vérifiant le mot de passe
- Un token JWT est généré et placé dans un cookie HTTP-only
- Les détails de l'utilisateur sont renvoyés dans la réponse (sans le token)
-
Requêtes authentifiées :
- Le cookie contenant le token JWT est automatiquement envoyé avec chaque requête
- Le filtre CookieAuthenticationFilter extrait et valide le token
- Si le token est valide, l'utilisateur est authentifié pour la requête
- Si le token est invalide ou absent, la requête est rejetée pour les endpoints protégés
-
Déconnexion :
- L'utilisateur envoie une requête de déconnexion
- Le serveur supprime le cookie d'authentification en définissant sa durée de vie à 0
Configuration des Cookies
Les cookies d'authentification sont configurés avec les attributs de sécurité suivants :
- HttpOnly : Empêche l'accès au cookie via JavaScript
- Secure : Le cookie n'est envoyé que sur des connexions HTTPS (en production)
- SameSite=Strict : Le cookie n'est pas envoyé lors des requêtes cross-site
- Path=/ : Le cookie est disponible pour tout le domaine
- Expiration : 24 heures par défaut
Hachage de Mot de Passe Argon2id
EasyGroup utilise l'algorithme Argon2id pour le hachage des mots de passe, avec les paramètres suivants :
- Longueur du sel : 16 octets
- Longueur du hachage : 32 octets
- Itérations : 3
- Mémoire : 64 Mo
- Parallélisme : 4 threads
Cette configuration offre une excellente protection contre les attaques par force brute, y compris celles utilisant des GPU ou des ASIC.
Points de Terminaison de Gestion des Utilisateurs
Récupération du Profil de l'Utilisateur Courant
Permet à un utilisateur authentifié de récupérer son propre profil.
- URL :
/api/users/me
- Méthode :
GET
- Authentification requise : Oui
- Permissions requises : Utilisateur authentifié
Réponse en Cas de Succès
- Code : 200 OK
- Exemple de contenu :
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]",
"firstName": "Prénom",
"lastName": "Nom",
"role": "USER",
"isActivated": true,
"createdAt": "2023-01-15T10:30:00",
"updatedAt": "2023-01-15T10:30:00"
}
Mise à Jour du Profil de l'Utilisateur Courant
Permet à un utilisateur authentifié de mettre à jour son propre profil.
- URL :
/api/users/me
- Méthode :
PUT
- Authentification requise : Oui
- Permissions requises : Utilisateur authentifié
- Corps de la Requête :
{
"firstName": "Nouveau Prénom",
"lastName": "Nouveau Nom"
}
Réponse en Cas de Succès
- Code : 200 OK
- Exemple de contenu :
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]",
"firstName": "Nouveau Prénom",
"lastName": "Nouveau Nom",
"role": "USER",
"isActivated": true,
"createdAt": "2023-01-15T10:30:00",
"updatedAt": "2023-01-15T11:45:00"
}
Suppression du Compte de l'Utilisateur Courant
Permet à un utilisateur authentifié de supprimer son propre compte.
- URL :
/api/users/me
- Méthode :
DELETE
- Authentification requise : Oui
- Permissions requises : Utilisateur authentifié
Réponse en Cas de Succès
- Code : 204 No Content
Récupération de Tous les Utilisateurs (Admin)
Permet à un administrateur de récupérer la liste de tous les utilisateurs.
- URL :
/api/users
- Méthode :
GET
- Authentification requise : Oui
- Permissions requises : Administrateur
Réponse en Cas de Succès
- Code : 200 OK
- Exemple de contenu :
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]",
"firstName": "Prénom1",
"lastName": "Nom1",
"role": "USER",
"isActivated": true,
"createdAt": "2023-01-15T10:30:00",
"updatedAt": "2023-01-15T10:30:00"
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"email": "[email protected]",
"firstName": "Prénom2",
"lastName": "Nom2",
"role": "ADMIN",
"isActivated": true,
"createdAt": "2023-01-14T09:15:00",
"updatedAt": "2023-01-14T09:15:00"
}
]
Récupération d'un Utilisateur par ID (Admin)
Permet à un administrateur de récupérer un utilisateur spécifique par son ID.
- URL :
/api/users/{id}
- Méthode :
GET
- Authentification requise : Oui
- Permissions requises : Administrateur
Réponse en Cas de Succès
- Code : 200 OK
- Exemple de contenu :
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]",
"firstName": "Prénom",
"lastName": "Nom",
"role": "USER",
"isActivated": true,
"createdAt": "2023-01-15T10:30:00",
"updatedAt": "2023-01-15T10:30:00"
}
Activation/Désactivation d'un Utilisateur (Admin)
Permet à un administrateur d'activer ou de désactiver un compte utilisateur.
- URL :
/api/users/{id}/activate
- Méthode :
PUT
- Authentification requise : Oui
- Permissions requises : Administrateur
- Paramètres de Requête :
isActivated=true|false
Réponse en Cas de Succès
- Code : 200 OK
- Exemple de contenu :
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "[email protected]",
"firstName": "Prénom",
"lastName": "Nom",
"role": "USER",
"isActivated": false,
"createdAt": "2023-01-15T10:30:00",
"updatedAt": "2023-01-16T14:20:00"
}
Points de Terminaison de Gestion des Listes
Note: Les endpoints de gestion des listes décrits ci-dessous sont planifiés pour une implémentation future et ne sont pas encore disponibles dans la version actuelle de l'API.
Création d'une Liste (Planifié)
Permettra de créer une nouvelle liste de personnes.
- URL :
/api/lists
- Méthode :
POST
- Authentification requise : Oui
- Permissions requises : Utilisateur authentifié
- Corps de la Requête :
{
"name": "Ma Liste"
}
Réponse en Cas de Succès
- Code : 201 Created
- Exemple de contenu :
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Ma Liste",
"isShared": false
}
Récupération des Listes d'un Utilisateur (Planifié)
Permettra de récupérer toutes les listes appartenant à l'utilisateur connecté.
- URL :
/api/lists
- Méthode :
GET
- Authentification requise : Oui
- Permissions requises : Utilisateur authentifié
Réponse en Cas de Succès
- Code : 200 OK
- Exemple de contenu :
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Ma Liste",
"isShared": false
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "Autre Liste",
"isShared": true
}
]
Points de Terminaison de Gestion des Personnes
Ajout d'une Personne à une Liste
Permet d'ajouter une nouvelle personne à une liste existante.
- URL :
/users/{userId}/lists/{listId}/persons
- Méthode :
POST
- Authentification requise : Oui
- Permissions requises : Propriétaire de la liste ou utilisateur avec accès partagé
- Corps de la Requête :
{
"name": "Jean Dupont",
"gender": "MALE",
"age": 25,
"frenchLevel": 3,
"oldDwwm": false,
"techLevel": 2,
"profile": "A_LAISE"
}
Réponse en Cas de Succès
- Code : 201 Created
- Exemple de contenu :
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Jean Dupont",
"gender": "MALE",
"age": 25,
"frenchLevel": 3,
"oldDwwm": false,
"techLevel": 2,
"profile": "A_LAISE"
}
Récupération des Personnes d'une Liste
Permet de récupérer toutes les personnes d'une liste spécifique.
- URL :
/users/{userId}/lists/{listId}/persons
- Méthode :
GET
- Authentification requise : Oui
- Permissions requises : Propriétaire de la liste ou utilisateur avec accès partagé
Réponse en Cas de Succès
- Code : 200 OK
- Exemple de contenu :
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Jean Dupont",
"gender": "MALE",
"age": 25,
"frenchLevel": 3,
"oldDwwm": false,
"techLevel": 2,
"profile": "A_LAISE"
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "Marie Martin",
"gender": "FEMALE",
"age": 30,
"frenchLevel": 4,
"oldDwwm": true,
"techLevel": 3,
"profile": "RESERVE"
}
]
Modification d'une Personne
Permet de modifier les informations d'une personne existante.
- URL :
/users/{userId}/lists/{listId}/persons/{personId}
- Méthode :
PUT
- Authentification requise : Oui
- Permissions requises : Propriétaire de la liste ou utilisateur avec accès partagé
- Corps de la Requête :
{
"name": "Jean Dupont Modifié",
"gender": "MALE",
"age": 26,
"frenchLevel": 4,
"oldDwwm": false,
"techLevel": 3,
"profile": "A_LAISE"
}
Réponse en Cas de Succès
- Code : 200 OK
- Exemple de contenu :
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Jean Dupont Modifié",
"gender": "MALE",
"age": 26,
"frenchLevel": 4,
"oldDwwm": false,
"techLevel": 3,
"profile": "A_LAISE"
}
Suppression d'une Personne
Permet de supprimer une personne d'une liste.
- URL :
/users/{userId}/lists/{listId}/persons/{personId}
- Méthode :
DELETE
- Authentification requise : Oui
- Permissions requises : Propriétaire de la liste ou utilisateur avec accès partagé
Réponse en Cas de Succès
- Code : 200 OK
Points de Terminaison de Gestion des Tirages et Groupes
Création d'un Tirage
Permet de créer un nouveau tirage à partir d'une liste existante et de générer des groupes.
- URL :
/api/users/{userId}/lists/{listId}/draws
- Méthode :
POST
- Authentification requise : Oui
- Permissions requises : Propriétaire de la liste ou utilisateur avec accès partagé
- Corps de la Requête :
{
"title": "Tirage du 15 janvier",
"numberOfGroups": 3
}
Réponse en Cas de Succès
- Code : 201 Created
- Exemple de contenu :
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Tirage du 15 janvier",
"createdAt": "2023-01-15T10:30:00",
"groups": [
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "Group 1"
},
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"name": "Group 2"
},
{
"id": "550e8400-e29b-41d4-a716-446655440003",
"name": "Group 3"
}
]
}
Récupération des Tirages d'une Liste
Permet de récupérer tous les tirages associés à une liste spécifique.
- URL :
/api/users/{userId}/lists/{listId}/draws
- Méthode :
GET
- Authentification requise : Oui
- Permissions requises : Propriétaire de la liste ou utilisateur avec accès partagé
Réponse en Cas de Succès
- Code : 200 OK
- Exemple de contenu :
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Tirage du 15 janvier",
"createdAt": "2023-01-15T10:30:00",
"groups": [
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "Group 1"
},
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"name": "Group 2"
}
]
},
{
"id": "550e8400-e29b-41d4-a716-446655440003",
"title": "Tirage du 20 janvier",
"createdAt": "2023-01-20T14:15:00",
"groups": [
{
"id": "550e8400-e29b-41d4-a716-446655440004",
"name": "Group 1"
},
{
"id": "550e8400-e29b-41d4-a716-446655440005",
"name": "Group 2"
}
]
}
]
Récupération des Groupes d'un Tirage
Permet de récupérer tous les groupes générés pour un tirage spécifique.
- URL :
/api/draws/{drawId}/groups
- Méthode :
GET
- Authentification requise : Oui
- Permissions requises : Propriétaire de la liste ou utilisateur avec accès partagé
Réponse en Cas de Succès
- Code : 200 OK
- Exemple de contenu :
[
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "Group 1",
"persons": [
{
"id": "550e8400-e29b-41d4-a716-446655440010",
"name": "Jean Dupont"
},
{
"id": "550e8400-e29b-41d4-a716-446655440011",
"name": "Marie Martin"
}
]
},
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"name": "Group 2",
"persons": [
{
"id": "550e8400-e29b-41d4-a716-446655440012",
"name": "Pierre Durand"
},
{
"id": "550e8400-e29b-41d4-a716-446655440013",
"name": "Sophie Petit"
}
]
}
]
Ajout d'une Personne à un Groupe
Permet d'ajouter manuellement une personne à un groupe existant.
- URL :
/api/groups/{groupId}/persons/{personId}
- Méthode :
POST
- Authentification requise : Oui
- Permissions requises : Propriétaire de la liste ou utilisateur avec accès partagé
Réponse en Cas de Succès
- Code : 200 OK
Suppression d'une Personne d'un Groupe
Permet de retirer manuellement une personne d'un groupe.
- URL :
/api/groups/{groupId}/persons/{personId}
- Méthode :
DELETE
- Authentification requise : Oui
- Permissions requises : Propriétaire de la liste ou utilisateur avec accès partagé
Réponse en Cas de Succès
- Code : 200 OK
- Exemple de contenu :
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Jean Dupont",
"gender": "MALE",
"age": 25,
"frenchLevel": 3,
"oldDwwm": false,
"techLevel": 2,
"profile": "A_LAISE"
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "Marie Martin",
"gender": "FEMALE",
"age": 30,
"frenchLevel": 4,
"oldDwwm": true,
"techLevel": 3,
"profile": "RESERVE"
}
]
Points de Terminaison Actuator
Spring Boot Actuator fournit plusieurs points de terminaison pour la surveillance et la gestion de l'application. Les suivants sont activés dans EasyGroup :
- Health :
/actuator/health
- Affiche l'état de santé de l'application et de ses dépendances (base de données, etc.) - Info :
/actuator/info
- Affiche les informations de l'application (version, environnement, etc.) - Metrics :
/actuator/metrics
- Affiche diverses métriques de l'application (mémoire, CPU, requêtes HTTP, etc.)
Réponses d'Erreur
400 Requête Incorrecte
{
"timestamp": "2023-11-01T12:00:00.000+00:00",
"status": 400,
"error": "Bad Request",
"message": "Validation failed for object='authRequest'",
"path": "/api/auth/register"
}
401 Non Autorisé
{
"timestamp": "2023-11-01T12:00:00.000+00:00",
"status": 401,
"error": "Unauthorized",
"message": "Authentication credentials not valid",
"path": "/api/lists"
}
403 Interdit
{
"timestamp": "2023-11-01T12:00:00.000+00:00",
"status": 403,
"error": "Forbidden",
"message": "Access denied to this resource",
"path": "/api/lists/550e8400-e29b-41d4-a716-446655440000"
}
404 Non Trouvé
{
"timestamp": "2023-11-01T12:00:00.000+00:00",
"status": 404,
"error": "Not Found",
"message": "List not found with id: 550e8400-e29b-41d4-a716-446655440000",
"path": "/api/lists/550e8400-e29b-41d4-a716-446655440000"
}
500 Erreur Interne du Serveur
{
"timestamp": "2023-11-01T12:00:00.000+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "An unexpected error occurred",
"path": "/api/lists"
}