Giter Club home page Giter Club logo

cancan's Introduction

CanCan

Wiki | RDocs | Screencast | Metrics

CanCan is an authorization solution for Ruby on Rails. This restricts what a given user is allowed to access throughout the application. It is completely decoupled from any role based implementation and focusses on keeping permission logic in a single location (the Ability class) so it is not duplicated across controllers, views, and database queries.

This assumes you already have authentication (such as Authlogic or Devise) that provides a current_user method which CanCan relies on. See Changing Defaults if you need different behavior.

Installation

CanCan is provided as a gem. Simply include it in your environment.rb or Gemfile.

config.gem "cancan"

Alternatively it can be installed as a plugin.

script/plugin install git://github.com/ryanb/cancan.git

Getting Started

First, define a class called Ability in “models/ability.rb”. It should look something like this.

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.admin?
      can :manage, :all
    else
      can :read, :all
    end
  end
end

This is where all permissions will go. See the “Defining Abilities” section below for more information.

The current user’s permissions can be accessed using the “can?” and “cannot?” methods in the view and controller.

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

See Checking Abilities for more information

The “authorize!” method in the controller will raise an exception if the user is not able to perform the given action.

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

Setting this for every action can be tedious, therefore the load_and_authorize_resource method is provided to automatically authorize all actions in a RESTful style resource controller. It will use a before filter to load the resource into an instance variable and authorize it for each action.

class ArticlesController < ApplicationController
  load_and_authorize_resource

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

See Authorizing Controller Actions for more information

If the user authorization fails, a CanCan::AccessDenied exception will be raised. You can catch this and modify its behavior in the ApplicationController.

class ApplicationController < ActionController::Base
  rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = exception.message
    redirect_to root_url
  end
end

See Exception Handling for more information.

Defining Abilities

As shown above, the Ability class is where all user permissions are defined. The user model is passed into the initialize method so the permissions can be modified based on any user attributes. CanCan makes no assumptions about how roles are handled in your application. See Role Based Authorization for an example.

The can method is used to define permissions and requires two arguments. The first one is the action you’re setting the permission for, the second one is the class of object you’re setting it on.

can :update, Article

You can pass an array for either of these parameters to match any one. In this case the user will have the ability to update or destroy both articles and comments.

can [:update, :destroy], [Article, Comment]

Use :manage to represent any action and :all to represent any class. Here are some examples.

can :manage, Article   # has permissions to do anything to articles
can :read, :all        # has permission to read any model
can :manage, :all      # has permission to do anything to any model

You can pass a hash of conditions as the third argument to further restrict what the user is able to access. Here the user will only have permission to read active projects which he owns.

can :read, Project, :active => true, :user_id => user.id

See Defining Abilities with Hashes for more information.

Blocks can also be used if you need more control.

can :update, Project do |project|
  project && project.groups.include?(user.group)
end

If the block returns true then the user has that :update ability for that project, otherwise he will be denied access. See Defining Abilities with Blocks for more information.

Aliasing Actions

You will usually be working with four actions when defining and checking permissions: :read, :create, :update, :destroy. These aren’t the same as the 7 RESTful actions in Rails. CanCan automatically adds some default aliases for mapping those actions.

alias_action :index, :show, :to => :read
alias_action :new, :to => :create
alias_action :edit, :to => :update

Notice the edit action is aliased to update. If the user is able to update a record he also has permission to edit it. You can define your own aliases in the Ability class

alias_action :update, :destroy, :to => :modify
can :modify, Comment
can? :update, Comment # => true

See Custom Actions for information on adding other actions.

Fetching Records

In the controller index action you may want to fetch only the records which the user has permission to read. You can do this with the accessible_by scope.

@articles = Article.accessible_by(current_ability)

See Fetching Records for more information.

Additional Docs

Special Thanks

CanCan was inspired by declarative_authorization and aegis. Many thanks to the authors and contributors.

cancan's People

Contributors

dchelimsky avatar logandk avatar ryanb avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.