Skip to content

Split src/webserver/oidc.rs (1556 lines) into a directory module #1319

Description

@lovasoa

Split-out of the "split oidc.rs" item from #1249.

src/webserver/oidc.rs is the largest file in the codebase at 1556 lines (wc -l src/webserver/oidc.rs). Anyone touching cookie flags has to scroll past JWT verifier generics, HMAC logout signing, the awc transport adapter, and ~12 large openidconnect type aliases. These concerns are independent of each other, and the file's coupling to the rest of the codebase is tiny, so the split is low-risk and high-payoff.

External surface is only 5 symbols

$ grep -rn "oidc::" src | grep -v "src/webserver/oidc.rs"
src/lib.rs:89:use crate::webserver::oidc::OidcState;
src/lib.rs:138:        let oidc_state = crate::webserver::oidc::initialize_oidc_state(config).await?;
src/webserver/http.rs:27:use super::oidc::OidcMiddleware;
src/webserver/http_request_info.rs:28:use super::oidc::OidcClaims;
src/webserver/database/sqlpage_functions/functions.rs:1058:    if !crate::webserver::oidc::is_safe_relative_redirect(redirect_uri) {

So the entire 1556-line file is reached from outside through just OidcState, initialize_oidc_state, OidcMiddleware, OidcClaims, and is_safe_relative_redirect. A split is almost entirely internal and mechanical.

The concerns are physically interleaved

(line ranges at HEAD 162f996)

Proposed change

Convert to a directory module:

oidc/
  mod.rs          // re-exports the ~5 public symbols
  config.rs       // OidcConfig, is_public_path, get_app_host
  discovery.rs    // OidcState/OidcSnapshot, maybe_refresh, client build, type aliases
  middleware.rs   // OidcMiddleware/OidcService, handle_request + handle_*
  flow.rs         // callback / token exchange / claim + nonce verification
  session.rs      // cookie builders, logout signing, redirect safety
  http_client.rs  // the AwcHttpClient adapter (now independently testable)

Do not regress the good existing state

Two things must be preserved by the move:

  • The real integration suite at tests/oidc/mod.rs (882 lines) spins up an embedded mock IdP (discovery/jwks/token endpoints) and covers the happy path, CSRF/nonce/signature/audience/issuer/expiry rejection, site-prefix, session-bound logout, and slow-discovery non-blocking behavior.
  • The lock-free read discipline: OidcState::snapshot() returns an Arc<OidcSnapshot> so request handling never holds the RwLock across .await. The split must keep this intact.

Risks and mitigations

Purely mechanical move, no behavior change. Mitigations:

  • Keep the public re-exports in mod.rs so no external code changes (the 5 call sites above stay byte-for-byte identical).
  • Rely on the existing OIDC integration tests above to catch any wiring mistake.

Expected win

Navigable auth code; the transport adapter becomes unit-testable in isolation; and it is a prerequisite for any future second-IdP or server-side-session work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions