-
Notifications
You must be signed in to change notification settings - Fork 0
Step10: Setting Up Authorization Using CanCan and Rolify
Inspired by Daniel Kehoe's example application using Devise, CanCan, and Bootstrap. This authorizaiton implementation uses CanCan and Rolify
-
Generate an ability class for CanCan:
rails g cancan:ability
-
Set up roles with the Rolify gem:
$ rails g rolify:role Role User
and$ rake db:migrate
-
Uncomment the line
# config.use_dynamic_shortcuts
inconfig/initializers/rolify.rb
to enable dynamic shortcuts likeuser.is_admin?
-
If you followed the instructions for installing Figaro, place an array of roles in your application.yml file. In this case, we're using ROLES: [admin, developer, user].
-
Seed the database with the roles and an admin user, whose credentials you can also place in your application.yml file:
YAML.load(ENV['ROLES']).each do |role| Role.create!(:name => role) puts 'role: ' << role end puts 'DEFAULT USERS' admin = User.create!( :name=> ENV['ADMIN_NAME'].dup, :email => ENV['ADMIN_EMAIL'].dup, :username => ENV['ADMIN_USERNAME'].dup, :password => ENV['ADMIN_PASSWORD'].dup, :password_confirmation => ENV['ADMIN_PASSWORD'].dup, :confirmed_at => Time.now) puts 'admin: ' << admin.name admin.add_role :admin developer = User.create!( :name=> 'Developer 1', :email => 'developer1@example.com', :username => 'developer1', :password => 'password55', :password_confirmation => 'password55', :confirmed_at => Time.now) developer.add_role :developer puts 'developer: ' << developer.name
user = User.create!( :name=> 'User 1',:email => 'user1@example.com', :username => 'user1', :password => 'password55', :password_confirmation => 'password55', :confirmed_at => Time.now) user.add_role :user puts 'user: ' << user.name ```
and run rake db:seed
-
In
app/models/ability.rb
specify the following basic abilities as follows:
def initialize(user) user ||= User.new # guest user (not logged in) if user.has_role?(:admin) can :manage, :all else can :read, :all if user.has_role? :developer can :read, :users if user.has_role? :user end end ```
-
Add
load_and_authorize_resource
tousers_controller.rb
and run$ rake db:test:prepare
again -
Add
user.add_role :admin
tospec/support/controller_macros.rb
just before signing in the user. -
Add the following to
controllers/application_controller.rb
:
rescue_from CanCan::AccessDenied do |exception| redirect_to root_url, :alert => exception.message end ```
to catch the CanCan::AccessDenied exception that's raised when user authorization fails. All tests should now be passing.