Replies: 1 comment 13 replies
-
Hi @bjeanes, thanks for continuing this discussion 👍🏻 Based on what you said, it seems that making methods like As for the account ID in the session, I'm thinking about an So, for current account, params, and session, the Rodauth::Rails.rodauth # account, params, and session are empty
Rodauth::Rails.rodauth(params: { foo: "bar" }) # set mock params
Rodauth::Rails.rodauth(account: Account.find(account_id)) # set @account and session[session_key]
Rodauth::Rails.rodauth(session: { two_factor_auth_setup: true }) # set mock session
Rodauth::Rails.rodauth(env: { ... }) # add more values to Rack env hash Regarding not having to call I also wanted to mention that over the past several weeks I've been working on a mixin for the account AR model, which defines a |
Beta Was this translation helpful? Give feedback.
-
Hey @janko,
This is a continuation of the discussion that started on Reddit last November, which I believe prompted you to add
Rodauth::Rails.rodauth
.In that thread, I linked to a gist which demonstrated what I was doing to
new
up a Roduath auth class instance as an API.Today, I finally have tried to switch to using your upstream method and immediately hit a few obstacles. I was going to open a GH issue initially (which I still may do) but also wanted to re-visit the larger discussion.
First up, the issues I hit with trying to use
Rodauth::Rails.rodauth
:session
raises:param
orrequest.params
raises:RuntimeError: Missing rack.input
Obviously, we are not in a real request setting and I understand that setting a session value (non-cookie session stores aside) won't have any end effect for a user. However, given how much of Roda internals are side-effecting, it isn't practical to be able to call any useful internal methods without touching things like the session.
Furthermore, unless one creates a separate slimmer config for API usage (and consequently risks bugs due to inconsistencies with the primary config), inevitably there will be
before_*
/after_*
hooks which may read params or read&write session store.Lastly, Rodauth core features vary with regard to using
account_id
and usingsession_value
(sometimes for good reason and other times perhaps for historical reasons--I'm not sure). This poses a very real need to address the session store situation and perhaps even pre-filling its contents.In the Reddit thread, you had picked up on my
account_from_id
auth method, which merely sets@account = account_ds(id).first
, but I've found I also need to havesession[session_key] = id
set, so that features usingsession_value
are functional. Another example I've encountered is withactive_sessions
feature where theactive_sessions_ds
is defined in terms ofsession_value
, causing me grief when wanting to delete a user's active sessions after an admin changes the email address. This comes up regularly with compromised accounts (for which we allow users to prove their identity to regain access).Anyway, I was able to work around the params issue by mutating the internal Rack env, like so:
I think setting the query string and form hash out of the box makes sense.
NOTE: in my usage, I actually am passing non-empty params and encoding to query string with
URI.encode_www_form
, because I have hooks which do things like readparam(login_param)
during audit log metadata (i.e. to capture old and new logins). Without having a separate config, I need to contend with this during "API" usage too. I've run into this need often enough, that there is a case for improvingRodauth::Rails.rodauth
to accept params out of the box, but we can defer that discussion.For the issue with touching session, I don't understand it and hitting that after fixing the params issue is what led me to leave this post. It gets really into the weeds with my understanding of the separation between Roda and Rodauth.
Now, as for the broader discussion of "programmable Rodauth"...
There are certainly things which
rodauth-rails
could do to make this use-case better, but I think there are some real challenges in the current spelling of Rodauth internals that would require a larger and serious discussion involving Jeremy.Chiefly is the issue of the atomicity around
before_x
,x
,after_x
. Rodauth's out of the box auditing functionality relies onafter_*
being called, for one, and custom config in eitherbefore_*
orafter_*
might affect the behaviour of the unit as a whole (perhaps bythrow
ing,raise
ing or altering state). Clearly, if an admin changes a users email this can't be done in the request's Rodauth instance or it will have side effects for the admin's session, so it must be done in a quarantined and virtual instance a laRodauth::Rails.rodauth
and I don't think anybody would argue that this shouldn't also leave an audit trail.However, we wouldn't want to simply duplicate the
before_x
,x
,after_x
triplets inside other API because sometimes they are not so simple, such aschange_login
being fallable andafter_change_login
not running in that condition.Ultimately, I think we can make Rodauth nice to use for these out-of-request use cases without Jeremy's support to de-couple the core stateful changes from the request life-cycle as a whole. By stateful here, I don't mean things like
@account
so much as things like inserting a password hash into the DB. Ideally, all features would be re-worked to be a discrete API and the Roda-exposed feature routes would use the same API as would a use case outside of that request. That's big work and I'm not sure Jeremy would even be interested in a move in that direction.Personally, this is the primary (and almost only) grievance I have with Rodauth as a whole. It has the best-designed data model of anything in Rubyland but hasn't really accounted for the use cases that would exist to support the human beings who are the users in that data model.
Beta Was this translation helpful? Give feedback.
All reactions