Curious if anybody has implemented a "become user" feature (or this is even possible with JWT)? It is very helpful for support purposes to see the exact screens of a given user's account.
I've done this before with devise. Anybody tried the same with knock / have ideas of how to do it?
My first thinking would be to override from_token_request and from_token_payload. Logic would be something like:
So, I ended up implementing this via a monkey patch (eww, I know). Basically I require a user to have a role of superadmin, at which point I'll allow authentication to happen against their account but then the entity that is loaded is the target user's account. Seems to work well so far.
Here is the code I used for future reference:
# lib/core_extentions/knock/auth_token_controller.rb
Knock::AuthTokenController.class_eval do
private
def authenticate
# if "become" is present then auth as the core user (not as the entity)
become = request.params["become"]
if become
u = User.find_by email: auth_params[:email], active: true, role: :superadmin
unless u.present? && u.authenticate(auth_params[:password])
raise Knock.not_found_exception_class
end
return true
end
unless entity.present? && entity.authenticate(auth_params[:password])
raise Knock.not_found_exception_class
end
end
end
# models/user.rb
def self.from_token_request request
# entity_class.find_by email: auth_params[:email]
# Returns a valid user, `nil` or raise `Knock.not_found_exception_class_name`
# e.g.
email = request.params["auth"] && request.params["auth"]["email"]
# check if a request has been made to "become" another user, if so the
# user must have a role of 'superadmin'
become = request.params["become"]
if become
u = self.find_by email: email, active: true, role: :superadmin
email = become if u.present?
end
self.find_by email: email, active: true
end
Thanks, @krsyoung ! I'm surprised this doesn't have any more comments on it. It's a very helpful issue. If Knock was more presently-maintained I'd say it should be included in the main documentation..
Most helpful comment
So, I ended up implementing this via a monkey patch (eww, I know). Basically I require a user to have a role of
superadmin, at which point I'll allow authentication to happen against their account but then the entity that is loaded is the target user's account. Seems to work well so far.Here is the code I used for future reference: