diff options
| author | tv <tv@krebsco.de> | 2026-10-24 19:25:54 +0200 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-24 19:25:54 +0200 |
| commit | 815ec2e9a641ad5ac5c2f886291e63c89966bd6c (patch) | |
| tree | 5840ab9e9adc8e5ab5259ef0da7949880cde5f53 /src/api/auth.rs | |
| parent | 09f2dfd083c4fcdce4c5ca7376353906eb025c42 (diff) | |
only protocol-writers may modify _continuum
Diffstat (limited to 'src/api/auth.rs')
| -rw-r--r-- | src/api/auth.rs | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/src/api/auth.rs b/src/api/auth.rs index 70b1af5..de4220c 100644 --- a/src/api/auth.rs +++ b/src/api/auth.rs @@ -72,14 +72,18 @@ fn parse_basic(headers: &HeaderMap) -> Option<(String, String)> { Some((user.to_owned(), pass.to_owned())) } -async fn authenticate(state: &AuthState, headers: &HeaderMap) -> bool { - let Some((user, pass)) = parse_basic(headers) else { - return false; - }; - let Some(hash) = state.users.get(&user).cloned() else { - return false; - }; +/// The user a request authenticated as (a request extension, set by [`basic_auth`]). +#[derive(Clone, Debug)] +pub(crate) struct AuthenticatedUser(pub(crate) String); +/// The user, if the credentials are valid. +async fn authenticate(state: &AuthState, headers: &HeaderMap) -> Option<String> { + let (user, pass) = parse_basic(headers)?; + let hash = state.users.get(&user).cloned()?; + verify(state, &user, pass, hash).await.then_some(user) +} + +async fn verify(state: &AuthState, user: &str, pass: String, hash: String) -> bool { let key = *blake3::hash(format!("{user}\0{pass}\0{hash}").as_bytes()).as_bytes(); // Fast path. The shard guard lives only until the end of this `match`; @@ -124,10 +128,10 @@ async fn authenticate(state: &AuthState, headers: &HeaderMap) -> bool { pub async fn basic_auth( State(state): State<AuthState>, headers: HeaderMap, - request: Request<Body>, + mut request: Request<Body>, next: axum::middleware::Next, ) -> Response { - if !authenticate(&state, &headers).await { + let Some(user) = authenticate(&state, &headers).await else { sleep(Duration::from_millis(1500)).await; return ( StatusCode::UNAUTHORIZED, @@ -135,7 +139,8 @@ pub async fn basic_auth( "Unauthorized", ) .into_response(); - } + }; + request.extensions_mut().insert(AuthenticatedUser(user)); next.run(request).await } |
