Solutions for use with Doorkeeper / API?
adambedford opened this issue · comments
I'm trying to figure out the best way to implement user impersonation with an Ember app and Doorkeeper. Has anyone had success using pretender with Doorkeeper?
One thought I've had: Switch Rails session store from cookie_store
to a Redis store so that sessions on the API work, however this violates the principles of REST since context is maintained on the server across requests.
Would love to hear potential solutions!
Hey @adambedford, I personally haven't tried it with Doorkeeper. Stack Overflow may be a more visible place for this question - this place is a bit quiet :)
Hey guys
I searched stackoverflow but didn't find this question... In any case I needed this too and after a couple hours I took a solution I wasn't too proud of but which worked.
Essentially I am using the database to store the ID of the user my true_user is impersonating and make sure to maintain that ID and utilize it appropriately:
module Admin
class UsersController < Admin::ApplicationController
def impersonate
user = User.find(params[:id])
impersonate_user(user)
true_user.update_attribute(:impersonating_user_id, user.id)
redirect_to root_path
end
def stop_impersonating
stop_impersonating_user
true_user.update_attribute(:impersonating_user_id, nil)
redirect_to root_path
end
end
end
and then using it in a doorkeeper context:
module Api
module V1
class OauthController < ActionController::API
before_action :doorkeeper_authorize!
def oauth_user
if user = current_resource_owner
render json: { email: user.email }
else
render json: {}, status: :forbidden
end
end
private
def current_resource_owner
if doorkeeper_token
u = User.find(doorkeeper_token.resource_owner_id)
if u.impersonating_user_id
u = User.find(u.impersonating_user_id)
end
end
u
end
end
end
end
Anyway not the best solution, but it's doing the trick. If someone finds a better way to do it (e.g. without having to use the persistence layer) I'd like to know it. I dug around in the pretender and the doorkeeper sources for an opportunity but not for too long...
I guess the core-problem is that Doorkeeper
does use ActionController::Base
as default controller (But Pretender gets inserted into the ApplicationController
via impersonates :user
)
Thus setting inside config/initializers/doorkeeper.rb
:
base_controller 'ApplicationController'
solved all issues for me.