diff options
Diffstat (limited to 'src/api')
-rw-r--r-- | src/api/error.rs | 26 | ||||
-rw-r--r-- | src/api/users.rs | 10 |
2 files changed, 33 insertions, 3 deletions
diff --git a/src/api/error.rs b/src/api/error.rs index bd43ce3..9048c20 100644 --- a/src/api/error.rs +++ b/src/api/error.rs @@ -9,6 +9,12 @@ pub enum Error { #[error("User not found")] UserNotFound, + #[error("Required header not found: {0}")] + HeaderNotFound(axum::http::HeaderName), + + #[error("Failed to parse header: {0} (wrong token type?)")] + Header(axum_extra::typed_header::TypedHeaderRejection), + #[error("Invalid user token")] InvalidToken, @@ -21,19 +27,35 @@ pub enum Error { #[error("Failed to reach authentication server: {0}")] AuthRequest(#[from] axum::http::Error), + #[error("Not authorization values found")] + Unauthorized, + #[error("Authentication error: {0}")] Auth(#[from] crate::auth::error::Error), } +impl From<axum_extra::typed_header::TypedHeaderRejection> for Error { + fn from(value: axum_extra::typed_header::TypedHeaderRejection) -> Self { + if value.is_missing() { + Self::HeaderNotFound(value.name().clone()) + } else { + Self::Header(value) + } + } +} + impl axum::response::IntoResponse for Error { fn into_response(self) -> axum::response::Response { + use axum::http::header::AUTHORIZATION; use axum::http::StatusCode; let status = match self { Self::RouteNotFound(_) | Self::UserNotFound => StatusCode::NOT_FOUND, Self::EmailExists => StatusCode::CONFLICT, - Self::EmailInvalid(_) => StatusCode::UNPROCESSABLE_ENTITY, - Self::InvalidToken => StatusCode::UNAUTHORIZED, + Self::InvalidToken | Self::Unauthorized => StatusCode::UNAUTHORIZED, + Self::HeaderNotFound(ref h) if h == AUTHORIZATION => StatusCode::UNAUTHORIZED, + Self::HeaderNotFound(_) => StatusCode::BAD_REQUEST, + Self::EmailInvalid(_) | Self::Header(_) => StatusCode::UNPROCESSABLE_ENTITY, Self::AuthRequest(_) | Self::Sqlx(_) => StatusCode::INTERNAL_SERVER_ERROR, Self::Auth(err) => return err.into_response(), }; diff --git a/src/api/users.rs b/src/api/users.rs index 0cac406..6eb2a39 100644 --- a/src/api/users.rs +++ b/src/api/users.rs @@ -9,6 +9,7 @@ use axum::{ use axum_extra::{ headers::{authorization::Basic, Authorization}, routing::Resource, + typed_header::TypedHeaderRejection, TypedHeader, }; use serde::{Deserialize, Serialize}; @@ -48,8 +49,15 @@ pub struct RegisterSchema { pub async fn login( State(state): State<AppState>, - TypedHeader(Authorization(basic)): TypedHeader<Authorization<Basic>>, + auth: Result<TypedHeader<Authorization<Basic>>, TypedHeaderRejection>, + claims: Option<RefreshClaims>, ) -> Result<(AccessClaims, RefreshClaims), Error> { + if let Some(refresh_claims) = claims { + return Ok((refresh_claims.refresh(), refresh_claims)); + } + + let TypedHeader(Authorization(basic)) = auth?; + let user_id = sqlx::query_scalar!("SELECT id FROM user_ WHERE email = $1", basic.username()) .fetch_optional(&state.pool) .await? |