[Symfony] Utilisation du plugin slapOrm.

SlapORM

Depuis quelque temps je recherche une méthode simple d’accéder à mes entrées LDAP via symfony. Il existe bien plusieurs solutions pour authentifier nos utilisateurs depuis l’annuaire mais quand on parle de modification ceci est une toute autre histoire ! Nous allons donc voir ici comment manipuler nos entrées LDAP à l’aide du plugin slapOrm. Il va s’en dire que quelques bases de php/symfony ainsi que de l’architecture LDAP sont nécessaires à la compréhension de cet article.

slapOrm késako ?

Commençons par replacer les choses dans leurs contextes. Un annuaire LDAP est, comme son nom l’indique, un annuaire. Il stocke donc des données sous forme hiérarchique et ceci de manière optimisée pour la lecture. Le meilleur exemple pour vous schématiser ce concept est de vous imaginer l’annuaire téléphonique. Dans celui ci les numéro de téléphone sont stocké sous forme hiérarchique (L’annuaire, contient des noms de villes qui contiennent des personnes qui possèdent un à plusieurs numéros de téléphone.) aussi il est assez simple de retrouver un numéro de téléphone à l’aide de cette hiérarchie. Le revers de la médaille est la difficulté rencontrée pour écrire dans celui ci. Un simple rapport du temps que vous mettez à trouver un numéro de téléphone par rapport au temps que vous mettez pour apparaître dans l’annuaire vous montre clairement la limite ! Nous utiliserons dans cet article OpenLDAP comme serveur LDAP.
Un ORM pour object-relational mapping ou mapping objet-relationnel en français est une technique de programmation permettant d’accéder à des données d’une base de données relationnelle sous forme d’objet. Ici dire que nous utilisons un ORM pour accéder à notre annuaire est un abus de langage.
Ce que nous allons faire réellement est de créer un abstraction de la hiérarchie de l’annuaire pour pouvoir l’utiliser avec des objets simples. En gros nous allons spécifier que nos utilisateurs ce trouve dans tel branche de l’annuaire et nous allons avoir un objet pour pouvoir y accéder simplement.
Vous l’aurez compris c’est le plugin slapOrm qui nous permet de faire ceci. Aux vus du manque flagrant de documentations sur le projet je vais tenter d’exprimer aux mieux les différents points d’utilisation ici.

Installation

slapOrm ne bénéficit pas encore d’une validation dans les dépôts officiels des plugin de symfony aussi nous allons donc opter pour une installation manuel ! Le plus simple est de télécharger et d’extraire les sources du plugin dans le dossier « plugins » de symfony.

$ wget http://download.github.com/chanmix51-slapOrm-472ba3c.tar.gz
$ tar xvf chanmix51-slapOrm-472ba3c.tar.gz -C /path/vers/dossier/plugins/
$ mv /path/vers/dossier/plugins/chanmix51-slapOrm-472ba3c /path/vers/dossier/plugins/slapOrmPlugin

Ceci est bien entendu à adapter à la dernière version du plugin.

Une fois ceci effectué nous allons activer le plugin dans la configuration de symfony. Editer donc le fichier config/ProjectConfiguration.class.php et activer le plugin

$ vi config/ProjectConfiguration.class.php

public function setup()

{

$this->enablePlugins(‘slapOrmPlugin’);

….

}

Vous avez maintenant installé le plugin. Vous remarquerez que deux nouvelles actions sont disponible avec la commande symfony.

slaporm
:build-form                  Generate forms associated to the LDAP model classes
:build-model                 Generate LDAP model classes based on the schema definition

Sans plus attendre continuons la configuration pour nous connecter au serveur LDAP.

Connexion au serveur

La connexion au serveur LDAP se fait avec le fichier de configuration de l’application (les variables de configuration app_ldap_host, app_ldap_port, app_ldap_dn et app_ldap_pass). Nous allons donc éditer notre fichier de configuration app.yml de notre application (ici frontend) et remplir le fichier avec les options correspondantes à nos besoins.

$ vi apps/frontend/config/app.yml

all:
ldap:
host: 127.0.0.1
port: 389
dn: cn=admin,ou=users,dc=exemple,dc=com
pass: password

Création du schéma

Nous allons maintenant configurer le schéma de notre ORM. C’est ici que nous allons spécifier les emplacements de nos entrées dans l’annuaire ainsi que les classes et attributs qui lui sont liés. Ils nous faut donc savoir plusieurs choses :

– Le nom que nous voulons donner à l’objet (le nom de la classe qui sera généré)

– L’emplacement dans la hiérarchie des entités et leur nomination (le dn et rdn, ex : ou=users,dc=exemple,dc=com pour le dn et cn pour le rdn)

