diff options
| author | Tolmachev Igor <me@igorek.dev> | 2025-09-01 13:32:05 +0300 |
|---|---|---|
| committer | Tolmachev Igor <me@igorek.dev> | 2025-09-01 13:32:05 +0300 |
| commit | b9d75e22db72aabf47815e381aa6432c1bff3877 (patch) | |
| tree | b6b0741461484c36919a3ec74fb075c77e867a59 /src/extract | |
| parent | 56d155ac2de9261575d7fd4671a08b95cd16e6bb (diff) | |
| download | queue_server-b9d75e22db72aabf47815e381aa6432c1bff3877.tar.gz queue_server-b9d75e22db72aabf47815e381aa6432c1bff3877.zip | |
Add account endpoints
Diffstat (limited to 'src/extract')
| -rw-r--r-- | src/extract/auth.rs | 36 | ||||
| -rw-r--r-- | src/extract/json.rs | 19 | ||||
| -rw-r--r-- | src/extract/mod.rs | 5 |
3 files changed, 60 insertions, 0 deletions
diff --git a/src/extract/auth.rs b/src/extract/auth.rs new file mode 100644 index 0000000..cc357fd --- /dev/null +++ b/src/extract/auth.rs | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | use axum::extract::FromRequestParts; | ||
| 2 | use axum::http::request::Parts; | ||
| 3 | use axum_extra::TypedHeader; | ||
| 4 | use entity::users; | ||
| 5 | use headers::authorization::{Authorization, Bearer}; | ||
| 6 | use sea_orm::EntityTrait; | ||
| 7 | |||
| 8 | use crate::{ApiError, AppState, validate_jwt}; | ||
| 9 | |||
| 10 | pub struct Auth(pub users::Model); | ||
| 11 | |||
| 12 | impl FromRequestParts<AppState> for Auth { | ||
| 13 | type Rejection = ApiError; | ||
| 14 | |||
| 15 | async fn from_request_parts( | ||
| 16 | parts: &mut Parts, | ||
| 17 | state: &AppState, | ||
| 18 | ) -> Result<Self, Self::Rejection> { | ||
| 19 | let token_header = | ||
| 20 | TypedHeader::<Authorization<Bearer>>::from_request_parts(parts, state).await?; | ||
| 21 | |||
| 22 | let jwt_claims = validate_jwt(token_header.token(), &state.secret) | ||
| 23 | .map_err(|_| ApiError::NotAuthorized)?; | ||
| 24 | |||
| 25 | let user = users::Entity::find_by_id(jwt_claims.sub) | ||
| 26 | .one(&state.db) | ||
| 27 | .await? | ||
| 28 | .ok_or(ApiError::NotAuthorized)?; | ||
| 29 | |||
| 30 | if jwt_claims.iat < user.password_issue_date.and_utc().timestamp() { | ||
| 31 | return Err(ApiError::NotAuthorized); | ||
| 32 | } | ||
| 33 | |||
| 34 | Ok(Auth(user)) | ||
| 35 | } | ||
| 36 | } | ||
diff --git a/src/extract/json.rs b/src/extract/json.rs new file mode 100644 index 0000000..cfde15b --- /dev/null +++ b/src/extract/json.rs | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | use axum::extract::rejection::JsonRejection; | ||
| 2 | use axum::extract::{FromRequest, Request}; | ||
| 3 | |||
| 4 | use crate::error::ApiError; | ||
| 5 | |||
| 6 | pub struct ApiJson<T>(pub T); | ||
| 7 | |||
| 8 | impl<S, T> FromRequest<S> for ApiJson<T> | ||
| 9 | where | ||
| 10 | axum::Json<T>: FromRequest<S, Rejection = JsonRejection>, | ||
| 11 | S: Send + Sync, | ||
| 12 | { | ||
| 13 | type Rejection = ApiError; | ||
| 14 | |||
| 15 | #[inline] | ||
| 16 | async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> { | ||
| 17 | Ok(Self(axum::Json::<T>::from_request(req, state).await?.0)) | ||
| 18 | } | ||
| 19 | } | ||
diff --git a/src/extract/mod.rs b/src/extract/mod.rs new file mode 100644 index 0000000..b46a610 --- /dev/null +++ b/src/extract/mod.rs | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | mod auth; | ||
| 2 | mod json; | ||
| 3 | |||
| 4 | pub use auth::Auth; | ||
| 5 | pub use json::ApiJson; | ||
