Skip to content

Using rolify with Devise and Authority

eubenesa edited this page Oct 10, 2014 · 10 revisions

Devise + Authority + rolify Tutorial

This Tutorial shows you how to setup a Rails >=3.1 application with a strong and flexible authentication/authorization stack using Devise, Authority and rolify (3.0 and later).

The basic idea is:

  • Devise provides authentication: lets users sign up and sign in, so that you know who they are.
  • rolify helps you assign roles to users and check which roles they have.
  • Authority helps you use those roles, or any other logic you like (user points, info from a single sign on app, etc) to control who can do what.

Installation

  1. First, create a bare new rails app. If you already have an existing app with Devise and Authority set up and you just want to add rolify, just add rolify in your Gemfile, run bundle install and skip to step 6
  • # rails new rolify_tutorial
  • edit the Gemfile and add Devise, Authority and rolify gems:
gem 'devise'
gem 'authority'
gem 'rolify'
  1. run bundle install to install all required gems

  2. Run Devise generator

  • # rails generate devise:install
  1. Create the User model from Devise
  • # rails generate devise User
  1. Create the ApplicationAuthorizer from Authority
  • # rails generate authority:install
  1. Create the Role class from rolify
  • # rails generate rolify Role User
  1. Run migrations
  • # rake db:migrate

Configuration

  1. Configure Devise according to your needs. Follow the Devise README for details.

  2. Edit the ApplicationAuthorizer (created by authority), updating the default method to check for the admin role:

  def self.default(adjective, user)
    user.has_role? :admin
  end

This represents that all actions require the admin role by default. You can then begin adding more specific logic.

  # To update a specific resource instance, you must either own it or be an admin
  def updatable_by?(user)
    resource.author == user || user.has_role?(:admin)
  end
  1. Use rolify's resourcify method in all models you want to put a role on. For example, if we have the Post model:
class Post < ActiveRecord::Base
  resourcify
  belongs_to :author, class_name: 'User'
end
  1. include Authority::UserAbilities in your User class (to add methods like can_update?) and include Authority::Abilities in your models (to add methods like updatable_by?), which will delegate to ApplicationAuthorizer unless you specify a different authorizer class.
class User < ActiveRecord::Base
  include Authority::UserAbilities
  has_many :posts, foreign_key: :author_id
end

...

class Post < ActiveRecord::Base
  resourcify
  include Authority::Abilities
end

Usage

  1. Create some User instances using rails console
> alice = User.new
> alice.email = "alice@example.com"
> alice.password = "test1234"
> alice.save

> bob = User.new
> bob.email = "bob@example.com"
> bob.password = "test1234"
> bob.save

> cathy = User.new
> cathy.email = "cathy@example.com"
> cathy.password = "test1234"
> cathy.save
  1. Add the admin role to a user.
> alice.add_role "admin"
  1. Create a post for a user:
> post = bob.posts.new
> post.title = 'Test Post'
> post.name = 'Test Post'
> post.content = 'Nothing to see here'
> post.save
  1. Check who can update this post.
> bob.can_update?(post) #=> true; he is the author
> alice.can_update?(post) #=> true; she is an admin
> cathy.can_update?(post) #=> false

Configure Authority

Authority provides ways to add enforcement of user authorization to your controllers. You can also configure which adjectives (like updatable_by?) and which verbs (like can_update?) are available in your application. For more info, see the Authority README.