– Les « objectClass » utilisé par l’objet (ex: inetOrgPerson, posixAccount)

– les attributs utilisés (ex: sn, cn, mail, …)

Il nous faut ensuite construire un fichier schema.yml dans le dossier config/slaporm construit de la sorte

ObjectName:
dn: « ou=here,dc=exemple,dc=com »
objectClass: [objectClass1, objectClass2]
rdn: myRdn
attributes:
attributes1:         { type: attributeType, param1: value, param2: value }
attributes2:         { type: attributeType, param1: value, param2: value }
attributes3:         { type: attributeType, param1: value, param2: value }

Le paramètre type peut contenir une valeurs parmis les suivantes : dn, integer, mail ou string ceci modifiant le conportemant du plugin en ce qui concerne la génération automatique de formulaire.

Voici un exemple de fichier de configuration schema.yml

User:
dn: « ou=users,dc=exemple,dc=com »
objectClass: [posixAccount, inetOrgPerson]
rdn: cn
attributes:
cn:         { type: string, length: 32768, multiple: false, required: true }
gidNumber:  { type: string, length: 32768,  multiple: false, required: true }
givenName:  { type: string, length: 32768, multiple: false }
homeDirectory: { type: string, length: 32768, multiple: false, required: true }
mail:  { type: mail, multiple: false }
sn:         { type: string, length: 32768, multiple: false }
uid:         { type: string, length: 32768, multiple: true, required: true }
uidNumber:  { type: string, length; 32769, multiple: false, required: true }
userPassword:         { type: string, length: 32768, multiple: false }

Group:
dn: « ou=groups,dc=exemple,dc=com »
objectClass: [posixGroup]
rdn: cn
attributes:
cn:     { type: string, length: 32768, multiple: false, required: true }
gidnumber: { type: string, length: 32768, multiple: false, required: true }
userpassword: { type: string, length: 32768, multiple: false }
memberuid: { type: string, length: 32768, multiple: true }
description: { type: string, length: 32768, multiple: false }

Attention à bien respecter les espaces (toujours par groupe de deux).

Créer une entrée

La création d’une entrée est donc intimement lié à la création d’un objet ! Ici nous allons créer une entrée de type « User » définit plus haut. Pour cela nous instantion la classe User et utilisons les fonctions magique de type set et get pour spécifier les attributs de l’objet. Attention tout de même tout les fonctions set et get pour fonctionner doivent n’avoir qu’une majuscule : La première lettre du nom de l’attribut sa suite étant en minuscule. Si vous spécifier une autre majuscule elle sera automatiquement mis en minuscule et précédé par un « underscore » (_).

La sauvegarde de l’objet dans l’annuaire est quand à elle réalisé par la « classe map » de la classe entité expliqué ci dessus. Ainsi nous pouvons sur n’importe qu’elle classe entité utiliser la fonction getMapInstance().

Puisqu’il n’y a rien de plus compréhensible qu’un peu de code

$user = new User();
$user->setCn(« toto4 »);
$user->setGidnumber(« 10001 »);
$user->setHomedirectory(« /home/toto4 »);
$user->setUid(array(« toto »));
$user->setUidnumber(« 1004 »);
$user->setUserpassword(« toto »);
$user->setSn(array(‘toto4’));
$user->setMail(array(‘romain42@gmail.com’));
$user->getMapInstance()->save($user);

Attention tout de même si vous avez des attributs de type boolean (1.3.6.1.4.1.1466.115.121.1.7) vous devez spécifier TRUE ou FALSE (en majuscule).

Récupérer un ou plusieurs objets

Le plus simple pour récupérer des informations est de récupérer toutes les entités pour une classe entité données (Exemple: récupérer tout les utilisateurs). Pour ceci dans la classe Map il suffit d’exécuter la fonction findAll(). Exemple

$users   = SlapOrm::getMapInstanceOf(‘User’)->findAll();
?>
There are <?php echo count($users) ?> users in this result:
<ul>
<?php foreach($users as $user): ?>
<li><?php echo $user->getCn() ?> has mail : <?php echo $user->getMail() ?></li>
<?php endforeach ?>
</ul>

Il existe aussi la fonction getByRdn qui vous permet de rechercher une entités à l’aide de son RDN. Exemple

$user = SlapOrm::getMapInstanceOf(‘User’)->getByRdn(« lermit »);

Enfin pour rechercher au plus fin il existe aussi les fonctions addAndFilter et addOrFilter qui sont détaillées dans la documentation officielle.

Références

* GitHud de slapOrm : https://github.com/chanmix51/slapOrm/wiki
* Site du langage YAML : http://www.yaml.org/

Si vous avez apprécié cet article, pensé à laissé un commentaire ou vous abonner au flux RSS feed.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *