Aller au contenu principal

Permissions & Contrôle d'Accès

Ce document décrit le système de permissions de StageConnect : les rôles utilisateurs, les droits associés, et comment ils sont appliqués dans le backend.

Rôles Utilisateurs (UserType)​

Le backend définit 6 rôles dans l'enum UserType (app/core/config.py). Ces rôles sont encodés dans chaque JWT dans le claim user_type.

Rôle JWTCodeInterfaceRôle métier
STUDENTUserType.STUDENTDiscover ou CareerÉtudiant L1/L2 ou L3/M
UNIVERSITY_ADMINUserType.UNIVERSITY_ADMINCareerResponsable pédagogique université
ACADEMIC_SUPERVISORUserType.ACADEMIC_SUPERVISORCareer (portail encadrant)Encadreur académique
COMPANYUserType.COMPANYCareerReprésentant entreprise
COMPANY_MENTORUserType.COMPANY_MENTORCareer (portail encadrant)Maître de stage
PLATFORM_ADMINUserType.PLATFORM_ADMINAdminAdministrateur plateforme
Distinction DB vs JWT

Dans la base de données (users.user_type), les valeurs sont différentes : STUDENT, ACADEMIC_STAFF, COMPANY_STAFF, ADMIN, SCHOOL_STAFF. Ces valeurs DB sont ensuite mappées vers les rôles JWT lors de l'authentification. Dans le code Python, toujours utiliser UserType.UNIVERSITY_ADMIN etc., pas les valeurs brutes de la DB.

Dépendances FastAPI par Rôle​

Le fichier app/utils/dependencies.py expose des dépendances prêtes à l'emploi :

# Accès étudiant uniquement
current_user = Depends(get_current_student)

# Accès admin université uniquement
current_user = Depends(get_current_university_admin)

# Accès encadreur académique uniquement
current_user = Depends(get_current_academic_supervisor)

# Accès entreprise uniquement
current_user = Depends(get_current_company_user)

# Accès maître de stage uniquement
current_user = Depends(get_current_company_mentor)

# Accès admin plateforme uniquement
current_user = Depends(get_current_platform_admin)

Multi-rôles​

# Utiliser require_user_types() pour les endpoints multi-rôles
from app.utils.dependencies import require_user_types
from app.core.config import UserType

@router.get("/shared-endpoint")
async def shared_endpoint(
current_user = Depends(require_user_types([
UserType.UNIVERSITY_ADMIN,
UserType.PLATFORM_ADMIN
]))
):
...

Matrice des Droits par Rôle​

Étudiants​

ActionL1/L2 (Discover)L3/M (Career)
Voir les offres de stage (liste)✅✅
Voir le détail d'une offre❌✅
Candidater à une offre❌✅
Retirer une candidature❌✅
Modifier son profil (basique)✅✅
Uploader un CV❌✅
Proposer un thème de stage❌✅
Créer un binôme❌✅
Consulter sa convention❌✅
Soumettre un rapport❌✅
Niveau L1/L2 vs L3/M

La séparation L1/L2 vs L3/M est actuellement gérée côté frontend par l'application (Discover vs Career). Le backend applique les permissions par UserType.STUDENT sans distinction de niveau. La distinction de niveau académique est basée sur students.academic_year en DB et vérifiée dans les services métier concernés.

Université​

ActionUNIVERSITY_ADMIN
Voir les étudiants de son université✅
Valider les thèmes de stage✅
Assigner des encadreurs académiques✅
Gérer les conventions de stage✅
Programmer les soutenances✅
Voir les statistiques université✅
Accéder aux données d'autres universités❌

Entreprise​

ActionCOMPANYCOMPANY_MENTOR
Publier des offres✅❌
Voir les candidatures reçues✅❌
Voir les stagiaires en cours✅✅ (siens uniquement)
Évaluer un stagiaire❌✅
Gérer les maîtres de stage✅❌
Voir le profil des candidats✅✅

Admin Plateforme​

ActionPLATFORM_ADMIN
Lire toutes les données✅
Modifier les utilisateurs✅
Voir les logs d'activité✅
Gérer les plans tarifaires✅
Accéder aux rapports de bugs✅
Suspendre un compte✅

Décorateurs de Sécurité​

Le fichier app/utils/decorators.py fournit des décorateurs pour vérifications rapides :

from app.utils.decorators import require_platform_admin, require_university_admin, require_company_access

@router.delete("/users/{user_id}")
@require_platform_admin
async def delete_user(user_id: str, current_user = Depends(get_current_user)):
...

Comment Ajouter un Nouveau Endpoint Protégé​

from fastapi import APIRouter, Depends
from app.utils.dependencies import get_current_student

router = APIRouter()

@router.get("/my-protected-endpoint")
async def my_endpoint(current_user = Depends(get_current_student)):
"""
Endpoint accessible uniquement aux étudiants.
current_user.user_type == UserType.STUDENT est garanti.
"""
student_id = current_user.id
...

Règles de Sécurité​

Règle absolue

Les permissions ne doivent JAMAIS être gérées côté frontend. Le frontend peut adapter son UI (masquer/afficher des boutons), mais le backend doit toujours refuser les requêtes non autorisées — indépendamment de ce que le frontend affiche.

  1. Toujours utiliser une dépendance : Chaque endpoint protégé doit avoir Depends(...) avec le bon rôle.
  2. Isolation des données : Un UNIVERSITY_ADMIN ne peut accéder qu'aux données de son université (filtrer par university_id).
  3. Pas de confiance au JWT pour les données : Le JWT dit qui vous êtes, pas quelles données vous pouvez voir — vérifier sur chaque requête.

Fichiers de Référence​

FichierContenu
app/core/config.pyDéfinition de UserType enum
app/utils/dependencies.pyDépendances FastAPI par rôle
app/utils/decorators.pyDécorateurs de sécurité
app/utils/auth.pyverify_token(), create_tokens()