Some checks failed
lint / lint (push) Has been cancelled
test / unit (push) Has been cancelled
test / integration (push) Has been cancelled
lint / lint (pull_request) Failing after 6m49s
test / unit (pull_request) Successful in 16m24s
test / integration (pull_request) Failing after 17m7s
- Reorganized imports in health, notifications, social, thoughts, and users handlers for clarity. - Updated function signatures in handlers to improve readability by aligning parameters. - Enhanced JSON response formatting in notifications and thoughts handlers. - Improved error handling in user-related functions. - Refactored OpenAPI documentation to maintain consistent formatting and structure. - Cleaned up unnecessary code and comments across various files. - Ensured consistent use of `Arc` for shared state in AppState and WorkerHandlers.
53 lines
1.7 KiB
Rust
53 lines
1.7 KiB
Rust
use crate::{errors::ApiError, state::AppState};
|
|
use axum::{extract::FromRequestParts, http::request::Parts};
|
|
use domain::value_objects::UserId;
|
|
|
|
pub struct AuthUser(pub UserId);
|
|
pub struct OptionalAuthUser(pub Option<UserId>);
|
|
|
|
impl FromRequestParts<AppState> for AuthUser {
|
|
type Rejection = ApiError;
|
|
async fn from_request_parts(parts: &mut Parts, state: &AppState) -> Result<Self, ApiError> {
|
|
extract_user_id(parts, state)
|
|
.await?
|
|
.ok_or(ApiError::Unauthorized)
|
|
.map(AuthUser)
|
|
}
|
|
}
|
|
|
|
impl FromRequestParts<AppState> for OptionalAuthUser {
|
|
type Rejection = ApiError;
|
|
async fn from_request_parts(parts: &mut Parts, state: &AppState) -> Result<Self, ApiError> {
|
|
Ok(OptionalAuthUser(extract_user_id(parts, state).await?))
|
|
}
|
|
}
|
|
|
|
async fn extract_user_id(parts: &mut Parts, state: &AppState) -> Result<Option<UserId>, ApiError> {
|
|
if let Some(auth_header) = parts.headers.get("Authorization") {
|
|
if let Ok(s) = auth_header.to_str() {
|
|
if let Some(token) = s.strip_prefix("Bearer ") {
|
|
return state
|
|
.auth
|
|
.validate_token(token)
|
|
.map(Some)
|
|
.map_err(|_| ApiError::Unauthorized);
|
|
}
|
|
}
|
|
}
|
|
if let Some(key_header) = parts.headers.get("X-Api-Key") {
|
|
if let Ok(raw) = key_header.to_str() {
|
|
let hash = sha256_hex(raw);
|
|
if let Ok(Some(key)) = state.api_keys.find_by_hash(&hash).await {
|
|
return Ok(Some(key.user_id));
|
|
}
|
|
}
|
|
}
|
|
Ok(None)
|
|
}
|
|
|
|
fn sha256_hex(s: &str) -> String {
|
|
use sha2::{Digest, Sha256};
|
|
let hash = Sha256::digest(s.as_bytes());
|
|
hex::encode(hash)
|
|
}
|