Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way of using "before_filter :authenticate_user!" together with a boolean in the table?

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)?

like image 310
alexchenco Avatar asked Nov 01 '12 04:11

alexchenco


3 Answers

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
like image 124
antiqe Avatar answered Oct 12 '22 10:10

antiqe


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.

like image 42
Ryan Bigg Avatar answered Oct 12 '22 10:10

Ryan Bigg


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
like image 38
alexs333 Avatar answered Oct 12 '22 10:10

alexs333