bobashare_web/api/v1/
delete.rs1use axum::{
4 extract::{Path, State},
5 response::{IntoResponse, Response},
6};
7use bobashare::storage::file::{DeleteUploadError, OpenUploadError};
8use displaydoc::Display;
9use hyper::StatusCode;
10use thiserror::Error;
11use tracing::{event, instrument, Level};
12
13use super::ApiErrorExt;
14use crate::AppState;
15
16#[derive(Debug, Error, Display)]
18pub enum DeleteError {
19 NotFound,
21 IncorrectKey,
23
24 InternalServer(#[from] anyhow::Error),
26}
27impl From<DeleteUploadError> for DeleteError {
28 fn from(err: DeleteUploadError) -> Self {
29 match err {
30 DeleteUploadError::NotFound => Self::NotFound,
31 e => Self::InternalServer(e.into()),
32 }
33 }
34}
35impl IntoResponse for DeleteError {
36 fn into_response(self) -> Response {
37 let code = match self {
38 Self::NotFound => StatusCode::NOT_FOUND,
39 Self::IncorrectKey => StatusCode::FORBIDDEN,
40 Self::InternalServer(_) => StatusCode::INTERNAL_SERVER_ERROR,
41 };
42 self.into_response_with_code(code)
43 }
44}
45
46#[instrument(skip(state))]
65pub async fn delete(
66 state: State<&'static AppState>,
67 Path(id): Path<String>,
68 key: String,
69) -> Result<impl IntoResponse, DeleteError> {
70 let key = key.trim();
71 event!(Level::DEBUG, "reading upload metadata");
72 let metadata = state
73 .backend
74 .read_upload_metadata(&id)
75 .await
76 .map_err(|e| match e {
77 OpenUploadError::NotFound(_) => DeleteError::NotFound,
78 e => DeleteError::InternalServer(
79 anyhow::Error::new(e).context("error reading upload metadata"),
80 ),
81 })?;
82 if metadata.is_expired() {
83 event!(
84 Level::INFO,
85 "upload was already expired anyway, deleting and sending NotFound response"
86 );
87 state.backend.delete_upload(&id).await?;
88 return Err(DeleteError::NotFound);
89 }
90 if metadata.delete_key != key {
91 event!(Level::INFO, "provided delete key was incorrect");
92 return Err(DeleteError::IncorrectKey);
93 }
94
95 event!(Level::DEBUG, "delete key was correct; deleting upload");
96 state.backend.delete_upload(&id).await?;
97
98 event!(Level::INFO, id, "successfully deleted upload");
99 Ok(StatusCode::NO_CONTENT)
100}