Files
warren/backend/src/lib/inbound/http/handlers/warrens/create_share.rs
2025-08-29 15:32:23 +02:00

88 lines
2.5 KiB
Rust

use axum::{Json, extract::State, http::StatusCode};
use serde::Deserialize;
use thiserror::Error;
use uuid::Uuid;
use crate::{
domain::warren::{
models::{
auth_session::AuthRequest,
file::{AbsoluteFilePath, AbsoluteFilePathError, FilePath, FilePathError},
share::{CreateShareBaseRequest, SharePassword, SharePasswordError},
},
ports::{AuthService, WarrenService},
},
inbound::http::{
AppState,
handlers::{ShareData, extractors::SessionIdHeader},
responses::{ApiError, ApiSuccess},
},
};
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(super) struct CreateShareHttpRequestBody {
warren_id: Uuid,
path: String,
lifetime: Option<u64>,
password: Option<String>,
}
#[derive(Debug, Error)]
enum ParseCreateShareHttpRequestError {
#[error(transparent)]
FilePath(#[from] FilePathError),
#[error(transparent)]
AbsoluteFilePath(#[from] AbsoluteFilePathError),
#[error(transparent)]
SharePassword(#[from] SharePasswordError),
}
impl From<ParseCreateShareHttpRequestError> for ApiError {
fn from(e: ParseCreateShareHttpRequestError) -> Self {
ApiError::BadRequest(e.to_string())
}
}
impl CreateShareHttpRequestBody {
fn try_into_domain(self) -> Result<CreateShareBaseRequest, ParseCreateShareHttpRequestError> {
let path: AbsoluteFilePath = {
let file_path = FilePath::new(&self.path)?;
file_path.try_into()?
};
let password = if let Some(password) = self.password {
Some(SharePassword::new(&password)?)
} else {
None
};
Ok(CreateShareBaseRequest::new(
self.warren_id,
path,
password,
self.lifetime,
))
}
}
pub async fn create_share<WS: WarrenService, AS: AuthService>(
State(state): State<AppState<WS, AS>>,
SessionIdHeader(session): SessionIdHeader,
Json(request): Json<CreateShareHttpRequestBody>,
) -> Result<ApiSuccess<ShareData>, ApiError> {
let domain_request = AuthRequest::new(session, request.try_into_domain()?);
state
.auth_service
.auth_warren_create_share(domain_request, state.warren_service.as_ref())
.await
.map(|response| {
ApiSuccess::new(
StatusCode::CREATED,
ShareData::from(response.share().clone()),
)
})
.map_err(ApiError::from)
}