Vous avez développé une petite application pour vos propres besoins, par exemple un outil de publication en ligne. Des gens l’ont remarquée et ont commencé à s’y intéresser, au point que vous la publiiez sous une licence quelconque, pour le plus grand bien de la communauté. Et un jour, ce qui allait très bien pour une seule personne ne suffit plus, et vous décidez de franchir le pas : rendre votre application multi utilisateurs. Belle initiative, mais par où commencer ?

Quels utilisateurs ?

Commencez par remettre à plat l’ensemble des fonctionnalités de votre outil. Recensez chacune d’entre elles et classez les par groupe en fonction des utilisateurs “type” qui seront amenés à les utiliser.

Dans notre cas, nous séparons les fonctionnalités de l’application en 3 groupes distincts :

L’administration
  • La configuration.
  • Le paramètrage du thème.
  • La sélection des greffons.
  • La gestion des utilisateurs.
La publication
  • La gestion / publication des billets.
  • La gestion des catégories.
  • La gestion des média.
  • La modération des commentaires.
La contribution
  • Ajout de commentaires.

Et voilà, nous avons défini 3 profils types, et défini leurs attributions possibles. Nous aurions pu en définir plus, par exemple un rédacteur qui aurait des droits d’écriture mais pas de publication, ou un modérateur pour les contributions qui n’aurait pas de droits en écriture, mais nous choisissons la simplicité. Reste maintenant à l’implémenter dans notre application, et là, deux choix s’offrent à nous.

Implémentation par profils

L’implémentation par profils est la plus simple à mettre en oeuvre, au détriment de la souplesse. On attribue un profil à chaque utilisateur, puis, pour chacune des actions possibles, on contrôle le profil de l’utilisateur, et on agit en conséquence. Pour cela, on va créer 3 méthodes, vérifiant que l’utilisateur dispose bien du profil voulu :

def is_admin
  si notre utilisateur a le profil administrateur 
    alors la condition est vérifiée
  sinon elle est fausse
end

def is_publisher
  si notre utilisateur a le profil rédacteur  
    ou que notre utilisateur a le profil administrateur 
    alors la condition est vérifiée
  sinon elle est fausse
end

def is_contributor
  si notre utilisateur a le profil contributeur
    ou que notre utilisateur a le profil a le profil rédacteur
    ou que notre utilisateur a le profil administrateur
    alors la condition est vérifiée
  sinon elle est fausse
end

Vous remarquerez que pour chaque profil inférieur, on vérifie également que l’utilisateur dispose du profil supérieur. En effet, on considère que les utilisateurs hiérarchiquement les plus élevés disposent de fait des droits les plus bas.

Implémentation par droits

Beaucoup plus complexe à mettre en place, l’implémentation par droit est en revanche extraordinairement souple. Elle ne convient cependant pas à n’importe quelle application car elle a son petit effet “usine à gaz”, vous pèserez donc bien le pour et le contre avant de la mettre en place.

Le principe est simple : vous définissez une série de droits ; chacun de ces droits correspond à une action possible sur l’application : créer une catégorie, modifier un billet, effacer un commentaire, afficher la liste des utilisateurs… Vous remarquerez au passage que ce système de droits repose sur le CRUD (Create, Read, Update, Delete) et trouve tout à fait sa place dans une application RESTful, mais je m’égare. Une fois définis les droits, vous créez les profils fonctionnels que nous avons vus tout à l’heure, et vous leur attribuez les droits qui vont bien. L’administrateur les aura à priori tous, le contributeur n’en aura que très peu. Pour cela, faites un tableau de correspondance entre les deux. Il y a d’ailleurs de fortes chances pour que vous ayez le même dans votre application :

Droits Administrateur Rédacteur Contributeur
Créer un billet X X
Ajouter un utilisateur X
Ajouter un commentaire X X X

Vous assignez ensuite un profil à chaque utilisateur. Pour chaque action possible, vous vérifierez que l’utilisateur dispose bien du droit adéquat. Pour cela, on va créer une méthode toute simple :

def has_right(droit)
  si notre utilisateur a le droit correspondant
    alors la condition est vérifiée
  sinon elle est fausse
end

Deux choses rendent cette implémentation par droits formidablement souple :

  • Vous pouvez ajouter autant de profils que vous le souhaitez, puisque ceux-ci ne sont que des conteneurs à doits. Les droits sont en effet liés à l’utilisateur et le profil ne sert qu’à les grouper.
  • Vous pouvez très facilement surcharger un profil en attribuant ou supprimant des droits à un utilisateur spécifique.

Et maintenant ?

Il ne vous reste plus qu’à vous mettre au travail, en réfléchissant bien à ce que vous souhaitez faire de votre application. Chaque système a ses avantages et ses inconvénients, et passer de l’un à l’autre est tout sauf évident.

jupiler, je sais pourquoi

Et pour ceux qui pensent que ce billet est une réflexion sur ce que pourrait devenir Typo dans un futur proche, vous vous trompez. 50% du code est déjà fait, il me reste à le propager à l’ensemble de l’application.

Perry the Platypus wants you to subscribe now! Even if you don't visit my site on a regular basis, you can get the latest posts delivered to you for free via Email: