Hooking into devise 2.0.5 and rails 3.2
cobbr2 opened this issue · 1 comments
I've had two problems with hooking pretender into our application.
First, just putting the impersonates :user
call into our ApplicationController did not work. We got 'undefined method "current_user"' when we did so. That's because Devise hasn't actually defined that method yet; it's defined when the ActiveSupport.on_load hook is called for ApplicationController, which is later in the Rails startup lifecycle. We've worked around that using:
def current_user
super
end
Secondly, the Very Important thing (calling stop_impersonating_user
before logout) appears to be both more difficult than documented, and unnecessary in our environment. We're using cookie-based (not database-backed) sessions.
Devise provides its own Devise::SessionsController; subclassing it is possible, but requires bringing its views into our own application (note also that it does not provide a logout
method; instead, it has a destroy
).
Since the session appears to be completely destroyed by Devise's destroy
method (and Warden's session handling), I'm wondering what risks might be posed by not calling stop_impersonating_user
.
Less directly, we looked at hooking at Warden's before_logout
callback, but that does not provide the controller object, so makes direct use of stop_impersonating_user
impossible.
We've not encountered the "Security warning" exception in practice while testing.
Am I taking any risks by not calling stop_impersonating_user
before logout?
Hey, so sorry, thought I had responded to this earlier.
First issue - I'll have to dig into it more. May make sense to move the hook into a Railtie.
Second issue - To see if there's a security risk, try this:
- Impersonate a user
- Sign out
- Sign in as a different user, and see if you're still impersonating
As far as I know, Devise does not destroy the entire session - just the Devise data.
If it is an issue, here's how to hook into Devise.
Assuming a User
model, change this in your routes.
devise_for :users, controllers: {sessions: "sessions"}
Then create a SessionsController
with:
class SessionsController < Devise::SessionsController
def destroy
stop_impersonating_user
super
end
end
Again, sorry for the slow response.