Gérer les permissions

De Sydonie

Configuration du fichier des permissions

config_permissions.php

Dans le répertoire "config/site/config_permissions.php" du site se trouve la délcaration de la politique de permissions du site.

Le fichier aura la forme suivante (à adapter selon les besoins) :

<?php
 
/** Permissions liées à l'action sur une instance **/
 
function myModelPermissionsRead($account, $entity) {
	return Perm::anyOf(
		Perm::isAdmin($account),
		Perm::is_a($entity, array('SydonieEntity_Account', 'SydonieEntity_Group')),
		Perm::exists(GROUP_VISITOR, '_GROUP_HAS_DOCUMENT_', $entity),
		Perm::isOwner($account, $entity),
		Perm::existsPath($account, '_IS_MEMBER_OF_GROUP_', '_GROUP_HAS_DOCUMENT_', $entity)
	);
}
 
function myModelPermissionsWrite($account, $entity) {
	$perm = Perm::anyOf(
	Perm::isAdmin($account),
	Perm::if_is_a($entity, 'SydonieEntity_Account',
		Perm::equals($account, $entity)        
	),
	Perm::exists($account, '_IS_MEMBER_OF_GROUP_', $entity),
	Perm::isOwner($account, $entity),
	Perm::existsPath($account, '_IS_MEMBER_OF_GROUP_', '_GROUP_CAN_WRITE_', $entity)
	);
	return $perm;
}
 
function myModelPermissionsAll($account, $entity) {
	$perm = Perm::anyOf(
		Perm::isAdmin($account),
		Perm::isOwner($account, $entity)          
	);
	return $perm;
}
 
 
Manager_Authorizer::getInstance()->registerPermissionModel('read',  'myModelPermissionsRead', false);
Manager_Authorizer::getInstance()->registerPermissionModel('write', 'myModelPermissionsWrite', false);
Manager_Authorizer::getInstance()->registerPermissionModel('all',   'myModelPermissionsAll', false);
 
 
/** Permissions liées à l'action sur une classe **/
function myClassModelPermissionsCreateEntity($account, $class) {
    return Perm::anyOf(
                    Perm::isAdmin($account)
    );
}
 
Manager_Authorizer::getInstance()->registerClassPermissionModel('createEntity', 'myClassModelPermissionsCreateEntity');
 
?>

Prenons l'exemple de la déclaration des permissions de lecture, qui sont décrite dans la fonction "myModelPermissionsRead" :

function myModelPermissionsRead($account, $entity) {
  return Perm::anyOf(
    Perm::isAdmin($account),
    Perm::is_a($entity, array('SydonieEntity_Account', 'SydonieEntity_Group')),
    Perm::exists(GROUP_VISITOR, '_GROUP_HAS_DOCUMENT_', $entity),
    Perm::isOwner($account, $entity),
    Perm::existsPath($account, '_IS_MEMBER_OF_GROUP_', '_GROUP_HAS_DOCUMENT_', $entity)
  );
}

Cette fonction doit retourner un fragment de SQL qui sera ajouté par Sydonie aux différentes requêtes SQL pour gérer les permissions. Ici, on autorise la lecture si n'importe laquelle des conditions suivantes est vérifiée :

- l'utilisateur est un administrateur
- l'entité est un compte utilisateur ou un groupe
- le groupe des visiteurs a accès à l'entité
- l'utilisateur est le propriétaire de l'entité
- l'utilisateur est membre d'un groupe qui a le droit de modifier l'entité

Déclaration du mot-clé

Reprenons notre exemple sur les permissions de lecture. Pour pouvoir utiliser cette permission sur les différentes actions d'instance de classe, il faut déclarer le mot-clé qui y est lié.

Manager_Authorizer::getInstance()->registerPermissionModel('read',  'myModelPermissionsRead', false);

Cette ligne de code fait appel à la classe Manager_Authorizer qui gère les différentes autorisations au sein du framework Sydonie. La méthode qui permet de déclarer le mot-clé pour une permission est "registerPermissionModel($keyword, $function, $override)" :

- $keyword correspond au mot-clé que vous allez utiliser dans votre site pour donner la permission de lecture sur une action d'instance.
- $function correspond au nom de la fonction que vous venez d'écrire.
- $override signifie que vous écrasez la fonction déclarée dans la base de Sydonie.

Vous pouvez ajouter autant de permissions que vous le souhaitez dans ce fichier de la même manière que c'est présenté dans cette page.

Utilisation des permissions sur une action

Dans le fichier de configuration des permissions, une fonction de permissions d'accès pour un groupe rédacteur a été déclaré et liée au mot-clé rédacteur (source ci-dessous) :

function myClassModelPermissionsRedacteur($account, $class) {
    return getManager('Groups')->isMemberOf($account, 'redacteur');
}
 
Manager_Authorizer::getInstance()->registerClassPermissionModel('redacteur', 'myClassModelPermissionsRedacteur', false);

Maintenant, je vais appliquer cette permission sur une action de classe Service_Gestion qui me permet de lister l'ensemble de mes actions pour un membre du groupe rédacteur. Pour rappel, une action est liée à deux méthodes : options_action() et do_action(). La déclaration des permissions s'effectue dans la méthode options_action (dans le source cette méthode est options_redacteur() ) :

protected function options_redacteur() {
	return array(
		'isClassAction' => true,
		'permissions' => 'redacteur'
	);
}

De cette façon, toute personne qui ne fera pas parti du groupe "rédacteur", n'aura donc pas le droit d'accès à cette action.


Liste des méthodes statiques

Perm::anyOf($fragmentSQL1, $fragmentSQL2, ...)

La méthode "Perm::anyOf" retourne un fagment de SQL qui constitue la disjonction de ses arguments (que l'on suppose être des fragments de requêtes SQL)

Perm::isAdmin($accountId)

La méthode "Perm::isAdmin" retourne un fragment de SQL pour vérifier que "$accountId" est bien membre du groupe admin.

Perm::is_a($entityId, array($className1, $className2, ...))

La méthode "Perm::is_a" retourne un fragment de SQL pour vérifier que l'entité si "entityId" est une instance d'une des classes "className1", "className2", etc.

Perm::exists($subjectId, $predicate, $objectId)

La méthode "Perm::exists" retourne un fragment de SQL qui vérifie si un triplet ("$subjectId", "$predicate", "$objectId") existe parmi les statements.

Perm::isOwner($accountId, $entityId)

Cette méthode retourne un fragment de SQL qui vérifie s'il existe un triplet ("$accountId", "_OWNS_", "$entityId") existe parmi les statements.

Perm::equals($entityId1, $entityId2)

Cette méthode retourne un fragment de SQL pour vérifier si les deux identifiants d'entité $entity1 et $entity2 sont égaux.

Perm::if_($fragmentSQL_condition, $fragmentSQL_SiVrai)

Cette méthode retourne un fragment de SQL qui est la conjonction de $fragmentSQL_condition et de $fragmentSQL_SiVrai.

Perm::if_is_a($entityId, $className, $fragmentSQL_SiVrai)

Raccourci pour Perm::if_(Perm::is_a($entityId, array($className)), $fragmentSQL_SiVrai