• A la une
  • Catégories
  • Dossiers
  • Rédacteurs
  • +

Tutoriel: Créer une gestion des droits simplifiée pour Rails

par Benjamin SANCHEZle 08/12/2011

Aujourd'hui, nous allons regarder comment mettre en place une gestion des droits simple dans Rails avec Devise.

# Introduction

Vous avez un site à faire où les utilisateurs n'ont pas tous les mêmes droits.

Certains utilisateurs ne peuvent que modifier leurs paramètres à eux, alors que les auteurs peuvent écrire des articles. Les modérateurs, eux, peuvent éditer et supprimer des commentaires, quel que soit l'article sur lequel ils ont été posés. Et bien sur, l'admin, lui, a tout les droits.

Regardons maintenant comment mettre ça en place de manière assez simple.

Prérequis: 

*  Rails
*  Devise (simplement remplaçable, en réalité)

Objectifs: 

*  Pouvoir définir des rôles pour les users.
*  Pouvoir tester simplement si un user appartient à tel ou tel rôle.
*  Pouvoir simplement autoriser ou interdire l’accès à une page/tout un controller à certains rôles.


Postulat: 

*  Votre classe d'utilisateurs est User. 
*  Votre partie admin est dans le module Admin, et tout ses controllers héritent de Admin::ApplicationController. 
*  Votre partie admin est protégée dans son intégralité par Devise.

# Mise en œuvre


Tout d'abord, on vas créer une migration, pour modifier notre table. Nous allons ajouter le champ role_id, qui est un integer, limit => 4, default => 0. Nous l'ajoutons aussi en index, ça peut servir si nous avons besoins de scopes.
Hop, on migre et on s'attaque au model.

Dans le model User, nous allons tout d'abord ajouter notre liste de rôles.
Elle pourrait être séparée, sous forme de classes/yml/autre, mais le sujet de l'article n'est pas là.

Ajoutons donc dans notre classe:

@@roles = [:undefined, :admin, :writer, :moderator, :user]

#pour pouvoir y accéder depuis ailleurs, sans avoir à se répéter
def self.roles
    @@roles
end

Maintenant, il nous faut un moyen de changer le rôle d'un user.

attr_accessible :role

def role
    @@roles[self.role_id || 0] end def role(value)     if role_id = @@roles.index(value)         self.role_id = role_id     end end

Il nous faut aussi le moyen de tester quel est le rôle d'un user.

def is?(roles)
    if roles.class.public_method_defined? :'include?'
        role.include?
 self.role
    else         role == self.role     end end

Voilà, maintenant, nous pouvons simplement tester si l'utilisateur courrant est l'admin, avec current_user.is? :admin, ou bien lui donner des tableaux : current_user.is? [:admin, :writer]. Mais il nous faudrait aussi pouvoir bloquer ou autoriser certains controllers en fonction de son rôle. Pour ça, nous allons utiliser before_filter.

classe Admin::Application < ApplicationController
    before_filter :authenticate_user!
    before_filter :check_authorisation

    def check_authorization

        @@only ||= User.roles
        @@except ||= []
        authorized_roles = @@only - @@except
        unless current_user.is? authorized_roles
            render :file => "#{Rails.root.to_s}/public/401.html", :status => :unauthorized
        end

    end

end


Voilà, tout est en place. Pour définir les utilisateurs autorisés à accéder à une page, il suffit de mettre par exemple @@only = [:admin, :moderator], ou bien @@except = [:undefined, :user], dans le controlleur en question.

Quoi, c'est un peu lourd, comme syntaxe ? Et bien simplifions ! Il suffit d'ajouter ces deux methods dans Admin::Aplication

def self.only(*args)
  @@only = *args
end

def self.except(*args)
  @@except = *args
end

Maintenant, nous pouvons faire.

module Admin  
  class ArticlesControllers < ApplicationControllers
    only :admin, :writer  
  end
end

# Conclusion

Cette gestion de permissions n'est pas encore très bonne. Il faudrait lui ajouter la possibilité d'affiner les permissions en fonction des pages, extraire le code dans des modules, et d'autres choses encore. Mais bon, ce n'est pas grave, son but est avant tout pédagogique. Si vous avez besoin d'une bonne gestion de permissions, je vous recommande la gem CanCan, qui est vraiment très bien pour ça.

 

  • Partager l'article en 1 clic !

    N'hésitez pas à aider le BlogDuWebdesign
Avatar_thumbAuteur : Benjamin voir son blog

Développeur autodidacte depuis quelques années, déjà, je suis le développeur du blog du webdesign, où mon rôle est de concretiser les différentes idées et maquettes.

Devenez membre !

Rejoignez la communauté des créatifs du web !
- Partagez vos créations
- Gagnez en visibilité
- Créez votre blog facilement
> En savoir plus

Créer mon compte

4Commentaires

  • Avatar_thumb
    Webdesign SP

    le 08/12/2011 | #1

    Merci pour cette tutoriel!

  • Avatar_thumb
    Antoine

    le 10/12/2011 | #2

    Merci pour le tuto ! Un peu technique mais je vais me pencher dessus !

  • Avatar_thumb
    Camille

    le 12/12/2011 | #3

    Bravo ! Pour info, tu as un <br> qui s'est glissé dans un de tes bouts de code :)

  • Avatar_thumb
    Benjamin SANCHEZ

    le 12/12/2011 | #4

    Merci beaucoup pour le petit br qui c'était glissé à travers la relecture

Ecrire un commentaire

captcha

Ouvrir