Recherche…


Introduction

CanCan est une stratégie d'autorisation simple pour Rails qui est découplée des rôles d'utilisateur. Toutes les autorisations sont stockées dans un seul emplacement.

Remarques

Avant d’utiliser CanCan, n’oubliez pas de créer des utilisateurs soit par gem, soit manuellement. Pour obtenir un maximum de fonctionnalités de CanCan, créez un utilisateur Admin.

Commencer avec CanCan

CanCan est une bibliothèque d'autorisation populaire pour Ruby on Rails qui restreint l'accès des utilisateurs à des ressources spécifiques. Le dernier bijou (CanCanCan) est une continuation du projet mort CanCan .

Les autorisations sont définies dans la classe Ability et peuvent être utilisées à partir de contrôleurs, de vues, de helpers ou de tout autre endroit du code.

Pour ajouter un support d'autorisation à une application, ajoutez le joyau CanCanCan au Gemfile :

gem 'cancancan'

Ensuite, définissez la classe de capacité:

# app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
  end
end

Ensuite, vérifiez l'autorisation à l'aide de load_and_authorize_resource pour charger les modèles autorisés dans le contrôleur:

class ArticlesController < ApplicationController
  load_and_authorize_resource

  def show
    # @article is already loaded and authorized
  end
end

authorize! vérifier l'autorisation ou lever une exception

def show
  @article = Article.find(params[:id])
  authorize! :read, @article
end

can? vérifier si un objet est autorisé par rapport à une action particulière dans les contrôleurs, les vues ou les assistants

<% if can? :update, @article %>
  <%= link_to "Edit", edit_article_path(@article) %>
<% end %>

Remarque: Cela suppose que l'utilisateur signé est fourni par la méthode current_user .

Définir les capacités

Les capacités sont définies dans la classe Ability utilisant les méthodes can et cannot . Considérez l'exemple ci-dessous pour la référence de base:

class Ability
  include CanCan::Ability

  def initialize(user)
    # for any visitor or user
    can :read, Article

    if user
      if user.admin?
        # admins can do any action on any model or action
        can :manage, :all
      else
        # regular users can read all content
        can :read, :all
        # and edit, update and destroy their own user only
        can [:edit, :destroy], User, id: user_id
        # but cannot read hidden articles
        cannot :read, Article, hidden: true
      end
    else
      # only unlogged visitors can visit a sign_up page:
      can :read, :sign_up
    end
  end
end

Gérer un grand nombre de capacités

Une fois que le nombre de définitions de capacités commence à augmenter, il devient de plus en plus difficile de gérer le fichier Ability.

La première stratégie pour gérer ces problèmes consiste à déplacer des capacités dans des méthodes significatives, comme dans cet exemple:

class Ability
  include CanCan::Ability

  def initialize(user)
    anyone_abilities 

    if user
      if user.admin?
        admin_abilities
      else
        authenticated_abilities
      end
    else
      guest_abilities
    end
  end

  private
  
  def anyone_abilities
    # define abilities for everyone, both logged users and visitors
  end

  def guest_abilities
    # define abilities for visitors only
  end

  def authenticated_abilities
    # define abilities for logged users only
  end

  def admin_abilities
    # define abilities for admins only
  end
end

Une fois que cette classe est devenue suffisamment importante, vous pouvez essayer de la diviser en différentes classes pour gérer les différentes responsabilités comme ceci:

# app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    self.merge Abilities::Everyone.new(user)

    if user
      if user.admin?
        self.merge Abilities::Admin.new(user)
      else
        self.merge Abilities::Authenticated.new(user)
      end
    else
      self.merge Abilities::Guest.new(user)
    end
  end
end

et définissez ensuite ces classes comme suit:

# app/models/abilities/guest.rb
module Abilities
  class Guest
    include CanCan::Ability

    def initialize(user)
      # Abilities for anonymous visitors only
    end
  end
end

et ainsi de suite avec des Abilities::Authenticated , Abilities::Admin ou tout autre.

Testez rapidement une capacité

Si vous souhaitez tester rapidement si une classe de capacité donne les autorisations correctes, vous pouvez initialiser une capacité dans la console ou dans un autre contexte avec l'environnement des rails chargé, il suffit de passer une instance d'utilisateur à tester:

test_ability = Ability.new(User.first)
test_ability.can?(:show, Post) #=> true
other_ability = Ability.new(RestrictedUser.first)
other_ability.cannot?(:show, Post) #=> true

Plus d'informations: https://github.com/ryanb/cancan/wiki/Testing-Abilities



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow