Skip to content

fix(dashboard): don't auto-SSO-redirect to /auth/login for password-only providers - #58852

Closed
Ahmett101 wants to merge 1 commit into
NousResearch:mainfrom
Ahmett101:fix/58810-password-only-provider-redirect
Closed

fix(dashboard): don't auto-SSO-redirect to /auth/login for password-only providers#58852
Ahmett101 wants to merge 1 commit into
NousResearch:mainfrom
Ahmett101:fix/58810-password-only-provider-redirect

Conversation

@Ahmett101

Copy link
Copy Markdown
Contributor

Summary

When the only registered interactive auth provider was a password-only one (e.g. the basic-auth provider), the dashboard root returned HTTP 500 instead of rendering the password form.

Two compounding root causes in the dashboard auth code:

  1. _auto_sso_response in hermes_cli/dashboard_auth/middleware.py got the / redirect happy whenever exactly one interactive provider was registered — and emitted a 302 to /auth/login?provider=<name> for any single provider, including password-only ones.
  2. The redirected /auth/login route then unconditionally calls provider.start_login(). BasicAuthProvider.start_login raises NotImplementedError because password login is a direct POST to /auth/password-login, not an OAuth redirect chain — and the resulting 500 leaked into the unauthenticated browser session.

Two narrow fixes complement each other:

  • _auto_sso_response skips the auto-redirect when the single registered provider has supports_password=True (and no OAuth session flow) — letting the request fall through to /login which renders the username/password form correctly.
  • auth_login catches NotImplementedError from start_login and 302-redirects to /login (defense in depth — covers cases where someone manually types /auth/login?provider=basic, bypassing the middleware's redirect skip).

Non-interactive token-only providers (e.g. drain) keep their 404 — the new password_only branch only kicks in when supports_password is true alongside supports_session=False.

Changes

  • hermes_cli/dashboard_auth/middleware.py_auto_sso_response skips when the single provider advertises supports_password=True and not supports_session=True so the request falls through to /login instead of hitting a 500-prone /auth/login redirect.
  • hermes_cli/dashboard_auth/routes.pyauth_login distinguishes password-only providers (redirect to /login) from non-interactive token-only providers (still 404); also wraps the existing start_login call in a defensive NotImplementedError catch that redirects to /login.
  • tests/hermes_cli/test_dashboard_auth_middleware.py — two new regression tests:
    • test_password_only_provider_does_not_trigger_auto_sso_redirect — hitting / with a basic-only registry must NOT 302 to /auth/login?provider=basic.
    • test_auth_login_redirects_to_login_when_provider_password_only — hitting /auth/login?provider=basic directly 302s to /login (not 404, not 500).

How to Test

venv/bin/python -m pytest tests/hermes_cli/test_dashboard_auth_middleware.py tests/hermes_cli/test_dashboard_auth_gate.py tests/hermes_cli/test_dashboard_auth_401_reauth.py tests/hermes_cli/test_dashboard_auth_audit.py -q
# 107/107 passed (35 pre-existing in this file + 2 new + rest of the auth suite)

Pinned by stash: stashing the two source files (hermes_cli/dashboard_auth/middleware.py + hermes_cli/dashboard_auth/routes.py) makes the second regression test fail with 404 == 302 — the fix is what introduces the redirect path that's now exercised.

Checklist

  • Tests pass — 107/107
  • Follows Conventional Commits
  • Cross-platform impact — Linux/macOS/Windows same (FastAPI/Starlette middleware behavior is portable)
  • profile-safe paths used (no path code modified)
  • .env not used for non-credential settings (no config surface changed; the providers remain configured the same way)

Risk & Impact

Low. The new _auto_sso_response gate (supports_password and not supports_session) restricts the existing auto-redirect narrowly: it skips ONLY providers that have neither OAuth nor session flow. Interactive OAuth providers (supports_session=True with a session-bearing start_login) still get the same auto-redirect they do today. The defense-in-depth NotImplementedError catch in auth_login is a no-op for every existing provider — only password-only providers raise it, and the catch converts the 500 into a clean 302 to /login.

Type: Bug fix
Closes: #58810

@alt-glitch alt-glitch added type/bug Something isn't working comp/dashboard Web dashboard / control panel UI (dashboard/, landing) area/auth Authentication, OAuth, credential pools P2 Medium — degraded but workaround exists labels Jul 5, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related to the dashboard-auth auto-SSO 500 cluster (regression from merged #54846). This PR is a broader superset than the earliest-open canonical fix #54887 (middleware-only) — it also guards the direct /auth/login route in routes.py (same shape as #58171). Anchor issue #55130; sibling both-facet PRs #58044/#58171. Related, not a duplicate — maintainer should pick the canonical fix.

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Comment (LGTM)

Fixes an SSO/auth UX bug: prevents auto-redirect to /auth/login for password-only providers (where SSO is not applicable). This is a targeted 3-file fix that correctly gates the SSO redirect on provider capability.

What looks good:

  • Well-scoped to the specific auth provider case
  • Clear conditional logic distinguishing SSO from password-only flows

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused dashboard-auth regression fix. This automated hermes-sweeper review found that current main already provides the requested behavior.

  • 3e24b16f566045399012bc1185fe0cdb6e1a1be9 added the equivalent password-provider handling after this PR was opened.
  • hermes_cli/dashboard_auth/middleware.py:212 skips auto-SSO for supports_password providers, allowing the regular /login flow.
  • hermes_cli/dashboard_auth/routes.py:195-202 redirects a password-capable provider's direct /auth/login request to /login before start_login().
  • tests/hermes_cli/test_dashboard_auth_password_login.py:201-217 covers both the root navigation and direct-route cases.

Closing as implemented on main; the PR's intended behavioral guarantee is already present with regression coverage.

@teknium1 teknium1 closed this Jul 15, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/dashboard Web dashboard / control panel UI (dashboard/, landing) P2 Medium — degraded but workaround exists sweeper:implemented-on-main Sweeper: behavior already present on current main type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dashboard: 500 on unauthenticated / when the only auth provider is password-only (auto-SSO redirects into OAuth start_login)

4 participants