Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails Devise + Devise-bascamper How to allow super user to login to any account?

I'm using devise and devise-basecamper for authentication with my subdomain based web app.

I would like to allow super users to access any of the accounts (basically any subdomain).

I'm not sure how i would go about implementing this so that a user can be authenticated into any subdomain since a user is currently validated against a specific subdomain.

Any ideas?

like image 815
Catfish Avatar asked Dec 11 '22 14:12

Catfish


1 Answers

If I understood correctly your needs, the st approach is to perform the following steps:

  • as an admin be able to "become" another user, in order to access your application as if you used his credential to log-in
  • After "becoming" this user you want to be able to "become" your real user back again whenever you want without having to log-out and log-in again.
  • Keep your admin privileges while you became another user (see bottom of the answer for this)
  • Avoid logs to mention action was perform by the user you "became"

Becoming user

This is necessary if you need to perform actions as another user, or "see what he sees"

First you need to implement the devise's official way (this is pseudo-code, I let you adapt it to your personal situation)

# the usage of session[:original_user_id] is explained later
def become
  if admin? or session[:original_user_id]

    if session[:original_user_id] == params[:id]
      session[:original_user_id] = nil # This is intended to clean-up stuff after you become your self back again
    else
      session[:original_user_id] = current_user.id # This is to record your real identity while you are becoming some one else
    end

    sign_in(:user, User.find(params[:id]))
  end
end

As you see, we "become" the requested user, plus we record in session your real user.id. Note that if you choose this solution you MUST set-up rails to save session data in database, to avoid avoid having those data roaming around in wild cookies.

Becoming your self back again

Second you need somewhere in your view a link to "become back your self", I suggest header as a good location

if session[:original_user_id]
  link_to 'Be my self', become_path(session[:original_user_id])
end

This will create a link, visible only for admin that "became" someone else, and the link will allow you to "become" the user with ID that correspond to your real user account. Clicking on it will bring back your real identity.

Keep your admin privileges while you became another user

Then you want to keep you admin privilege, we need to cheat the system to make him believe that the user you "became" is an admin, but we must protect the application so it won't do unwanted save of this "fake privilege" in the database

In your application controller, implement a before filter

before_filter :fake_admin

def fake_admin
  if session[:original_user_id]
    current_user.fake_admin = true
    current_user.admin = true
  end
end

Then to protect you user record to gain unwanted admin privilege, in your user model you can set a before_save_filter (or before_validation_filter, depending on your architecture)

before_save :check_for_fake_admin

def check_for_fake_admin
  self.admin = false if self.fake_admin
end

Avoid logs to mention the name of the user you became

You have no choice than manually hack all places in your application where an action needs to mention the admin name instead of the user you "became"'s name. Axample in records updated_by must be set to session[:original_user_id] if it is not nil

Now that's needed not only in the logs, but for any other thing. It all depend on your application and it can become very tedious to maintain.

Disclamer

  • This is pseudo code, unsecure and if you choose this solution you would need to enforce security
  • I answer to your question because you asked, but my personal piece of advise is: do not implement this solution, cause it looks like a big security hole, and you should let admin user to log-out and log-in after they become someone else
like image 125
Benj Avatar answered May 03 '23 03:05

Benj