7

I have a Rails app using Devise for authentication. Users belong to Dealers and I want to prevent users who belong to disabled dealers from being able to sign in.

Is there a straightforward way to extend Devise's authentication finder so that it will not include users from deleted dealers? Perhaps using a named scope on User?

Cheers

Tristan

tristanm
  • 3,337
  • 2
  • 27
  • 40

2 Answers2

16

Turns out all I needed to do was override my user model's find_for_authentication method:

class User < ActiveRecord::Base
  ...

  # Intercept Devise to check if DealershipUser's Dealership is active
  def self.find_for_authentication(conditions)
    user = super
    return nil if user.is_a?(DealershipUser) && user.dealership.deleted?
    user
  end

  ...
end
  1. Find the user in the normal way by calling super.
  2. I'm using STI so I check that the user is a DealershipUser and then check if the dealership is deleted (acts_as_paranoid).
  3. Return the user.

This is a very specific solution for my scenario but you could override find_for_authentication however you like provided you return the user afterwards.

tristanm
  • 3,337
  • 2
  • 27
  • 40
4

Searching Stackoverflow.com gave me this question/answer: Custom authentication strategy for devise

Basically, you have to implement a custom authentication strategy at Warden's level (that underlies Devise). For my project, I did the following:

In config/initializers/devise.rb:

Devise.setup do |config|
  config.warden do |manager|
    manager.default_strategies(:scope => :user).unshift :user_has_login_access
  end
end

Warden::Strategies.add(:user_has_login_access) do
  def valid?
    # pass the commit parameter as 'login' or something like that, so that this strategy only activates when the user is trying to login
    params[:commit] == 'login' 
  end

  def authenticate!
    u = User.find_by_email(params[:user][:email])
    if u.can_login? # retrieves boolean value stored in the User model, set wherever
      success! u
    else
      fail! "Account does not have login privilages."
    end
  end
end

You can read more about custom Warden strategies here: https://github.com/hassox/warden/wiki/Strategies

Hope that helps!

Community
  • 1
  • 1
neezer
  • 19,720
  • 33
  • 121
  • 220
  • Turns out I could override find_for_authentication (see below). Thanks for your answer though, it may have shed some light on another issue I'm working through. – tristanm Dec 15 '10 at 20:20