57 lines
1.3 KiB
Rust
57 lines
1.3 KiB
Rust
use crate::{auth::Auth, state::ReqState};
|
|
use axum::{
|
|
extract::{Multipart, State},
|
|
response::IntoResponse,
|
|
Json,
|
|
};
|
|
use hyper::StatusCode;
|
|
use serde::Serialize;
|
|
|
|
#[derive(Serialize)]
|
|
struct UploadResponse {
|
|
id: String,
|
|
revocation_key: String,
|
|
}
|
|
|
|
pub async fn post(
|
|
State(state): ReqState,
|
|
Auth(_): Auth,
|
|
mut multipart: Multipart,
|
|
) -> impl IntoResponse {
|
|
let mut file = None;
|
|
|
|
while let Some(field) = multipart.next_field().await.unwrap() {
|
|
let bytes = field.bytes().await;
|
|
if bytes.is_ok() {
|
|
file = Some(bytes.unwrap());
|
|
}
|
|
}
|
|
|
|
if file.is_none() {
|
|
return Err(StatusCode::BAD_REQUEST);
|
|
}
|
|
|
|
let file = file.unwrap();
|
|
|
|
let mut id = crate::utils::gen_filename();
|
|
while state.files_dir.join(&id).exists() {
|
|
id = crate::utils::gen_filename();
|
|
}
|
|
|
|
let path = state.files_dir.join(id.clone());
|
|
tokio::fs::write(path, file)
|
|
.await
|
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
|
|
|
let revocation_key = crate::utils::gen_revocation_key();
|
|
sqlx::query!(
|
|
"insert into files (id, revocation_key) values ($1, $2)",
|
|
id,
|
|
revocation_key
|
|
)
|
|
.execute(&state.db)
|
|
.await
|
|
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
|
|
|
Ok(Json(UploadResponse { id, revocation_key }))
|
|
}
|