diff options
Diffstat (limited to 'src/extract/auth.rs')
| -rw-r--r-- | src/extract/auth.rs | 36 |
1 files changed, 36 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 | } | ||
