136 lines
4.1 KiB
Rust
136 lines
4.1 KiB
Rust
use actix_multipart::Multipart;
|
|
use actix_web::{web, HttpResponse, post, delete, get, ResponseError};
|
|
use log::error;
|
|
use serenity::futures::StreamExt;
|
|
use siren::ServiceError;
|
|
|
|
use crate::{auth::{JwtAuth, InsertUser, QueryUser}, storage::{upload_file, get_file, delete_file}};
|
|
|
|
#[post("/picture")]
|
|
async fn set_picture(mut payload: Multipart, auth: JwtAuth) -> HttpResponse {
|
|
while let Some(item) = payload.next().await {
|
|
let mut bytes = web::BytesMut::new();
|
|
let mut field = match item {
|
|
Ok(field) => field,
|
|
Err(err) => return ResponseError::error_response(&err)
|
|
};
|
|
let content_type = field.content_disposition();
|
|
// Get file name and construct the file path
|
|
let file_name = match content_type.get_filename() {
|
|
Some(name) => {
|
|
// Verify extension is supported
|
|
match name.split(".").last() {
|
|
Some(ext) => {
|
|
match ext {
|
|
"png" | "jpg" | "jpeg" => name,
|
|
_ => return ResponseError::error_response(&ServiceError {
|
|
status: 400,
|
|
message: "File extension is not supported".to_string()
|
|
})
|
|
}
|
|
},
|
|
None => return ResponseError::error_response(&ServiceError {
|
|
status: 400,
|
|
message: "Unknown file extension".to_string()
|
|
})
|
|
}
|
|
},
|
|
None => return ResponseError::error_response(&ServiceError {
|
|
status: 400,
|
|
message: "File name is not provided".to_string()
|
|
})
|
|
};
|
|
let path = format!("users/{}/{}", auth.user.email, file_name);
|
|
|
|
// Build the file and store it in minio
|
|
while let Some(chunk) = field.next().await {
|
|
let data = match chunk {
|
|
Ok(data) => data,
|
|
Err(err) => {
|
|
error!("Failed to get chunk: {}", err);
|
|
return ResponseError::error_response(&err);
|
|
}
|
|
};
|
|
bytes.extend_from_slice(&data);
|
|
}
|
|
match upload_file(&path, &bytes).await {
|
|
Ok(_) => {
|
|
match InsertUser::update_profile(&auth.user.email, Some(&path)) {
|
|
Ok(_) => {}
|
|
Err(err) => {
|
|
error!("Failed to update user profile: {}", err);
|
|
return ResponseError::error_response(&err);
|
|
}
|
|
};
|
|
},
|
|
Err(err) => {
|
|
error!("Failed to upload file: {}", err);
|
|
return ResponseError::error_response(&err);
|
|
}
|
|
}
|
|
};
|
|
return HttpResponse::Ok().finish();
|
|
}
|
|
|
|
#[get("/picture")]
|
|
async fn get_picture(auth: JwtAuth) -> HttpResponse {
|
|
let user = match QueryUser::get_by_email(&auth.user.email) {
|
|
Ok(user) => user,
|
|
Err(err) => {
|
|
error!("Failed to get user: {}", err);
|
|
return ResponseError::error_response(&err);
|
|
}
|
|
};
|
|
if let Some(path) = user.profile_picture {
|
|
match get_file(&path).await {
|
|
Ok(bytes) => return HttpResponse::Ok().body(bytes),
|
|
Err(err) => {
|
|
error!("Failed to get file: {}", err);
|
|
return ResponseError::error_response(&err);
|
|
}
|
|
}
|
|
} else {
|
|
return HttpResponse::NotFound().finish();
|
|
}
|
|
}
|
|
|
|
#[delete("/picture")]
|
|
async fn delete_picture(auth: JwtAuth) -> HttpResponse {
|
|
match QueryUser::get_by_email(&auth.user.email) {
|
|
Ok(user) => {
|
|
match user.profile_picture {
|
|
Some(path) => {
|
|
match delete_file(&path).await {
|
|
Ok(_) => {
|
|
match InsertUser::update_profile(&auth.user.email, None) {
|
|
Ok(_) => {}
|
|
Err(err) => {
|
|
error!("Failed to update user profile: {}", err);
|
|
return ResponseError::error_response(&err);
|
|
}
|
|
};
|
|
}
|
|
Err(err) => {
|
|
error!("Failed to delete file: {}", err);
|
|
return ResponseError::error_response(&err);
|
|
}
|
|
};
|
|
},
|
|
None => {}
|
|
}
|
|
},
|
|
Err(err) => {
|
|
error!("Failed to get user: {}", err);
|
|
return ResponseError::error_response(&err);
|
|
}
|
|
};
|
|
return HttpResponse::Ok().finish();
|
|
}
|
|
|
|
pub fn init_routes(config: &mut web::ServiceConfig) {
|
|
config.service(web::scope("users")
|
|
.service(set_picture)
|
|
.service(get_picture)
|
|
.service(delete_picture)
|
|
);
|
|
} |