1

I have an app that is using CacCan and Devise. I am having Devise handle the User destroy action

The route

DELETE /users(.:format)    devise/registrations#destroy

My Controller

class UsersController < ApplicationController
  skip_before_filter :authenticate_user!, :only => :portfolio

  def index
    redirect_to dashboard_user_path(current_user)
  end

  def dashboard
    ...
  end

  def portfolio
  end
end

My ability.rb

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    if user.role?('Administrator')
      can :access, :rails_admin
      can :dashboard
      can :manage, :all
    else
      cannot :destroy, User
      can :read, :all
      ...
    end
  end
end

This code above does not work. A user who is not an administrator still has the ability to delete a user. I am assuming the reason is that I do not have UsersController#destroy method.

So my question is, How do I make CanCan prevent a user who is not an administrator from being able to delete a user?

Any help would be greatly appreciated.

Thanks

user2517182
  • 1,241
  • 3
  • 15
  • 37

1 Answers1

0

It seems to me that you defined abilities but not use them at all.

I suggest to read at least this (gem has a reach wiki with very useful information so it worth to read all articles). I prefer to use powerful load_and_authorize_resource but in you case maybe enough authorize! (code is NOT tested!)

def destroy
  @user = User.find(params[:id])
  authorize! :destroy, @user
  ...
end
gotva
  • 5,919
  • 2
  • 25
  • 35
  • Thanks for the answer. I tried authorize! with load_and_authorize_resource and the delete still happen for a user that is not an admin. I was wondering if there was a way to implement authorization on an action that is called from Devise. The reason I say this is; I could create a method in my controller and a route for that method. Then make the changes you suggested. But it would not stop some one from running devise/registrations#destroy which would delete a user. – user2517182 Nov 21 '13 at 04:22
  • well I think (but I am not sure) that destroy route goes to another controller/action. I found several examples: [this](http://stackoverflow.com/questions/16289299/rails-how-to-destroy-users-created-under-devise) asserts that devise does not provide `destroy` action, [devise wiki](https://github.com/plataformatec/devise/wiki/How-To:-Disable-user-from-destroying-his-account) provides another example. I suggest to check if your action works when user destroys account - then debug ability else try to implement devise example and apply `authorize` there. – gotva Nov 21 '13 at 06:12
  • The first line in Devise::RegistrationsController#destroy is resource.destroy. I believe this using my User#destroy method. Not sure if I could use the first link, but the second link to the devise wiki seems promising. I will take a look at that and let you know if it works. – user2517182 Nov 25 '13 at 18:52