Skip to content

fix: don't delete the session when a resource requires a tenant - #1198

Open
bars0udin wants to merge 1 commit into
team-alembic:mainfrom
bars0udin:fix-multitenant-session-deletion
Open

fix: don't delete the session when a resource requires a tenant#1198
bars0udin wants to merge 1 commit into
team-alembic:mainfrom
bars0udin:fix-multitenant-session-deletion

Conversation

@bars0udin

Copy link
Copy Markdown

The failure mode

Plug.Helpers.retrieve_from_session/3 iterates every authenticated resource for the otp_app and deletes the session key of each one it can't resolve a user for. For a multitenant resource with global? false, a request that carries no tenant fails with Ash.Error.Invalid.TenantRequired — the query is rejected by Ash.Actions.Read.validate_multitenancy/1 before it reaches the data layer — and the perfectly good session is deleted anyway.

Who it affects

Any app with a tenant-scoped authenticated resource plus a pipeline that doesn't set an Ash tenant: an admin/staff area, a webhook endpoint, a health check, or simply a second authenticated resource whose pipeline is tenant-less. Users of the multitenant resource are silently signed out by requests to those routes.

Note that retrieve_from_session/3 reads the tenant from Ash.PlugHelpers.get_tenant(conn) only, so this bites whenever the plug pipeline hasn't set one — assign_new_resources/4 has a session["tenant"] fallback, but the plug path does not.

Reproduction

Two authenticated resources, one of them multitenant and not global?; a request through a pipeline that sets no tenant. The multitenant resource's session key is gone afterwards even though the subject is untouched. The added test uses the existing Example.MultiTenantUserWithWebAuthn fixture, which is already multitenancy do strategy :context end.

The fix

Only delete the session key when the lookup was actually able to run. If the resource declares multitenancy, isn't global?, and this request has no tenant, the failure says nothing about the session, so leave it alone. Genuinely absent or unresolvable subjects are still cleared, as covered by the second added test.

`retrieve_from_session/3` iterates every authenticated resource for the
otp_app and deletes the session key of each one it can't resolve a user
for. For a multitenant resource with `global? false`, a request that
carries no tenant fails with `Ash.Error.Invalid.TenantRequired` before
the query reaches the data layer, so the session is discarded without
anything having been learned about whether it was valid.

Only delete the session key when the lookup was actually able to run.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant