I'm using Devise. I added a admin
boolean column to my users
table:
class AddAdminToUsers < ActiveRecord::Migration
def self.up
add_column :users, :admin, :boolean, :default => false
end
def self.down
remove_column :users, :admin
end
end
I want only allow admins to destroy users.
Devise's before_filter :authenticate_user!
works by only enabling signed in users to perform an action. Is there a way of adding something to :authenticate_user
so that only users with :admin => true
can perform an action (en.g. destroy action)?
before_filter :authenticate_user!
before_filter :is_admin?
def is_admin?
if current_user.admin?
true
else
render :text => 'Who are you to doing this? :)'
end
end
I would highly recommend to put all your admin actions underneath an admin namespace within your application and to use a gem such as CanCanCan for the authorization.
For instance, the action to delete a User
object would be in the UsersController
underneath the Admin
namespace. The controller would basically be defined like this:
class Admin::UsersController < Admin::BaseController
def destroy
user = User.find(params[:id])
user.destroy
redirect_to admin_users_path
end
end
The Admin::BaseController
referenced here is the controller which provides a base for your admin namespace. It should authorize users, like this:
class Admin::BaseController < ApplicationController
before_filter :authenticate_user!
before_filter :authorize_admin
def authorize_admin
authorize! :manage, :all
end
end
The authorize!
helper would be provided by CanCan
. I won't repeat what the CanCan wiki already covers in regard to setting up the Ability
class. CanCan is also covered in a great screencast by the author.
It's inside this Ability
class that you should be checking for that boolean field and then letting CanCan deal with the authorization.
To actually route to this new Admin::UsersController
, define this inside your config/routes.rb
file:
namespace :admin do
resources :users
end
If you don't want to use CanCanCan, there's also Pundit.
It is recommended not to modify behaviour of third party methods such as :authenticate_user!. You can easily achieve by setting up the second filter, which may be as simple as the following :
before_filter :ensure_admin, :only => [:new, :create]
private
def ensure_admin
unless current_user && current_user.admin?
render :text => "You are not authorised to perform this action", :status => :unauthorized
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With