ankane / pretender

Log in as another user in Rails

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.