Principe des masques de bits pour les permissions
Dans la conception de systèmes de permissions, les masques de bits offrent une méthode compacte et performante pour représenter des ensembles de droits. Chaque bit dans un entier correspond à une permission spécifique, où la valeur 1 indique l'accord et 0 le refus.
Définition des permissions
Les permissions sont stockées sous forme d'entiers. Par exemple, une séquence binaire de 8 bits peut modéliser jusqu'à 8 permissions distinctes. La table ci-dessous illustre la correspondance entre les positions de bits et les descriptions de permissions.
| Index de bit | Description |
|---|---|
| 0 | Lecture seule |
| 1 | Écriture |
| 2 | Exécution |
| 3 | Suppression |
Chaque permission est calculée par un décalage de bits : la permission d'index k vaut 1 << k en binaire.
Affectation des permissions à un utilisateur
Pour attribuer plusieurs permissions à un utilisateur, on addtiionne les valeurs décimales correspondantes. Par exemple, accorder les permissions d'index 1 (écriture) et 2 (exécution) donne la somme 2 + 4 = 6. Voici une requête SQL pour calculer cette valeur :
SELECT
SUM(POWER(2, def.id)) AS valeur_totale_permissions
FROM (
VALUES
(1, 'Écriture'),
(2, 'Exécution')
) AS def(id, description);
Vérification des permissions détenues
Pour déterminer quelles permissions un utilisateur possède, on effectue une opération ET bit à bit entre sa valeur de permissions et chaque définition. Si le résultat correspond à la valeur de la permission, celle-ci est incluse. Avec une valeur utilisateur de 6 (binaire 110), la requête suivante identifie les permissions :
SELECT
def.id AS permission_index,
def.description AS permission_nom,
POWER(2, def.id) AS permission_valeur,
tmp.valeur_utilisateur,
tmp.valeur_utilisateur & POWER(2, def.id) AS valeur_intersection
FROM (
VALUES
(0, 'Lecture seule'),
(1, 'Écriture'),
(2, 'Exécution'),
(3, 'Suppression')
) AS def(id, description),
(SELECT 6 AS valeur_utilisateur) AS tmp
WHERE (tmp.valeur_utilisateur & POWER(2, def.id)) = POWER(2, def.id);
Cette requête retourne les permissions "Écriture" et "Exécution" pour la valeur 6.
Contrôle d'accès à un module fonctionnel
Supposons qu'un module nécessite les permissions d'index 1, 2 et 3 (valeur 14). Si un utilisateur a les permissinos d'index 2 et 3 (valeur 12), on peut vérifier l'accès en testant si valeur_utilisateur & valeur_module > 0. Pour lister les permissions effectives sur ce module, on combine les deux valeurs :
SELECT
def.id AS permission_index,
def.description AS permission_nom,
POWER(2, def.id) AS permission_valeur,
tmp.valeur_combinee,
tmp.valeur_combinee & POWER(2, def.id) AS valeur_intersection
FROM (
VALUES
(0, 'Lecture seule'),
(1, 'Écriture'),
(2, 'Exécution'),
(3, 'Suppression')
) AS def(id, description),
(SELECT (POWER(2, 1) + POWER(2, 2) + POWER(2, 3)) & (POWER(2, 2) + POWER(2, 3)) AS valeur_combinee) AS tmp
WHERE (tmp.valeur_combinee & POWER(2, def.id)) = POWER(2, def.id);
Le résultat indique que l'utilisateur peut exécuter et supprimer dans ce module, mais pas écrire.