diff options
Diffstat (limited to 'src/auth.rs')
-rw-r--r-- | src/auth.rs | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/src/auth.rs b/src/auth.rs index 09494fb..6bf0ddf 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,5 +1,10 @@ use argon2::{Argon2, PasswordHash, PasswordVerifier}; -use axum::extract::State; +use axum::{ + async_trait, + extract::{FromRequestParts, State}, + http::request::Parts, + RequestPartsExt, +}; use axum_extra::{ headers::{authorization::Basic, Authorization}, TypedHeader, @@ -28,18 +33,16 @@ pub fn router() -> axum::Router<AppState> { pub async fn issue( State(state): State<AppState>, - TypedHeader(Authorization(basic)): TypedHeader<Authorization<Basic>>, + Account { id, password }: Account, ) -> Result<(AccessClaims, RefreshClaims), Error> { - let uuid = Uuid::try_parse(basic.username())?; - - let p: String = sqlx::query_scalar!("SELECT password_hash FROM credential WHERE id = $1", uuid) + let p: String = sqlx::query_scalar!("SELECT password_hash FROM credential WHERE id = $1", id) .fetch_optional(&state.pool) .await? .ok_or(Error::LoginInvalid)?; - Argon2::default().verify_password(basic.password().as_bytes(), &PasswordHash::new(&p)?)?; + Argon2::default().verify_password(password.as_bytes(), &PasswordHash::new(&p)?)?; - let refresh = RefreshClaims::issue(uuid); + let refresh = RefreshClaims::issue(id); let access = refresh.refresh(); Ok((access, refresh)) } @@ -48,6 +51,27 @@ pub async fn refresh(claims: RefreshClaims) -> AccessClaims { claims.refresh() } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Account { + pub id: Uuid, + pub password: String, +} + +#[async_trait] +impl FromRequestParts<AppState> for Account { + type Rejection = Error; + + async fn from_request_parts(parts: &mut Parts, _: &AppState) -> Result<Self, Self::Rejection> { + let TypedHeader(Authorization(basic)) = + parts.extract::<TypedHeader<Authorization<Basic>>>().await?; + + Ok(Self { + id: Uuid::try_parse(basic.username())?, + password: basic.password().to_string(), + }) + } +} + #[cfg(test)] mod tests { use super::*; @@ -57,7 +81,7 @@ mod tests { http::{header::AUTHORIZATION, Request, StatusCode}, Router, }; - use axum_extra::headers::authorization::Credentials; + use axum_extra::headers::{authorization::Credentials, Authorization}; use sqlx::PgPool; use tower::ServiceExt; |