Table profils / rôles
Création de la table de relation entre utilisateurs et rôles
Notions théoriques
Le type ENUM pour les rôles
Pourquoi utiliser un type ENUM pour les rôles ?
Dans une base de données relationnelle comme PostgreSQL (et donc Supabase), il est souvent nécessaire de limiter les valeurs possibles d’un champ à un ensemble précis.
C’est exactement ce que permet un type ENUM : un type personnalisé qui restreint les valeurs à une liste définie.
Dans notre projet, les utilisateurs peuvent avoir différents rôles :
- guest
- student
- teacher
- admin
- super-admin
Ces rôles ont des droits différents dans l’application. Il est donc important de les gérer de manière fiable et sécurisée.
Avantages d’un type ENUM
- Validation automatique : PostgreSQL empêche l’insertion d’une valeur non prévue.
- Lisibilité : les valeurs sont explicites et claires (
'admin'
,'student'
, etc.). - Sécurité : impossible d’ajouter un rôle non prévu par erreur.
- Compatibilité avec Supabase : les types ENUM sont bien pris en charge dans l’interface.
Toujours préférer un type ENUM à une simple colonne texte quand les valeurs possibles sont connues et limitées.
Définition d’un type ENUM
Voici comment créer un type ENUM dans PostgreSQL :
create type user_role as enum ('guest', 'student', 'teacher', 'admin', 'super-admin');
Cette commande crée un nouveau type user_role
avec cinq valeurs autorisées.
Créer la table user_roles
Créer une table pour stocker les rôles des utilisateurs
Une fois le type ENUM créé, on peut l’utiliser dans une table.
La table user_roles
permet de lier un utilisateur à un rôle donné.
Structure de la table :
Colonne | Type | Description |
---|---|---|
id | uuid | Identifiant unique (clé primaire) |
user_id | uuid | Référence à auth.users(id) |
role | user_role | Rôle de l’utilisateur |
created_at | timestamp with time zone | Date de création de la ligne |
updated_at | timestamp with time zone | Date de dernière mise à jour |
Script SQL pour créer la table
create table public.user_roles (
id uuid default uuid_generate_v4() primary key,
user_id uuid references auth.users(id) not null,
role user_role not null default 'guest',
created_at timestamp with time zone default current_timestamp,
updated_at timestamp with time zone default current_timestamp
);
Le champ role
utilise le type user_role
défini précédemment.
La valeur par défaut est 'guest'
.
Bonnes pratiques cyber
- Limiter les rôles possibles via un ENUM empêche les erreurs ou attaques par injection de rôles non autorisés.
- Auditer les changements de rôle : les champs
created_at
etupdated_at
permettent de tracer les modifications. - Éviter les valeurs libres : ne jamais autoriser un champ texte libre pour des rôles critiques.
Ne jamais stocker les rôles dans une chaîne de caractères libre (text
) sans validation stricte.
Exemple pratique
Créer la table des rôles
Créer le type ENUM et la table des rôles
Il est possible de créer le type ENUM et la table via le SQL Editor de Supabase.
- Ouvrir l’onglet SQL Editor.
- Exécuter la requête suivante pour créer le type ENUM :
create type user_role as enum ('guest', 'student', 'teacher', 'admin', 'super-admin');
- Créer ensuite la table
user_roles
:
create table public.user_roles (
id uuid default uuid_generate_v4() primary key,
user_id uuid references auth.users(id) not null,
role user_role not null default 'guest',
created_at timestamp with time zone default current_timestamp,
updated_at timestamp with time zone default current_timestamp
);
Insérer un rôle pour un utilisateur
Il est possible d’attribuer un rôle à un utilisateur existant :
insert into public.user_roles (user_id, role)
values ('<uuid_utilisateur>', 'admin');
Remplacer <uuid_utilisateur>
par un identifiant réel d’utilisateur existant dans auth.users
.
Vérifier le contenu de la table
Aller dans Table Editor > user_roles et vérifier que :
- la ligne a bien été insérée,
- le champ
role
est bien rempli, - les dates
created_at
etupdated_at
sont présentes.
Tester la sécurité du type ENUM
Tenter d’insérer une valeur non autorisée :
insert into public.user_roles (user_id, role)
values ('<uuid_utilisateur>', 'hacker');
Résultat attendu : une erreur indiquant que 'hacker'
n’est pas une valeur valide pour user_role
.
Test de mémorisation/compréhension
TP pour réfléchir et résoudre des problèmes
1. Créer le type ENUM user_role
Dans l’éditeur SQL de Supabase, créer un type ENUM contenant les rôles suivants : 'guest'
, 'student'
, 'teacher'
, 'admin'
, 'super-admin'
.
create type user_role as enum ('guest', 'student', 'teacher', 'admin', 'super-admin');
Une solution
Vous devez être connecté pour voir le contenu.
2. Créer la table user_roles
Créer la table
user_roles
avec une référence àauth.users
Créer une table user_roles
avec les colonnes suivantes :
id
de typeuuid
, clé primaire, généré automatiquementuser_id
de typeuuid
, référence àauth.users(id)
role
de typeuser_role
, avec la valeur par défaut'guest'
created_at
etupdated_at
de typetimestamp with time zone
, avec valeur par défaut àcurrent_timestamp
Une solution
Vous devez être connecté pour voir le contenu.
3. Insérer un rôle
Insérer un rôle pour un utilisateur existant
Insérer une ligne dans la table user_roles
pour attribuer à un utilisateur existant le rôle 'admin'
.
⚠️ Remplacer
<uuid_utilisateur>
par un identifiant réel d’un utilisateur de votre base Supabase.
Une solution
Vous devez être connecté pour voir le contenu.
4. Vérifier que l’insertion a bien fonctionné
Vérifier que la ligne a bien été insérée dans la table user_roles
:
- Accéder à l’onglet Table Editor > user_roles
- Vérifier que les colonnes
user_id
,role
,created_at
,updated_at
sont correctement remplies
Une solution
Vous devez être connecté pour voir le contenu.
5. Tester la sécurité du type ENUM
Tenter d’insérer une valeur non autorisée dans le champ role
, comme 'hacker'
.
Observer le comportement de PostgreSQL.
Une solution
Vous devez être connecté pour voir le contenu.
6. Modifier le rôle d’un utilisateur existant
Mettre à jour le rôle d’un utilisateur en le passant de 'admin'
à 'super-admin'
.
Une solution
Vous devez être connecté pour voir le contenu.
7. Un seul rôle par utilisateur
Ajouter une contrainte d’unicité sur
user_id
Empêcher qu’un même utilisateur ait plusieurs rôles en ajoutant une contrainte UNIQUE(user_id)
.
Une solution
Vous devez être connecté pour voir le contenu.
8. Vérifier les contraintes de sécurité
Essayer d’insérer un second rôle pour le même utilisateur.
Observer que la base de données empêche l’insertion.
Une solution
Vous devez être connecté pour voir le contenu.
9. Lister tous les utilisateurs avec leur rôle
Créer une requête SQL qui affiche tous les utilisateurs et leur rôle (en joignant auth.users
et user_roles
).
Une solution
Vous devez être connecté pour voir le contenu.
10. Retirer le rôle d’un utilisateur
Pour tester, supprimer un rôle attribué à un utilisateur.
Une solution
Vous devez être connecté pour voir le contenu.