use axum::{ extract::{Extension, Path}, http::StatusCode, routing::{delete, get, post}, Json, Router, }; use sqlx::PgPool; use uuid::Uuid; use crate::error::AppError; use crate::models::share::{CreateShareDto, Share, ShareResponse}; use crate::services::auth::AuthUser; pub fn routes() -> Router { Router::new() .route("/shares", get(list_shares)) .route("/shares", post(create_share)) .route("/shares/:id", get(get_share)) .route("/shares/:id", delete(delete_share)) .route("/shares/access/:access_key", get(access_shared_file)) } async fn list_shares( auth_user: AuthUser, Extension(pool): Extension, ) -> Result>, AppError> { let owned_shares = Share::list_by_owner(&pool, auth_user.id).await?; let received_shares = Share::list_by_recipient(&pool, auth_user.id).await?; let mut share_responses = Vec::new(); for share in owned_shares { let share_response = Share::get_full_share_details(&pool, share.id).await?; share_responses.push(share_response); } for share in received_shares { let share_response = Share::get_full_share_details(&pool, share.id).await?; share_responses.push(share_response); } Ok(Json(share_responses)) } async fn create_share( auth_user: AuthUser, Extension(pool): Extension, Json(create_share_dto): Json, ) -> Result, AppError> { let share = Share::create(&pool, auth_user.id, create_share_dto).await?; Ok(Json(share)) } async fn get_share( auth_user: AuthUser, Extension(pool): Extension, Path(id): Path, ) -> Result, AppError> { let share = Share::find_by_id(&pool, id).await?; if share.owner_id != auth_user.id && share.recipient_id != Some(auth_user.id) { return Err(AppError::AccessDenied("You don't have access to this share".to_string())); } let share_response = Share::get_full_share_details(&pool, id).await?; Ok(Json(share_response)) } async fn delete_share( auth_user: AuthUser, Extension(pool): Extension, Path(id): Path, ) -> Result { Share::delete(&pool, id, auth_user.id).await?; Ok(StatusCode::NO_CONTENT) } async fn access_shared_file( Extension(pool): Extension, Path(access_key): Path, ) -> Result, AppError> { let share = Share::find_by_access_key(&pool, &access_key).await?; if let Some(expires_at) = share.expires_at { if expires_at < time::OffsetDateTime::now_utc() { return Err(AppError::AccessDenied("This share has expired".to_string())); } } let share_response = Share::get_full_share_details(&pool, share.id).await?; Ok(Json(share_response)) }