Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to ban/block users with Devise for Rails?

I'm using Devise for authentication in my rails app and I'd like to be able to block certain accounts and prevent users from reregistering with a blocked email. I'm just not sure what the best way is to go about it.

My first thought was to override the sessions and registrations controllers to check the model for a user with a blocked bit, but I have a feeling there might be a more elegant way.

like image 978
rxb Avatar asked Oct 08 '10 23:10

rxb


3 Answers

The best approach is to do it in Devise way:

Below assumes that you are using Devise database_authenticatable module and your application's users model names User.

1. Implement an account_active? method.

Add boolean account_active column in users table or define account_active? method in User model (you can chose your own method name). For example:

    # app/models/user.rb
    def account_active?
      blocked_at.nil?
    end

2. Overwrite the active_for_authentication? method in your model (User).

    # app/models/user.rb
    def active_for_authentication?
      super && account_active?
    end

3. Add method which returns translation for flash message.

Whenever active_for_authentication? returns false, Devise asks the reason why your model is inactive using the inactive_message method.

    # app/models/user.rb 
    def inactive_message
      account_active? ? super : :locked
    end

And that's it. You don't need to care about sign_out or redirect_to user.

Moreover, user is locked immediately, with next request, not after next sign in.

More: devise/authenticatable.rb.

like image 164
sampi Avatar answered Nov 01 '22 04:11

sampi


I would do it like this:

def after_sign_in_path_for(resource)
  if resource.is_a?(User) && resource.banned?
    sign_out resource
    banned_user_path
  else
   super
  end
end
like image 37
DinoR Avatar answered Nov 01 '22 05:11

DinoR


A better solution is to override the active_for_authentication? method on the devise model (User). Like so:

    def active_for_authentication?
      super && !self.banned?
    end
like image 5
iwiznia Avatar answered Nov 01 '22 04:11

iwiznia