Skip to content

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

@lovasoa

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions