feat: AdminApiUser extractor for Bearer-token admin endpoints
Some checks failed
CI / Check / Test (push) Has been cancelled

This commit is contained in:
2026-06-03 00:00:45 +02:00
parent bf0350c87a
commit bb503f3ce8
2 changed files with 30 additions and 2 deletions

View File

@@ -98,6 +98,34 @@ where
} }
} }
pub struct AdminApiUser(pub UserId);
impl<S> FromRequestParts<S> for AdminApiUser
where
AppState: FromRef<S>,
S: Send + Sync,
{
type Rejection = ApiError;
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
let AuthenticatedUser(user_id) =
AuthenticatedUser::from_request_parts(parts, state).await?;
let app_state = AppState::from_ref(state);
let user = app_state
.app_ctx
.repos
.user
.find_by_id(&user_id)
.await
.map_err(|e| ApiError(e))?
.ok_or_else(|| ApiError(DomainError::NotFound("user not found".into())))?;
match user.role() {
domain::models::UserRole::Admin => Ok(AdminApiUser(user_id)),
_ => Err(ApiError(DomainError::Forbidden("admin only".into()))),
}
}
}
pub struct AdminUser(pub UserId); pub struct AdminUser(pub UserId);
impl<S> FromRequestParts<S> for AdminUser impl<S> FromRequestParts<S> for AdminUser

View File

@@ -19,7 +19,7 @@ use domain::value_objects::WrapUpId;
use crate::{ use crate::{
csrf::CsrfToken, csrf::CsrfToken,
errors::ApiError, errors::ApiError,
extractors::{AdminUser, AuthenticatedUser, OptionalCookieUser}, extractors::{AdminApiUser, AuthenticatedUser, OptionalCookieUser},
render::render_page, render::render_page,
state::AppState, state::AppState,
}; };
@@ -53,7 +53,7 @@ fn record_to_dto(r: &WrapUpRecord) -> WrapUpStatusResponse {
)] )]
pub async fn post_generate( pub async fn post_generate(
State(state): State<AppState>, State(state): State<AppState>,
_admin: AdminUser, _admin: AdminApiUser,
Json(req): Json<GenerateWrapUpRequest>, Json(req): Json<GenerateWrapUpRequest>,
) -> Result<Json<WrapUpGeneratedResponse>, ApiError> { ) -> Result<Json<WrapUpGeneratedResponse>, ApiError> {
let start = NaiveDate::parse_from_str(&req.start_date, "%Y-%m-%d") let start = NaiveDate::parse_from_str(&req.start_date, "%Y-%m-%d")