adam12 / rodauth-become_account

Easily switch between Rodauth accounts
14 stars 3 forks source link

Work with rodauth-rails? #3

Closed benoror closed 3 months ago

benoror commented 4 months ago

Is there anything different in particular needed to make it work with janko/rodauth-rails? I try it out on our Administrate panel but it won't change the current_account

Screenshot 2024-07-04 at 10 16 48 a m
adam12 commented 4 months ago

I've never tried it with rodauth-rails so I am not sure, to be honest.

It works simply by modifying the session and simulating a login as the user. During logout, it puts the session back the way it was. It's possible that Rails (or rodauth-rails) does something different with the session outside of what ships with Rack.

Hard to say :\ Sorry I can't be of more assistance.

benoror commented 4 months ago

Thanks a bunch @adam12, I'm gonna dig into rodauth-rails and see if there's something I can figure out!

p.s. Maybe @janko has some insights as well 😄

benoror commented 4 months ago

Well, to get started with I think it has more to do to the fact that I'm not even using the Rails session, but JWT instead (for the API-only part): https://github.com/janko/rodauth-rails?tab=readme-ov-file#install-options

Update: Looks like the Admin side of things should be using Rails session? See comment: https://github.com/adam12/rodauth-become_account/issues/3#issuecomment-2229718172

adam12 commented 4 months ago

That's likely the issue.

janko commented 4 months ago

If the account model was previously loaded by calling #rails_account, then calling #become_account to change #account will not change #rails_account. Not sure how to detect that @account has changed on the Rodauth instance, other than overriding #account_from_{login,session,id} and clearing @rails_account đŸ€”

janko commented 3 months ago

@benoror I just pushed a commit to rodauth-rails main that should refresh #rails_account when #account changed, such as when #become_account is called. Would you mind testing this out when you get the chance?

benoror commented 3 months ago

@janko Thanks! I just checked out latest code HEAD and ran some quick tests.

Apparently it does succesfully change rodauth.rails_account just after executing rodauth.become_account(...)

But in the context of the application it goes back to the old account as soon as a new rout is rendered.

I am suspicious Rails' session, and/or rodauth.session is not being refreshed, but I am not savvy enough and still trying out other things.

Will keep you posted, lmk if you can think of something else in the meantime.

*Worth noting that I originally setup rodauth & rodauth-rails as JSON API only, but the place where I am needing the impersonation is a server-side Rails Admin engine using Administrate Gem, based off this example app:

https://github.com/thoughtbot/administrate/blob/00e262428ac3ab4f27fc585cb97644520a806878/spec/example_app/app/controllers/admin/customers_controller.rb#L3-L11

p.s.: Also made sure current_account always use rodauth.rails_account at the top-level controller(s)

benoror commented 3 months ago

FFWIW I these approaches both individually and in combination:

        rodauth_account = DB[:accounts][id: requested_resource.id]
        rodauth.become_account(rodauth_account)

Inspired from the lib itself: https://github.com/adam12/rodauth-become_account/blob/ec5d5509e5aa3b7f26a018fc679c0c7552c05bf7/lib/rodauth/features/become_account.rb#L14-L18

        session.delete(:account_id)
        session[:user_id] = requested_resource.id
        rodauth.session[rodauth.session_key] = requested_resource.id

From rodauth implementation itself: https://github.com/jeremyevans/rodauth/blob/5d9eb7affafe7fe84f2cb195e377b4683b914ddd/lib/rodauth/features/base.rb

& rodauth-rails as well:

https://github.com/search?q=repo%3Ajanko%2Frodauth-rails%20account_from_&type=code

        rodauth.account_from_login(requested_resource.email)
        rodauth.login_session("password")
benoror commented 3 months ago

Update: Setting only_json? to false and avoiding using rodauth.require_http_basic_auth made it work right out of the box (using simply rodauth.become_account(rodauth_account))

Context: I originally set up my app to be a Rails JSON API app only (followed janko/rodauth-rails/wiki/JSON-API), then when I added Administrate gem I followed the second part of this guide [https://administrate-demo.herokuapp.com/rails_api] to bring back Cookies/Session middlewares in order to enable Authentication (followed https://administrate-demo.herokuapp.com/authentication) using rodauth.require_http_basic_auth

Thesis: The only_json? true config is conflicting somehow with basic_auth and/or Rails session middleware

adam12 commented 3 months ago

Cool. I am not sure there's much to be done on this end. Can we close?

benoror commented 3 months ago

Yes let's consider this closed. If I have new findings I might document it here in case anyone else stumble upon a similar scenario.

Thanks both of you! đŸ–€

adam12 commented 3 months ago

Nice! Thanks for reporting back your findings.