Skip to content

fix: refresh deps for best-effort auth logout, /logout never 500s (closes #14) - #17

Merged
nycomp merged 1 commit into
mainfrom
fix/logout-500-stale-session
Oct 1, 2026
Merged

nycomp merged 1 commit into
mainfrom
fix/logout-500-stale-session

Conversation

@nycomp

@nycomp nycomp commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Closes #14.

Root cause

GET /logout → flask_campus → campus.auth.logout() → LoginSessions.Login.revoke() → DELETE /auth/v1/logins/<id>. The auth service's DELETE route (_verify_session_id in campus/auth/resources/login.py) requires the auth-service-side {provider}_session_id cookie of the requesting client and 404s with "No session ID in client" when it's absent. The Campus client keeps that cookie in a per-process in-memory requests.Session jar — since campus-admin runs 2 gunicorn workers (PR #12), the login POST and the logout DELETE can land on different workers, the cookie isn't there, the DELETE 404s, and raise_for_status() turned /logout into a 500 while the user stayed signed in.

Fix

Upstream, in nyjc-computing/campus-api-python#58 (merged, eb1c876): AuthAPI.logout() now treats remote revocation as best-effort — it logs a warning and clears the stored login session id instead of raising, so logout always completes locally with a redirect. The auth-service-side strictness is filed upstream as nyjc-computing/campus#692 (revocation of sessions created by the same client credentials should not depend on a volatile per-process cookie).

This PR refreshes poetry.lock to that commit.

Verification (local, against dev auth service)

  • Reproduced the exact deployed failure with two fresh Campus clients (simulating two workers): worker 1 creates a real login session, worker 2 (empty cookie jar) logs out — the DELETE now returns 404 "No session ID in client", which is caught and logged; the local session key is cleared and the flow returns cleanly. Previously this raised NotFoundError → 500.
  • GET /logout with no session → 302 /.
  • GET /logout with a stale logins_login_id → 302, key cleared, landing page renders signed-out state.
  • ruff check clean; app-factory smoke (create_app) passes.

Drift note

The refresh also pulls campus-suite weekly 484a1bb → d0c2ce4 (redirect_uri fail-closed enforcement, RFC 7009 token revocation, refresh-token grant, and campus#652 which now requires PUBLIC_URL). PUBLIC_URL is already set on the Railway service and documented in .env.example/README, so no action needed.

…oses #14)

campus-api-python eb1c876 (PR nyjc-computing/campus-api-python#58) makes
AuthAPI.logout() treat remote login-session revocation as best-effort:
on failure it logs a warning and clears the stored login session id
instead of raising NotFoundError, so /logout always completes with a
local logout + redirect.

Lock refresh also picks up campus-suite weekly d0c2ce4 (redirect_uri
enforcement, RFC 7009 token revocation, refresh-token grant, and
campus#652 which makes PUBLIC_URL required — already set on Railway and
documented in .env.example/README).
@nycomp
nycomp merged commit bade128 into main Oct 1, 2026
4 checks passed
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.

GET /logout returns Internal Server Error (NotFoundError: No session ID in client)

2 participants