Question

I have separate models for Devise users and admins. I am also using Basecamp style subdomains. Everything is working well except for a few controllers and actions where I need to be able to authenticate as either a user or as an admin.

Currently I have authenticate_user! set in my application_controller.rb and I am skipping it with skip_before_filter for those controllers and actions that only admins should have access to.

Unfortunately I cannot simply specify the authentication requirement on each controller as I will still need some controllers and action to be access by both a User or an Admin.

I have tried a few things to no avail. It seems that if I move the authenticate_user! and authenticate_admin! into some sort of subdomain detection logic it fails to process. Basically:

current_subdomain = request.subdomains.first    
if current_subdomain == 'admin'
 authenticate_admin!
else
 authenticate_user!
end

I was, at one point, able to get it to attempt authentication but for some reason it was failing to except the session controller from needing authentication which resulted in a redirection loop (a first for me with Ruby!).

I realize that I could add a field to my User that denotes admin status, but the application requires a greater separation of powers between User and Admin than that will allow, except for a few controllers and actions.

  • Ruby 1.9.2
  • Rails 3.0.3
  • Devise 1.1.3
Was it helpful?

Solution

Try writing your own before filter along the lines of

#application_controller.rb
def authenticate_any!
    if admin_signed_in?
        true
    else
        authenticate_user!
    end
end

then in the controller where you want both admins and user to be able to have access through authentication use

#myobject_controller.rb
before_filter :authenticate_any!

If you have logged in as an admin then you will pass the before_filter, otherwise you will go through authenticate_user! which is the default behaviour.

OTHER TIPS

Actually this doesn't work:

#application_controller.rb
def authenticate_any!
    if admin_signed_in?
        true
    else
        authenticate_user!
    end
end

It will start an infinite recursion on authenticate user..

try this instead:

def authenticate_user!
  return if admin_signed_in?
  super
end

Just remember that with this second solution you're saying something like this: 'You must be logged in as, at least, user' and you will lose the authentication of users only.

Admins will be able to access everything.

Maybe you should consider additional gem - CanCan to handle roles

Quite nice described here: http://www.tonyamoyal.com/2010/09/29/rails-authentication-with-devise-and-cancan-part-2-restful-resources-for-administrators/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top