feat: enhance album and media management with update and delete functionalities
This commit is contained in:
@@ -2,12 +2,13 @@ use axum::{
|
||||
Json, Router,
|
||||
extract::{Path, State},
|
||||
http::StatusCode,
|
||||
routing::{get, post},
|
||||
};
|
||||
use libertas_core::{
|
||||
models::AlbumPermission,
|
||||
schema::{AddMediaToAlbumData, CreateAlbumData, ShareAlbumData},
|
||||
models::{Album, AlbumPermission},
|
||||
schema::{AddMediaToAlbumData, CreateAlbumData, ShareAlbumData, UpdateAlbumData},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{error::ApiError, middleware::auth::UserId, state::AppState};
|
||||
@@ -68,7 +69,7 @@ pub struct ShareAlbumRequest {
|
||||
|
||||
async fn share_album(
|
||||
State(state): State<AppState>,
|
||||
UserId(owner_id): UserId, // The person sharing must be authenticated
|
||||
UserId(owner_id): UserId,
|
||||
Path(album_id): Path<Uuid>,
|
||||
Json(payload): Json<ShareAlbumRequest>,
|
||||
) -> Result<StatusCode, ApiError> {
|
||||
@@ -83,9 +84,95 @@ async fn share_album(
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct AlbumResponse {
|
||||
id: Uuid,
|
||||
owner_id: Uuid,
|
||||
name: String,
|
||||
description: Option<String>,
|
||||
is_public: bool,
|
||||
created_at: chrono::DateTime<chrono::Utc>,
|
||||
updated_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
impl From<Album> for AlbumResponse {
|
||||
fn from(album: Album) -> Self {
|
||||
Self {
|
||||
id: album.id,
|
||||
owner_id: album.owner_id,
|
||||
name: album.name,
|
||||
description: album.description,
|
||||
is_public: album.is_public,
|
||||
created_at: album.created_at,
|
||||
updated_at: album.updated_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UpdateAlbumRequest {
|
||||
name: Option<String>,
|
||||
description: Option<Option<String>>,
|
||||
is_public: Option<bool>,
|
||||
}
|
||||
|
||||
async fn list_user_albums(
|
||||
State(state): State<AppState>,
|
||||
UserId(user_id): UserId,
|
||||
) -> Result<Json<Vec<AlbumResponse>>, ApiError> {
|
||||
let albums = state.album_service.list_user_albums(user_id).await?;
|
||||
let response = albums.into_iter().map(AlbumResponse::from).collect();
|
||||
Ok(Json(response))
|
||||
}
|
||||
|
||||
async fn get_album_details(
|
||||
State(state): State<AppState>,
|
||||
UserId(user_id): UserId,
|
||||
Path(album_id): Path<Uuid>,
|
||||
) -> Result<Json<AlbumResponse>, ApiError> {
|
||||
let album = state
|
||||
.album_service
|
||||
.get_album_details(album_id, user_id)
|
||||
.await?;
|
||||
Ok(Json(album.into()))
|
||||
}
|
||||
|
||||
async fn update_album(
|
||||
State(state): State<AppState>,
|
||||
UserId(user_id): UserId,
|
||||
Path(album_id): Path<Uuid>,
|
||||
Json(payload): Json<UpdateAlbumRequest>,
|
||||
) -> Result<Json<AlbumResponse>, ApiError> {
|
||||
let data = UpdateAlbumData {
|
||||
name: payload.name.as_deref(),
|
||||
description: payload.description.as_ref().map(|opt_s| opt_s.as_deref()),
|
||||
is_public: payload.is_public,
|
||||
};
|
||||
let album = state
|
||||
.album_service
|
||||
.update_album(album_id, user_id, data)
|
||||
.await?;
|
||||
Ok(Json(album.into()))
|
||||
}
|
||||
|
||||
async fn delete_album(
|
||||
State(state): State<AppState>,
|
||||
UserId(user_id): UserId,
|
||||
Path(album_id): Path<Uuid>,
|
||||
) -> Result<StatusCode, ApiError> {
|
||||
state.album_service.delete_album(album_id, user_id).await?;
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
pub fn album_routes() -> Router<AppState> {
|
||||
Router::new()
|
||||
.route("/", axum::routing::post(create_album))
|
||||
.route("/{album_id}/media", axum::routing::post(add_media_to_album))
|
||||
.route("/{album_id}/share", axum::routing::post(share_album))
|
||||
.route("/", post(create_album).get(list_user_albums))
|
||||
.route(
|
||||
"/{id}",
|
||||
get(get_album_details)
|
||||
.put(update_album)
|
||||
.delete(delete_album),
|
||||
)
|
||||
.route("/{id}/media", post(add_media_to_album))
|
||||
.route("/{id}/share", post(share_album))
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use axum::{Json, extract::State, http::StatusCode};
|
||||
use libertas_core::schema::{CreateUserData, LoginUserData};
|
||||
use libertas_core::schema::{CreateUserData, LoginUserData, UserResponse};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{error::ApiError, middleware::auth::UserId, state::AppState};
|
||||
use crate::{error::ApiError, state::AppState};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct RegisterRequest {
|
||||
@@ -12,13 +11,6 @@ pub struct RegisterRequest {
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct UserResponse {
|
||||
id: Uuid,
|
||||
username: String,
|
||||
email: String,
|
||||
}
|
||||
|
||||
pub async fn register(
|
||||
State(state): State<AppState>,
|
||||
Json(payload): Json<RegisterRequest>,
|
||||
@@ -64,16 +56,8 @@ pub async fn login(
|
||||
Ok(Json(LoginResponse { token }))
|
||||
}
|
||||
|
||||
pub async fn get_me(
|
||||
State(state): State<AppState>,
|
||||
UserId(user_id): UserId,
|
||||
) -> Result<Json<UserResponse>, ApiError> {
|
||||
let user = state.user_service.get_user_details(user_id).await?;
|
||||
|
||||
let response = UserResponse {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
};
|
||||
Ok(Json(response))
|
||||
pub fn auth_routes() -> axum::Router<AppState> {
|
||||
axum::Router::new()
|
||||
.route("/register", axum::routing::post(register))
|
||||
.route("/login", axum::routing::post(login))
|
||||
}
|
||||
|
||||
@@ -40,7 +40,8 @@ impl From<Media> for MediaResponse {
|
||||
pub fn media_routes() -> Router<AppState> {
|
||||
Router::new()
|
||||
.route("/", post(upload_media))
|
||||
.route("/{media_id}/file", get(get_media_file))
|
||||
.route("/{id}", get(get_media_details).delete(delete_media))
|
||||
.route("/{id}/file", get(get_media_file))
|
||||
.layer(DefaultBodyLimit::max(250 * 1024 * 1024))
|
||||
}
|
||||
|
||||
@@ -104,3 +105,21 @@ async fn get_media_file(
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_media_details(
|
||||
State(state): State<AppState>,
|
||||
UserId(user_id): UserId,
|
||||
Path(id): Path<Uuid>,
|
||||
) -> Result<Json<MediaResponse>, ApiError> {
|
||||
let media = state.media_service.get_media_details(id, user_id).await?;
|
||||
Ok(Json(media.into()))
|
||||
}
|
||||
|
||||
async fn delete_media(
|
||||
State(state): State<AppState>,
|
||||
UserId(user_id): UserId,
|
||||
Path(id): Path<Uuid>,
|
||||
) -> Result<StatusCode, ApiError> {
|
||||
state.media_service.delete_media(id, user_id).await?;
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod album_handlers;
|
||||
pub mod auth_handlers;
|
||||
pub mod media_handlers;
|
||||
pub mod user_handlers;
|
||||
|
||||
22
libertas_api/src/handlers/user_handlers.rs
Normal file
22
libertas_api/src/handlers/user_handlers.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use axum::{Json, Router, extract::State};
|
||||
use libertas_core::schema::UserResponse;
|
||||
|
||||
use crate::{error::ApiError, middleware::auth::UserId, state::AppState};
|
||||
|
||||
pub async fn get_me(
|
||||
State(state): State<AppState>,
|
||||
UserId(user_id): UserId,
|
||||
) -> Result<Json<UserResponse>, ApiError> {
|
||||
let user = state.user_service.get_user_details(user_id).await?;
|
||||
|
||||
let response = UserResponse {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
};
|
||||
Ok(Json(response))
|
||||
}
|
||||
|
||||
pub fn user_routes() -> Router<AppState> {
|
||||
Router::new().route("/me", axum::routing::get(get_me))
|
||||
}
|
||||
Reference in New Issue
Block a user