refactor(all): Remove unused code and update dependencies in multiple modules
This commit is contained in:
parent
3291266a42
commit
42fcd9398e
18 changed files with 192 additions and 324 deletions
121
Cargo.lock
generated
121
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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<PgPool> {
|
||||
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<RedisConnectionManager> {
|
||||
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<FutureProducer> {
|
|||
.set("bootstrap.servers", &config.kafka.brokers)
|
||||
.set("message.timeout.ms", "5000")
|
||||
.create()?;
|
||||
|
||||
|
||||
Ok(producer)
|
||||
}
|
||||
|
||||
pub async fn init_zitadel(config: &AppConfig) -> Result<AuthServiceClient<tonic::transport::Channel>> {
|
||||
|
||||
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<dyn std::error::Error>>
|
||||
{
|
||||
// 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<MinioClient, Box<dyn std::error::Error + Send + Sync>> {
|
||||
pub async fn init_minio(
|
||||
config: &AppConfig,
|
||||
) -> Result<MinioClient, Box<dyn std::error::Error + Send + Sync>> {
|
||||
// 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<MinioClient, Box<dyn std::
|
|||
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -3,5 +3,7 @@ pub mod errors;
|
|||
pub mod models;
|
||||
pub mod traits;
|
||||
pub mod config;
|
||||
pub mod utils;
|
||||
pub use errors::{Error, ErrorKind, Result};
|
||||
pub use utils::{create_response, extract_user_id};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use redis::aio::ConnectionManager as RedisConnectionManager;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::PgPool;
|
||||
use uuid::Uuid;
|
||||
use zitadel::api::zitadel::auth::v1::auth_service_client::AuthServiceClient;
|
||||
//use zitadel::api::zitadel::auth::v1::auth_service_client::AuthServiceClient;
|
||||
use serde_json::Value as JsonValue;
|
||||
use std::str::FromStr;
|
||||
|
||||
|
@ -245,7 +245,7 @@ pub struct AppState {
|
|||
pub db_pool: PgPool,
|
||||
pub redis_pool: RedisConnectionManager,
|
||||
pub kafka_producer: FutureProducer,
|
||||
pub zitadel_client: AuthServiceClient<tonic::transport::Channel>,
|
||||
// pub zitadel_client: AuthServiceClient<tonic::transport::Channel>,
|
||||
pub minio_client: MinioClient,
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Output = Result<Instance, Self::Error>> + Send;
|
||||
fn get(&self, id: Uuid) -> impl Future<Output = Result<Instance, Self::Error>> + Send;
|
||||
fn list_by_customer(&self, customer_id: Uuid) -> impl Future<Output = Result<Vec<Instance>, Self::Error>> + Send;
|
||||
fn update(&self, instance: &Instance) -> impl Future<Output = Result<Instance, Self::Error>> + Send;
|
||||
fn delete(&self, id: Uuid) -> impl Future<Output = Result<(), Self::Error>> + Send;
|
||||
fn list(&self, page: i32) -> impl Future<Output = Result<Vec<Instance>, Self::Error>> + Send;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait RoomStore {
|
||||
type Error;
|
||||
|
||||
fn create(&self, room: &Room) -> impl Future<Output = Result<Room, Self::Error>> + Send;
|
||||
fn get(&self, id: Uuid) -> impl Future<Output = Result<Room, Self::Error>> + Send;
|
||||
fn list_by_instance(&self, instance_id: Uuid) -> impl Future<Output = Result<Vec<Room>, Self::Error>> + Send;
|
||||
fn update(&self, room: &Room) -> impl Future<Output = Result<Room, Self::Error>> + Send;
|
||||
fn delete(&self, id: Uuid) -> impl Future<Output = Result<(), Self::Error>> + Send;
|
||||
fn list(&self, instance_id: Uuid) -> impl Future<Output = Result<Vec<Room>, Self::Error>> + Send;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait TrackStore {
|
||||
type Error;
|
||||
|
||||
fn create(&self, track: &Track) -> impl Future<Output = Result<Track, Self::Error>> + Send;
|
||||
fn get(&self, id: Uuid) -> impl Future<Output = Result<Track, Self::Error>> + Send;
|
||||
fn list_by_room(&self, room_id: Uuid) -> impl Future<Output = Result<Vec<Track>, Self::Error>> + Send;
|
||||
fn update(&self, track: &Track) -> impl Future<Output = Result<Track, Self::Error>> + Send;
|
||||
fn delete(&self, id: Uuid) -> impl Future<Output = Result<(), Self::Error>> + Send;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait UserStore {
|
||||
type Error;
|
||||
|
||||
fn create(&self, user: &User) -> impl Future<Output = Result<User, Self::Error>> + Send;
|
||||
fn get(&self, id: Uuid) -> impl Future<Output = Result<User, Self::Error>> + Send;
|
||||
fn get_by_email(&self, email: &str) -> impl Future<Output = Result<User, Self::Error>> + Send;
|
||||
fn list_by_instance(&self, instance_id: Uuid) -> impl Future<Output = Result<Vec<User>, Self::Error>> + Send;
|
||||
fn update(&self, user: &User) -> impl Future<Output = Result<User, Self::Error>> + Send;
|
||||
fn delete(&self, id: Uuid) -> impl Future<Output = Result<(), Self::Error>> + Send;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait MessageStore {
|
||||
type Error;
|
||||
|
||||
fn send_message(&self, message: &Message) -> impl Future<Output = Result<MessageId, Self::Error>> + Send;
|
||||
fn get_messages(&self, filter: &MessageFilter) -> impl Future<Output = Result<Vec<Message>, Self::Error>> + Send;
|
||||
fn update_status(&self, message_id: Uuid, status: Status) -> impl Future<Output = Result<(), Self::Error>> + Send;
|
||||
fn delete_messages(&self, filter: &MessageFilter) -> impl Future<Output = Result<(), Self::Error>> + Send;
|
||||
fn search_messages(&self, query: &SearchQuery) -> impl Future<Output = Result<Vec<Message>, Self::Error>> + Send;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait FileStore {
|
||||
type Error;
|
||||
|
||||
fn upload_file(&self, upload: &FileUpload) -> impl Future<Output = Result<FileInfo, Self::Error>> + Send;
|
||||
fn get_file(&self, file_id: Uuid) -> impl Future<Output = Result<FileContent, Self::Error>> + Send;
|
||||
fn delete_file(&self, file_id: Uuid) -> impl Future<Output = Result<(), Self::Error>> + Send;
|
||||
fn list_files(&self, prefix: &str) -> impl Future<Output = Result<Vec<FileInfo>, Self::Error>> + Send;
|
||||
}
|
|
@ -40,7 +40,7 @@ pub fn generate_jwt(user: &User, secret: &str) -> Result<String, AppError> {
|
|||
exp: expiration,
|
||||
iat: issued_at,
|
||||
email: user.email.clone(),
|
||||
username: user.username.clone(),
|
||||
username: user.email.clone(),
|
||||
};
|
||||
|
||||
encode(
|
|
@ -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"
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
pub mod handlers;
|
|
@ -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));
|
||||
}
|
|
@ -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 }
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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<AppState>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
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<AppState>,
|
||||
file_path: web::Json<String>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
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<AppState>,
|
||||
file_path: web::Json<String>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
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<AppState>,
|
||||
folder_path: web::Json<String>,
|
||||
) -> Result<HttpResponse, AppError> {
|
||||
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))
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue