Code Monkey home page Code Monkey logo

cancan_readme's Introduction

Authorization with CancanCan

Objectives

  1. Understand how to create an Ability class.
  2. Learn how to model permissions in the database.
  3. Prevent users from accessing certain actions from the controller.
  4. Prevent users from seeing certain pieces of the view.

Overview

We have been looking at different modes of authentication. Now, we'll shift our focus, and start dealing with authorization: how do you describe a permissions model, and how do you implement it in Rails?

(Also, in case you were wondering, standard UNIX permissions let you delete a file you don't own and can't write to. You must, however, be able to write to the directory that contains the file.)

CancanCan

CanCanCan is a gem for Rails that provides a simple but quite flexible way to authorize users to perform actions. It's the continuation of a no longer maintained gem CanCan.

In your controllers, it looks like this:

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

Here we're calling CanCanCan's authorize! method to determine if the user can :read this @article. If they can't, an exception is thrown.

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

class ArticlesController < ApplicationController
  load_and_authorize_resource

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

##Handling Unauthorized Access

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|
    redirect_to root_url, :alert => exception.message
  end
end

In your views, it might look like this:

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

Or maybe this:

   <% if cannot? :update, @article %>
     Editing disabled.
   <% end %>

##Abilities To generate the ability file you can run rails g cancan:ability

This creates an ability.rb file in your models directory with an Ability class inside.

To define the permissions, you fill out the Ability class, which goes a bit like this:

    class Ability
      include CanCan::Ability

      def initialize(user)
        if user.admin?
          # only admins can change things
          can :update, Article
        end
        # but anyone can read them
        can :read, Article
      end
    end

Your Ability class is passed an instance of your User model by calling the current_user method. In the initializer, you call can or cannot to define what this particular user can do.

can and cannot both take these arguments: --the action, written as a symbol --an ActiveRecord class, an instance of which is the target of the action.

You can be more specific if you want to allow or disallow actions based on information in the models. For example,

    can :write, Article, owner_id: user.id

This will let the user write any article whose owner_id is her user id. (That is, any Article she owns).

    can :read, Article, :category => { :visible => true }

This will let the user :read any Article whose category's visible column is true.

CanCanCan doesn't make any assumptions about how you've stored permission information in your user model. It's up to you to add the appropriate fields to support your authorization scheme.

A simple scheme

Here is a basic CanCanCan Ability class for a message board.

The rules are: anyone can post. Registered users can edit their post after posting (but not delete it). Moderators can do anything to any post.

    class Ability
      include CanCan::Ability

      def initialize(user)
        can :read, Post
      	can :create, Post
        unless user.nil? # guest
          # CanCan accepts a hash of conditions;
          # here, we're saying that the Post's user_id
          # needs to match the requesting User's id
      	  can :update, Post, { user_id: user.id }
      	end
      	if user.admin?
      	  can :manage, Post
      	end
      end
    end

:manage is a special CanCanCan action which means "any action". So users with an admin column set to true can do anything to any Post.

Video Review

Resources

cancan_readme's People

Contributors

annjohn avatar aturkewi avatar authorbeard avatar blake41 avatar dkennell avatar dom-mc avatar franknowinski avatar gj avatar imkaruna avatar joelachance avatar jonbf avatar maxwellbenton avatar mendelb avatar pletcher avatar queerviolet avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cancan_readme's Issues

overview beginning section

it might be worth discussing authorization vs authentication in a readme that opens the whole section and lists the various gems which are commonly used to do both, combinations of gems people use etc. use this readme to focus on the details of how to use cancan

CanCan Gem

@queerviolet I think this is the old version of the gem. Can you update this readme and the lab with any API changes to the newer version of the gem cancancan?

Not sure last example is accurate

The text states that 'users can edit their post after posting', but the code seems to say that any user can edit any other user's posts:

unless user.nil? # guest
   can :update, Post
end

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.