BLOG-78 Backend image upload and download #84

Merged
squid merged 6 commits from BLOG-78_image_management into main 2025-07-27 13:10:47 +08:00
5 changed files with 26 additions and 11 deletions
Showing only changes of commit c639a85ff3 - Show all commits

View File

@ -28,6 +28,8 @@ pub trait ImageController: Send + Sync {
pub struct ImageControllerImpl { pub struct ImageControllerImpl {
upload_image_use_case: Arc<dyn UploadImageUseCase>, upload_image_use_case: Arc<dyn UploadImageUseCase>,
get_image_use_case: Arc<dyn GetImageUseCase>, get_image_use_case: Arc<dyn GetImageUseCase>,
mime_type_whitelist: Vec<String>,
} }
impl ImageControllerImpl { impl ImageControllerImpl {
@ -38,6 +40,12 @@ impl ImageControllerImpl {
Self { Self {
upload_image_use_case, upload_image_use_case,
get_image_use_case, get_image_use_case,
mime_type_whitelist: vec![
"image/jpeg".to_string(),
"image/png".to_string(),
"image/gif".to_string(),
"image/webp".to_string(),
],
} }
} }
} }
@ -48,6 +56,10 @@ impl ImageController for ImageControllerImpl {
&self, &self,
image: ImageRequestDto, image: ImageRequestDto,
) -> Result<ImageInfoResponseDto, ImageError> { ) -> Result<ImageInfoResponseDto, ImageError> {
if !self.mime_type_whitelist.contains(&image.mime_type) {
return Err(ImageError::UnsupportedMimeType);
}
let id = self let id = self
.upload_image_use_case .upload_image_use_case
.execute(image.to_entity()) .execute(image.to_entity())

View File

@ -3,4 +3,5 @@ pub enum ImageError {
DatabaseError(String), DatabaseError(String),
StorageError(String), StorageError(String),
NotFound, NotFound,
UnsupportedMimeType,
} }

View File

@ -1,4 +1,4 @@
#[derive(sqlx::FromRow, Debug)] #[derive(sqlx::FromRow)]
pub struct ImageRecord { pub struct ImageRecord {
pub id: i32, pub id: i32,
pub mime_type: String, pub mime_type: String,

View File

@ -57,10 +57,13 @@ async fn upload_image_handler(
match result { match result {
Ok(image_info) => HttpResponse::Created().json(image_info), Ok(image_info) => HttpResponse::Created().json(image_info),
Err(e) => { Err(e) => match e {
log::error!("{e:?}"); ImageError::UnsupportedMimeType => HttpResponse::BadRequest().body(format!("{e:?}")),
HttpResponse::InternalServerError().finish() _ => {
} log::error!("{e:?}");
HttpResponse::InternalServerError().finish()
}
},
} }
} }
@ -75,13 +78,12 @@ async fn get_image_by_id_handler(
Ok(image_response) => HttpResponse::Ok() Ok(image_response) => HttpResponse::Ok()
.content_type(image_response.mime_type) .content_type(image_response.mime_type)
.body(image_response.data), .body(image_response.data),
Err(e) => { Err(e) => match e {
if e == ImageError::NotFound { ImageError::NotFound => HttpResponse::NotFound().finish(),
HttpResponse::NotFound().finish() _ => {
} else {
log::error!("{e:?}"); log::error!("{e:?}");
HttpResponse::InternalServerError().finish() HttpResponse::InternalServerError().finish()
} }
} },
} }
} }

View File

@ -1,6 +1,6 @@
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
#[derive(sqlx::FromRow, Debug)] #[derive(sqlx::FromRow)]
pub struct PostWithLabelRecord { pub struct PostWithLabelRecord {
pub post_id: i32, pub post_id: i32,
pub title: String, pub title: String,