-
-
Notifications
You must be signed in to change notification settings - Fork 172
Split src/webserver/oidc.rs (1556 lines) into a directory module #1319
Description
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)
- Config / path matching (
OidcConfig,is_public_path,get_app_host) talks only toAppConfig. - Provider discovery + client build (
OidcSnapshot,OidcState,maybe_refresh,build_oidc_client,make_oidc_client) plus the ~12 largeopenidconnecttype aliases (OidcToken,OidcClaims,OidcTokenResponse,OidcClient) that visually dominate the file. - Actix middleware / request routing (
OidcMiddleware,OidcService,handle_requestand thehandle_*family). - Token exchange + claim/nonce verification (
process_oidc_callback,exchange_code_for_token,check_nonce,AudienceVerifier). - Cookie/session + redirect plumbing (the
*_cookiebuilders such asset_auth_cookieandcreate_tmp_login_flow_state_cookie, HMAC logout signingcompute_logout_signature/verify_logout_params,is_safe_relative_redirect,build_redirect_response). - A generic
awctransport adapter (AwcHttpClient, ~110 lines throughAwcWrapperError) implementingopenidconnect::AsyncHttpClientoverawc. This is not OIDC-specific. It ispubbut used only within this file, so it should move to its own module where it becomes independently unit-testable.
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 anArc<OidcSnapshot>so request handling never holds theRwLockacross.await. The split must keep this intact.
Risks and mitigations
Purely mechanical move, no behavior change. Mitigations:
- Keep the public re-exports in
mod.rsso 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.