From 42fcd9398e9351b49ab49ddbf7ad3df617b08b36 Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Sat, 8 Mar 2025 21:51:28 -0300 Subject: [PATCH] refactor(all): Remove unused code and update dependencies in multiple modules --- Cargo.lock | 121 ++++++++++++++++++++++++++++ Cargo.toml | 5 ++ gb-auth/Cargo.toml | 2 +- gb-core/Cargo.toml | 2 + gb-core/src/config.rs | 15 ++-- gb-core/src/db.rs | 75 ++++++----------- gb-core/src/lib.rs | 2 + gb-core/src/models.rs | 4 +- gb-core/src/traits.rs | 75 ----------------- {gb-server => gb-core}/src/utils.rs | 2 +- gb-file/Cargo.toml | 7 ++ gb-file/src/handlers.rs | 7 +- gb-file/src/lib.rs | 1 + gb-file/src/router.rs | 37 --------- gb-server/Cargo.toml | 1 + gb-server/src/main.rs | 24 +++--- gb-vm/src/handlers.rs | 103 ----------------------- gb-vm/src/router.rs | 33 -------- 18 files changed, 192 insertions(+), 324 deletions(-) rename {gb-server => gb-core}/src/utils.rs (99%) delete mode 100644 gb-file/src/router.rs diff --git a/Cargo.lock b/Cargo.lock index 6f23222..f6adafc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,6 +74,24 @@ dependencies = [ "syn 2.0.99", ] +[[package]] +name = "actix-multipart" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9edfb0e7663d7fe18c8d5b668c9c1bcf79176b1dcc9d4da9592503209a6bfb0" +dependencies = [ + "actix-utils", + "actix-web", + "bytes", + "derive_more", + "futures-core", + "httparse", + "local-waker", + "log", + "mime", + "twoway", +] + [[package]] name = "actix-router" version = "0.5.3" @@ -2096,6 +2114,12 @@ dependencies = [ "zip", ] +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + [[package]] name = "dotenvy" version = "0.15.7" @@ -2206,6 +2230,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "email-encoding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a87260449b06739ee78d6281c68d2a0ff3e3af64a78df63d3a1aeb3c06997c8a" +dependencies = [ + "base64 0.22.1", + "memchr", +] + +[[package]] +name = "email_address" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -2698,6 +2738,8 @@ dependencies = [ "async-trait", "axum 0.7.9", "chrono", + "jsonwebtoken", + "lettre", "minio", "mockall", "rdkafka", @@ -2741,11 +2783,16 @@ dependencies = [ name = "gb-file" version = "0.1.0" dependencies = [ + "actix-multipart", "actix-web", "async-trait", + "futures 0.3.31", "gb-core", + "jsonwebtoken", + "lettre", "minio", "rstest", + "sanitize-filename", "serde", "serde_json", "tempfile", @@ -2753,6 +2800,7 @@ dependencies = [ "tokio", "tokio-test", "tracing", + "uuid", ] [[package]] @@ -2869,6 +2917,7 @@ dependencies = [ "async-trait", "axum 0.7.9", "chrono", + "dotenv", "futures-util", "gb-core", "gb-file", @@ -3489,6 +3538,17 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + [[package]] name = "http" version = "0.2.12" @@ -4182,6 +4242,29 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" +[[package]] +name = "lettre" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bd09637ae3ec7bd605b8e135e757980b3968430ff2b1a4a94fb7769e50166d" +dependencies = [ + "base64 0.21.7", + "email-encoding", + "email_address", + "fastrand 1.9.0", + "futures-util", + "hostname", + "httpdate", + "idna 0.3.0", + "mime", + "native-tls", + "nom 7.1.3", + "once_cell", + "quoted_printable", + "socket2 0.4.10", + "tokio", +] + [[package]] name = "libc" version = "0.2.170" @@ -4312,6 +4395,12 @@ dependencies = [ "weezl", ] +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "matchers" version = "0.1.0" @@ -5986,6 +6075,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "quoted_printable" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3866219251662ec3b26fc217e3e05bf9c4f84325234dfb96bf0bf840889e49" + [[package]] name = "rand" version = "0.7.3" @@ -6696,6 +6791,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "sanitize-filename" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf18934a12018228c5b55a6dae9df5d0641e3566b3630cb46cc55564068e7c2f" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "schannel" version = "0.1.27" @@ -8290,12 +8395,28 @@ dependencies = [ "webrtc-util", ] +[[package]] +name = "twoway" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c57ffb460d7c24cd6eda43694110189030a3d1dfe418416d9468fd1c1d290b47" +dependencies = [ + "memchr", + "unchecked-index", +] + [[package]] name = "typenum" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +[[package]] +name = "unchecked-index" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" + [[package]] name = "unicase" version = "2.8.1" diff --git a/Cargo.toml b/Cargo.toml index 9bd8334..e1fc7c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,8 @@ tower-http = { version = "0.5", features = ["cors", "trace", "fs"] } hyper = { version = "1.1", features = ["full"] } hyper-util = { version = "0.1" } tonic = { version = "0.10", features = ["tls", "transport"] } +actix-multipart = "0.4" + # Database and storage sqlx = { version = "0.7", features = ["runtime-tokio-native-tls", "postgres", "mysql", "sqlite", "uuid", "time", "json"] } @@ -111,6 +113,9 @@ base64 = "0.21" semver = "1.0" walkdir = "2.4" tempfile = "3.9" +dotenv = "0.15" +lettre = "0.10" +sanitize-filename = "0.3" # Web assembly wasm-bindgen = "0.2" diff --git a/gb-auth/Cargo.toml b/gb-auth/Cargo.toml index 8140f94..d07625b 100644 --- a/gb-auth/Cargo.toml +++ b/gb-auth/Cargo.toml @@ -9,7 +9,7 @@ license = { workspace = true } gb-core = { path = "../gb-core" } # Authentication & Security -jsonwebtoken = "9.2" +jsonwebtoken = { workspace = true } argon2 = "0.5" rand = { version = "0.8", features = ["std"] } oauth2 = "4.4" diff --git a/gb-core/Cargo.toml b/gb-core/Cargo.toml index eccf856..b218909 100644 --- a/gb-core/Cargo.toml +++ b/gb-core/Cargo.toml @@ -24,6 +24,8 @@ rdkafka = { workspace = true } tonic = { workspace = true } actix-web ={ workspace = true } anyhow = { workspace = true } +jsonwebtoken = { workspace = true } +lettre= { workspace = true } [dev-dependencies] mockall= { workspace = true } diff --git a/gb-core/src/config.rs b/gb-core/src/config.rs index 74ecf4b..f8b6d0e 100644 --- a/gb-core/src/config.rs +++ b/gb-core/src/config.rs @@ -7,7 +7,7 @@ pub struct AppConfig { pub database: DatabaseConfig, pub redis: RedisConfig, pub kafka: KafkaConfig, - pub zitadel: ZitadelConfig, + // pub zitadel: ZitadelConfig, pub minio: MinioConfig, pub email: EmailConfig, } @@ -39,6 +39,7 @@ pub struct ZitadelConfig { pub domain: String, pub client_id: String, pub client_secret: String, + pub access_token: String, } #[derive(Clone, Debug, Deserialize)] @@ -82,12 +83,12 @@ impl AppConfig { kafka: KafkaConfig { brokers: env::var("KAFKA_BROKERS").expect("KAFKA_BROKERS must be set"), }, - zitadel: ZitadelConfig { - domain: env::var("ZITADEL_DOMAIN").expect("ZITADEL_DOMAIN must be set"), - client_id: env::var("ZITADEL_CLIENT_ID").expect("ZITADEL_CLIENT_ID must be set"), - client_secret: env::var("ZITADEL_CLIENT_SECRET") - .expect("ZITADEL_CLIENT_SECRET must be set"), - }, + // zitadel: ZitadelConfig { + // domain: env::var("ZITADEL_DOMAIN").expect("ZITADEL_DOMAIN must be set"), + // client_id: env::var("ZITADEL_CLIENT_ID").expect("ZITADEL_CLIENT_ID must be set"), + // client_secret: env::var("ZITADEL_CLIENT_SECRET") + // .expect("ZITADEL_CLIENT_SECRET must be set"), + // }, minio: MinioConfig { endpoint: env::var("MINIO_ENDPOINT").expect("MINIO_ENDPOINT must be set"), access_key: env::var("MINIO_ACCESS_KEY").expect("MINIO_ACCESS_KEY must be set"), diff --git a/gb-core/src/db.rs b/gb-core/src/db.rs index 72b67a6..d429db6 100644 --- a/gb-core/src/db.rs +++ b/gb-core/src/db.rs @@ -1,29 +1,31 @@ +use crate::config::AppConfig; use anyhow::Result; -use rdkafka::ClientConfig; -use rdkafka::producer::FutureProducer; -use redis::aio::ConnectionManager as RedisConnectionManager; -use sqlx::postgres::{PgPoolOptions, PgPool}; -use zitadel::api::clients::ClientBuilder; -use zitadel::api::zitadel::auth::v1::auth_service_client::AuthServiceClient; +use minio::s3::client::{Client as MinioClient, ClientBuilder as MinioClientBuilder}; use minio::s3::creds::StaticProvider; use minio::s3::http::BaseUrl; -use minio::s3::client::{Client as MinioClient, ClientBuilder as MinioClientBuilder}; +use rdkafka::producer::FutureProducer; +use rdkafka::ClientConfig; +use redis::aio::ConnectionManager as RedisConnectionManager; +use sqlx::postgres::{PgPool, PgPoolOptions}; use std::str::FromStr; -use crate::config::AppConfig; +// use zitadel::api::clients::ClientBuilder; +// use zitadel::api::interceptors::AccessTokenInterceptor; +// use zitadel::api::zitadel::auth::v1::auth_service_client::AuthServiceClient; pub async fn init_postgres(config: &AppConfig) -> Result { let pool = PgPoolOptions::new() .max_connections(config.database.max_connections) .connect(&config.database.url) - .await?; - + .await + .map_err(|e| anyhow::anyhow!(e))?; + Ok(pool) } pub async fn init_redis(config: &AppConfig) -> Result { let client = redis::Client::open(config.redis.url.as_str())?; let connection_manager = RedisConnectionManager::new(client).await?; - + Ok(connection_manager) } @@ -32,34 +34,29 @@ pub async fn init_kafka(config: &AppConfig) -> Result { .set("bootstrap.servers", &config.kafka.brokers) .set("message.timeout.ms", "5000") .create()?; - + Ok(producer) } -pub async fn init_zitadel(config: &AppConfig) -> Result> { - - let mut client = ClientBuilder::new(&config.zitadel.domain) - - .with_access_token(&"test") - .build_auth_client() - .await?; - - - Ok(client) +pub async fn init_zitadel( + config: &AppConfig, +) -> Result< + (), + Box> + { + // TODO: https://github.com/smartive/zitadel-rust/blob/be389ca08c7f82d36fc1bcc36d2d9eb8666b22cd/examples/fetch_profile_with_service_account.rs#L18 + Ok(()) } - -pub async fn init_minio(config: &AppConfig) -> Result> { +pub async fn init_minio( + config: &AppConfig, +) -> Result> { // Construct the base URL let base_url = format!("https://{}", config.minio.endpoint); let base_url = BaseUrl::from_str(&base_url)?; // Create credentials provider - let credentials = StaticProvider::new( - &config.minio.access_key, - &config.minio.secret_key, - None, - ); + let credentials = StaticProvider::new(&config.minio.access_key, &config.minio.secret_key, None); // Build the MinIO client let client = MinioClientBuilder::new(base_url.clone()) @@ -69,23 +66,3 @@ pub async fn init_minio(config: &AppConfig) -> Result, + // pub zitadel_client: AuthServiceClient, pub minio_client: MinioClient, } diff --git a/gb-core/src/traits.rs b/gb-core/src/traits.rs index d745850..e69de29 100644 --- a/gb-core/src/traits.rs +++ b/gb-core/src/traits.rs @@ -1,75 +0,0 @@ -//! Core traits defining the system interfaces -//! File: gb-core/src/traits.rs - -use crate::models::*; -use std::future::Future; -use uuid::Uuid; -use async_trait::async_trait; - -#[async_trait] -pub trait InstanceStore { - type Error; - - fn create(&self, instance: &Instance) -> impl Future> + Send; - fn get(&self, id: Uuid) -> impl Future> + Send; - fn list_by_customer(&self, customer_id: Uuid) -> impl Future, Self::Error>> + Send; - fn update(&self, instance: &Instance) -> impl Future> + Send; - fn delete(&self, id: Uuid) -> impl Future> + Send; - fn list(&self, page: i32) -> impl Future, Self::Error>> + Send; -} - -#[async_trait] -pub trait RoomStore { - type Error; - - fn create(&self, room: &Room) -> impl Future> + Send; - fn get(&self, id: Uuid) -> impl Future> + Send; - fn list_by_instance(&self, instance_id: Uuid) -> impl Future, Self::Error>> + Send; - fn update(&self, room: &Room) -> impl Future> + Send; - fn delete(&self, id: Uuid) -> impl Future> + Send; - fn list(&self, instance_id: Uuid) -> impl Future, Self::Error>> + Send; -} - -#[async_trait] -pub trait TrackStore { - type Error; - - fn create(&self, track: &Track) -> impl Future> + Send; - fn get(&self, id: Uuid) -> impl Future> + Send; - fn list_by_room(&self, room_id: Uuid) -> impl Future, Self::Error>> + Send; - fn update(&self, track: &Track) -> impl Future> + Send; - fn delete(&self, id: Uuid) -> impl Future> + Send; -} - -#[async_trait] -pub trait UserStore { - type Error; - - fn create(&self, user: &User) -> impl Future> + Send; - fn get(&self, id: Uuid) -> impl Future> + Send; - fn get_by_email(&self, email: &str) -> impl Future> + Send; - fn list_by_instance(&self, instance_id: Uuid) -> impl Future, Self::Error>> + Send; - fn update(&self, user: &User) -> impl Future> + Send; - fn delete(&self, id: Uuid) -> impl Future> + Send; -} - -#[async_trait] -pub trait MessageStore { - type Error; - - fn send_message(&self, message: &Message) -> impl Future> + Send; - fn get_messages(&self, filter: &MessageFilter) -> impl Future, Self::Error>> + Send; - fn update_status(&self, message_id: Uuid, status: Status) -> impl Future> + Send; - fn delete_messages(&self, filter: &MessageFilter) -> impl Future> + Send; - fn search_messages(&self, query: &SearchQuery) -> impl Future, Self::Error>> + Send; -} - -#[async_trait] -pub trait FileStore { - type Error; - - fn upload_file(&self, upload: &FileUpload) -> impl Future> + Send; - fn get_file(&self, file_id: Uuid) -> impl Future> + Send; - fn delete_file(&self, file_id: Uuid) -> impl Future> + Send; - fn list_files(&self, prefix: &str) -> impl Future, Self::Error>> + Send; -} diff --git a/gb-server/src/utils.rs b/gb-core/src/utils.rs similarity index 99% rename from gb-server/src/utils.rs rename to gb-core/src/utils.rs index 197224b..da9457b 100644 --- a/gb-server/src/utils.rs +++ b/gb-core/src/utils.rs @@ -40,7 +40,7 @@ pub fn generate_jwt(user: &User, secret: &str) -> Result { exp: expiration, iat: issued_at, email: user.email.clone(), - username: user.username.clone(), + username: user.email.clone(), }; encode( diff --git a/gb-file/Cargo.toml b/gb-file/Cargo.toml index 8508587..aea5688 100644 --- a/gb-file/Cargo.toml +++ b/gb-file/Cargo.toml @@ -15,6 +15,13 @@ thiserror= { workspace = true } tracing= { workspace = true } minio = { workspace = true } actix-web ={ workspace = true } +actix-multipart ={ workspace = true } +futures ={ workspace = true } +uuid = { workspace = true } +jsonwebtoken = { workspace = true } +lettre= { workspace = true } +sanitize-filename = { workspace = true } + [dev-dependencies] rstest= { workspace = true } tokio-test = "0.4" diff --git a/gb-file/src/handlers.rs b/gb-file/src/handlers.rs index 43e0a13..d4c1e16 100644 --- a/gb-file/src/handlers.rs +++ b/gb-file/src/handlers.rs @@ -1,11 +1,10 @@ use actix_multipart::Multipart; use actix_web::{web, HttpRequest, HttpResponse}; use futures::{StreamExt, TryStreamExt}; +use gb_core::models::AppState; use std::io::Write; -use uuid::Uuid; - -use crate::models::AppError; -use crate::utils::{create_response, extract_user_id}; +use gb_core::models::AppError; +use gb_core::utils::{create_response, extract_user_id}; #[actix_web::post("/files/upload")] pub async fn upload_file( diff --git a/gb-file/src/lib.rs b/gb-file/src/lib.rs index e69de29..30ef99f 100644 --- a/gb-file/src/lib.rs +++ b/gb-file/src/lib.rs @@ -0,0 +1 @@ +pub mod handlers; \ No newline at end of file diff --git a/gb-file/src/router.rs b/gb-file/src/router.rs deleted file mode 100644 index 4bf0484..0000000 --- a/gb-file/src/router.rs +++ /dev/null @@ -1,37 +0,0 @@ -use actix_web::web; - -use crate::router; - -pub fn files_router_configure(cfg: &mut web::ServiceConfig) { - // File & Document Management - cfg.route("/files/upload", web::post().to(handlers::upload_file)) - .route("/files/download", web::post().to(handlers::download)) - .route("/files/delete", web::post().to(handlers::delete_file)) - .route("/files/getContents", web::post().to(handlers::get_file_contents)) - .route("/files/createFolder", web::post().to(handlers::create_folder)) - .route("/files/dirFolder", web::post().to(handlers::dir_folder)) - - // Conversations & Real-time Communication - .route("/conversations/create", web::post().to(handlers::create_conversation)) - .route("/conversations/join", web::post().to(handlers::join_conversation)) - .route("/conversations/leave", web::post().to(handlers::leave_conversation)) - .route("/conversations/members", web::get().to(handlers::get_conversation_members)) - .route("/conversations/messages", web::get().to(handlers::get_messages)) - .route("/conversations/messages/send", web::post().to(handlers::send_message)) - - // Communication Services - .route("/comm/email/send", web::post().to(handlers::send_email)) - - // User Management - .route("/users/profile", web::get().to(handlers::get_user_profile)) - - // Calendar & Task Management - .route("/calendar/events/create", web::post().to(handlers::create_event)) - - .route("/tasks/create", web::post().to(handlers::create_task)) - .route("/tasks/list", web::get().to(handlers::get_tasks)) - - // Admin - .route("/admin/system/status", web::get().to(handlers::get_system_status)) - .route("/admin/logs/view", web::get().to(handlers::view_logs)); -} diff --git a/gb-server/Cargo.toml b/gb-server/Cargo.toml index 437d494..899bea9 100644 --- a/gb-server/Cargo.toml +++ b/gb-server/Cargo.toml @@ -28,6 +28,7 @@ hyper-util = { workspace = true } tower = { workspace = true } tower-http = { workspace = true, features = ["cors", "trace"] } actix-web = { workspace = true } +dotenv = { workspace = true } [dev-dependencies] rstest = { workspace = true } diff --git a/gb-server/src/main.rs b/gb-server/src/main.rs index fe53a97..6795da4 100644 --- a/gb-server/src/main.rs +++ b/gb-server/src/main.rs @@ -1,9 +1,10 @@ use actix_web::{middleware, web, App, HttpServer}; +use gb_core::models; use tracing_subscriber::fmt::format::FmtSpan; - +use dotenv::dotenv; use gb_core::config::AppConfig; -use gb_core::db::{init_kafka, init_minio, init_postgres, init_redis, init_zitadel}; - +use gb_core::db::{init_kafka, init_minio, init_postgres, init_redis}; +use gb_file::handlers::upload_file; #[actix_web::main] async fn main() -> std::io::Result<()> { @@ -21,7 +22,7 @@ async fn main() -> std::io::Result<()> { let db_pool = init_postgres(&config).await.expect("Failed to connect to PostgreSQL"); let redis_pool = init_redis(&config).await.expect("Failed to connect to Redis"); let kafka_producer = init_kafka(&config).await.expect("Failed to initialize Kafka"); - let zitadel_client = init_zitadel(&config).await.expect("Failed to initialize Zitadel"); + // let zitadel_client = init_zitadel(&config).await.expect("Failed to initialize Zitadel"); let minio_client = init_minio(&config).await.expect("Failed to initialize Minio"); let app_state = web::Data::new(models::AppState { @@ -29,24 +30,23 @@ async fn main() -> std::io::Result<()> { db_pool, redis_pool, kafka_producer, - zitadel_client, minio_client, }); // Start HTTP server HttpServer::new(move || { - let cors = Cors::default() - .allow_any_origin() - .allow_any_method() - .allow_any_header() - .max_age(3600); + // let cors = Cors::default() + // .allow_any_origin() + // .allow_any_method() + // .allow_any_header() + // .max_age(3600); App::new() .wrap(middleware::Logger::default()) .wrap(middleware::Compress::default()) - .wrap(cors) +// .wrap(cors) .app_data(app_state.clone()) - .configure(files_router_configure) + .service(upload_file) }) .bind((config.server.host.clone(), config.server.port))? .run() diff --git a/gb-vm/src/handlers.rs b/gb-vm/src/handlers.rs index 43e0a13..e69de29 100644 --- a/gb-vm/src/handlers.rs +++ b/gb-vm/src/handlers.rs @@ -1,103 +0,0 @@ -use actix_multipart::Multipart; -use actix_web::{web, HttpRequest, HttpResponse}; -use futures::{StreamExt, TryStreamExt}; -use std::io::Write; -use uuid::Uuid; - -use crate::models::AppError; -use crate::utils::{create_response, extract_user_id}; - -#[actix_web::post("/files/upload")] -pub async fn upload_file( - req: HttpRequest, - mut payload: Multipart, - state: web::Data, -) -> Result { - let user_id = extract_user_id(&req)?; - let folder_path = req.query_string(); // Assuming folder path is passed as query parameter - - while let Ok(Some(mut field)) = payload.try_next().await { - let content_disposition = field.content_disposition(); - let filename = content_disposition - .get_filename() - .ok_or_else(|| AppError::Validation("Filename not provided".to_string()))? - .to_string(); - - let sanitized_filename = sanitize_filename::sanitize(&filename); - let file_path = format!("{}/{}/{}", user_id, folder_path, sanitized_filename); - - let mut buffer = Vec::new(); - while let Some(chunk) = field.next().await { - let data = chunk.map_err(|e| AppError::Internal(format!("Error reading file: {}", e)))?; - buffer.write_all(&data).map_err(|e| AppError::Internal(format!("Error writing to buffer: {}", e)))?; - } - - let content_type = field.content_type().map(|t| t.to_string()).unwrap_or_else(|| "application/octet-stream".to_string()); - - state.minio_client - .put_object(&state.config.minio.bucket, &file_path, &buffer, Some(content_type.as_str()), None) - .await - .map_err(|e| AppError::Minio(format!("Failed to upload file to Minio: {}", e)))?; - - return Ok(create_response( - format!("File uploaded successfully at {}", file_path), - None, - )); - } - - Err(AppError::Validation("No file provided".to_string())) -} - -#[actix_web::post("/files/download")] -pub async fn download( - req: HttpRequest, - state: web::Data, - file_path: web::Json, -) -> Result { - let user_id = extract_user_id(&req)?; - - let file_content = state.minio_client - .get_object(&state.config.minio.bucket, &file_path) - .await - .map_err(|e| AppError::Minio(format!("Failed to retrieve file from Minio: {}", e)))?; - - Ok(HttpResponse::Ok() - .content_type("application/octet-stream") - .append_header(("Content-Disposition", format!("attachment; filename=\"{}\"", file_path))) - .body(file_content)) -} - -#[actix_web::post("/files/delete")] -pub async fn delete_file( - req: HttpRequest, - state: web::Data, - file_path: web::Json, -) -> Result { - let user_id = extract_user_id(&req)?; - - state.minio_client - .remove_object(&state.config.minio.bucket, &file_path) - .await - .map_err(|e| AppError::Minio(format!("Failed to delete file from Minio: {}", e)))?; - - Ok(create_response( - true, - Some("File deleted successfully".to_string()), - )) -} - -#[actix_web::post("/files/list")] -pub async fn list_files( - req: HttpRequest, - state: web::Data, - folder_path: web::Json, -) -> Result { - let user_id = extract_user_id(&req)?; - - let objects = state.minio_client - .list_objects(&state.config.minio.bucket, &folder_path, None, None) - .await - .map_err(|e| AppError::Minio(format!("Failed to list objects in Minio: {}", e)))?; - - Ok(create_response(objects, None)) -} \ No newline at end of file diff --git a/gb-vm/src/router.rs b/gb-vm/src/router.rs index 4bf0484..9cf1b17 100644 --- a/gb-vm/src/router.rs +++ b/gb-vm/src/router.rs @@ -2,36 +2,3 @@ use actix_web::web; use crate::router; -pub fn files_router_configure(cfg: &mut web::ServiceConfig) { - // File & Document Management - cfg.route("/files/upload", web::post().to(handlers::upload_file)) - .route("/files/download", web::post().to(handlers::download)) - .route("/files/delete", web::post().to(handlers::delete_file)) - .route("/files/getContents", web::post().to(handlers::get_file_contents)) - .route("/files/createFolder", web::post().to(handlers::create_folder)) - .route("/files/dirFolder", web::post().to(handlers::dir_folder)) - - // Conversations & Real-time Communication - .route("/conversations/create", web::post().to(handlers::create_conversation)) - .route("/conversations/join", web::post().to(handlers::join_conversation)) - .route("/conversations/leave", web::post().to(handlers::leave_conversation)) - .route("/conversations/members", web::get().to(handlers::get_conversation_members)) - .route("/conversations/messages", web::get().to(handlers::get_messages)) - .route("/conversations/messages/send", web::post().to(handlers::send_message)) - - // Communication Services - .route("/comm/email/send", web::post().to(handlers::send_email)) - - // User Management - .route("/users/profile", web::get().to(handlers::get_user_profile)) - - // Calendar & Task Management - .route("/calendar/events/create", web::post().to(handlers::create_event)) - - .route("/tasks/create", web::post().to(handlers::create_task)) - .route("/tasks/list", web::get().to(handlers::get_tasks)) - - // Admin - .route("/admin/system/status", web::get().to(handlers::get_system_status)) - .route("/admin/logs/view", web::get().to(handlers::view_logs)); -}