-
Notifications
You must be signed in to change notification settings - Fork 405
Using rolify with Devise and Authority
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.
- 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'
-
run
bundle install
to install all required gems -
Run Devise generator
# rails generate devise:install
- Create the User model from Devise
# rails generate devise User
- Create the ApplicationAuthorizer from Authority
# rails generate authority:install
- Create the Role class from rolify
# rails generate rolify Role User
- Run migrations
# rake db:migrate
-
Configure Devise according to your needs. Follow the Devise README for details.
-
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
- 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
-
include Authority::UserAbilities
in your User class (to add methods likecan_update?
) andinclude Authority::Abilities
in your models (to add methods likeupdatable_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
- Create some User instances using
rails console
> alice = User.new
> alice.email = "[email protected]"
> alice.password = "test1234"
> alice.save
> bob = User.new
> bob.email = "[email protected]"
> bob.password = "test1234"
> bob.save
> cathy = User.new
> cathy.email = "[email protected]"
> cathy.password = "test1234"
> cathy.save
- Add the admin role to a user.
> alice.add_role "admin"
- 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
- 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
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.