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",
|
"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]]
|
[[package]]
|
||||||
name = "actix-router"
|
name = "actix-router"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
|
@ -2096,6 +2114,12 @@ dependencies = [
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dotenv"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dotenvy"
|
name = "dotenvy"
|
||||||
version = "0.15.7"
|
version = "0.15.7"
|
||||||
|
@ -2206,6 +2230,22 @@ dependencies = [
|
||||||
"zeroize",
|
"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]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.8.35"
|
version = "0.8.35"
|
||||||
|
@ -2698,6 +2738,8 @@ dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum 0.7.9",
|
"axum 0.7.9",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"jsonwebtoken",
|
||||||
|
"lettre",
|
||||||
"minio",
|
"minio",
|
||||||
"mockall",
|
"mockall",
|
||||||
"rdkafka",
|
"rdkafka",
|
||||||
|
@ -2741,11 +2783,16 @@ dependencies = [
|
||||||
name = "gb-file"
|
name = "gb-file"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"actix-multipart",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"futures 0.3.31",
|
||||||
"gb-core",
|
"gb-core",
|
||||||
|
"jsonwebtoken",
|
||||||
|
"lettre",
|
||||||
"minio",
|
"minio",
|
||||||
"rstest",
|
"rstest",
|
||||||
|
"sanitize-filename",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
@ -2753,6 +2800,7 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-test",
|
"tokio-test",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2869,6 +2917,7 @@ dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum 0.7.9",
|
"axum 0.7.9",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"dotenv",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"gb-core",
|
"gb-core",
|
||||||
"gb-file",
|
"gb-file",
|
||||||
|
@ -3489,6 +3538,17 @@ dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"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]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "0.2.12"
|
version = "0.2.12"
|
||||||
|
@ -4182,6 +4242,29 @@ version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
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]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.170"
|
version = "0.2.170"
|
||||||
|
@ -4312,6 +4395,12 @@ dependencies = [
|
||||||
"weezl",
|
"weezl",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "match_cfg"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchers"
|
name = "matchers"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -5986,6 +6075,12 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quoted_printable"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a3866219251662ec3b26fc217e3e05bf9c4f84325234dfb96bf0bf840889e49"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
|
@ -6696,6 +6791,16 @@ dependencies = [
|
||||||
"winapi-util",
|
"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]]
|
[[package]]
|
||||||
name = "schannel"
|
name = "schannel"
|
||||||
version = "0.1.27"
|
version = "0.1.27"
|
||||||
|
@ -8290,12 +8395,28 @@ dependencies = [
|
||||||
"webrtc-util",
|
"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]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.18.0"
|
version = "1.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unchecked-index"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicase"
|
name = "unicase"
|
||||||
version = "2.8.1"
|
version = "2.8.1"
|
||||||
|
|
|
@ -46,6 +46,8 @@ tower-http = { version = "0.5", features = ["cors", "trace", "fs"] }
|
||||||
hyper = { version = "1.1", features = ["full"] }
|
hyper = { version = "1.1", features = ["full"] }
|
||||||
hyper-util = { version = "0.1" }
|
hyper-util = { version = "0.1" }
|
||||||
tonic = { version = "0.10", features = ["tls", "transport"] }
|
tonic = { version = "0.10", features = ["tls", "transport"] }
|
||||||
|
actix-multipart = "0.4"
|
||||||
|
|
||||||
|
|
||||||
# Database and storage
|
# Database and storage
|
||||||
sqlx = { version = "0.7", features = ["runtime-tokio-native-tls", "postgres", "mysql", "sqlite", "uuid", "time", "json"] }
|
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"
|
semver = "1.0"
|
||||||
walkdir = "2.4"
|
walkdir = "2.4"
|
||||||
tempfile = "3.9"
|
tempfile = "3.9"
|
||||||
|
dotenv = "0.15"
|
||||||
|
lettre = "0.10"
|
||||||
|
sanitize-filename = "0.3"
|
||||||
|
|
||||||
# Web assembly
|
# Web assembly
|
||||||
wasm-bindgen = "0.2"
|
wasm-bindgen = "0.2"
|
||||||
|
|
|
@ -9,7 +9,7 @@ license = { workspace = true }
|
||||||
gb-core = { path = "../gb-core" }
|
gb-core = { path = "../gb-core" }
|
||||||
|
|
||||||
# Authentication & Security
|
# Authentication & Security
|
||||||
jsonwebtoken = "9.2"
|
jsonwebtoken = { workspace = true }
|
||||||
argon2 = "0.5"
|
argon2 = "0.5"
|
||||||
rand = { version = "0.8", features = ["std"] }
|
rand = { version = "0.8", features = ["std"] }
|
||||||
oauth2 = "4.4"
|
oauth2 = "4.4"
|
||||||
|
|
|
@ -24,6 +24,8 @@ rdkafka = { workspace = true }
|
||||||
tonic = { workspace = true }
|
tonic = { workspace = true }
|
||||||
actix-web ={ workspace = true }
|
actix-web ={ workspace = true }
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
|
jsonwebtoken = { workspace = true }
|
||||||
|
lettre= { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
mockall= { workspace = true }
|
mockall= { workspace = true }
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub struct AppConfig {
|
||||||
pub database: DatabaseConfig,
|
pub database: DatabaseConfig,
|
||||||
pub redis: RedisConfig,
|
pub redis: RedisConfig,
|
||||||
pub kafka: KafkaConfig,
|
pub kafka: KafkaConfig,
|
||||||
pub zitadel: ZitadelConfig,
|
// pub zitadel: ZitadelConfig,
|
||||||
pub minio: MinioConfig,
|
pub minio: MinioConfig,
|
||||||
pub email: EmailConfig,
|
pub email: EmailConfig,
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ pub struct ZitadelConfig {
|
||||||
pub domain: String,
|
pub domain: String,
|
||||||
pub client_id: String,
|
pub client_id: String,
|
||||||
pub client_secret: String,
|
pub client_secret: String,
|
||||||
|
pub access_token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
@ -82,12 +83,12 @@ impl AppConfig {
|
||||||
kafka: KafkaConfig {
|
kafka: KafkaConfig {
|
||||||
brokers: env::var("KAFKA_BROKERS").expect("KAFKA_BROKERS must be set"),
|
brokers: env::var("KAFKA_BROKERS").expect("KAFKA_BROKERS must be set"),
|
||||||
},
|
},
|
||||||
zitadel: ZitadelConfig {
|
// zitadel: ZitadelConfig {
|
||||||
domain: env::var("ZITADEL_DOMAIN").expect("ZITADEL_DOMAIN must be set"),
|
// 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_id: env::var("ZITADEL_CLIENT_ID").expect("ZITADEL_CLIENT_ID must be set"),
|
||||||
client_secret: env::var("ZITADEL_CLIENT_SECRET")
|
// client_secret: env::var("ZITADEL_CLIENT_SECRET")
|
||||||
.expect("ZITADEL_CLIENT_SECRET must be set"),
|
// .expect("ZITADEL_CLIENT_SECRET must be set"),
|
||||||
},
|
// },
|
||||||
minio: MinioConfig {
|
minio: MinioConfig {
|
||||||
endpoint: env::var("MINIO_ENDPOINT").expect("MINIO_ENDPOINT must be set"),
|
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"),
|
access_key: env::var("MINIO_ACCESS_KEY").expect("MINIO_ACCESS_KEY must be set"),
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
|
use crate::config::AppConfig;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use rdkafka::ClientConfig;
|
use minio::s3::client::{Client as MinioClient, ClientBuilder as MinioClientBuilder};
|
||||||
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::creds::StaticProvider;
|
use minio::s3::creds::StaticProvider;
|
||||||
use minio::s3::http::BaseUrl;
|
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 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> {
|
pub async fn init_postgres(config: &AppConfig) -> Result<PgPool> {
|
||||||
let pool = PgPoolOptions::new()
|
let pool = PgPoolOptions::new()
|
||||||
.max_connections(config.database.max_connections)
|
.max_connections(config.database.max_connections)
|
||||||
.connect(&config.database.url)
|
.connect(&config.database.url)
|
||||||
.await?;
|
.await
|
||||||
|
.map_err(|e| anyhow::anyhow!(e))?;
|
||||||
|
|
||||||
Ok(pool)
|
Ok(pool)
|
||||||
}
|
}
|
||||||
|
@ -36,30 +38,25 @@ pub async fn init_kafka(config: &AppConfig) -> Result<FutureProducer> {
|
||||||
Ok(producer)
|
Ok(producer)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn init_zitadel(config: &AppConfig) -> Result<AuthServiceClient<tonic::transport::Channel>> {
|
pub async fn init_zitadel(
|
||||||
|
config: &AppConfig,
|
||||||
let mut client = ClientBuilder::new(&config.zitadel.domain)
|
) -> Result<
|
||||||
|
(),
|
||||||
.with_access_token(&"test")
|
Box<dyn std::error::Error>>
|
||||||
.build_auth_client()
|
{
|
||||||
.await?;
|
// TODO: https://github.com/smartive/zitadel-rust/blob/be389ca08c7f82d36fc1bcc36d2d9eb8666b22cd/examples/fetch_profile_with_service_account.rs#L18
|
||||||
|
Ok(())
|
||||||
|
|
||||||
Ok(client)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn init_minio(
|
||||||
pub async fn init_minio(config: &AppConfig) -> Result<MinioClient, Box<dyn std::error::Error + Send + Sync>> {
|
config: &AppConfig,
|
||||||
|
) -> Result<MinioClient, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
// Construct the base URL
|
// Construct the base URL
|
||||||
let base_url = format!("https://{}", config.minio.endpoint);
|
let base_url = format!("https://{}", config.minio.endpoint);
|
||||||
let base_url = BaseUrl::from_str(&base_url)?;
|
let base_url = BaseUrl::from_str(&base_url)?;
|
||||||
|
|
||||||
// Create credentials provider
|
// Create credentials provider
|
||||||
let credentials = StaticProvider::new(
|
let credentials = StaticProvider::new(&config.minio.access_key, &config.minio.secret_key, None);
|
||||||
&config.minio.access_key,
|
|
||||||
&config.minio.secret_key,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Build the MinIO client
|
// Build the MinIO client
|
||||||
let client = MinioClientBuilder::new(base_url.clone())
|
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)
|
Ok(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,5 +3,7 @@ pub mod errors;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod traits;
|
pub mod traits;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod utils;
|
||||||
pub use errors::{Error, ErrorKind, Result};
|
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 serde::{Deserialize, Serialize};
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use uuid::Uuid;
|
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 serde_json::Value as JsonValue;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
@ -245,7 +245,7 @@ pub struct AppState {
|
||||||
pub db_pool: PgPool,
|
pub db_pool: PgPool,
|
||||||
pub redis_pool: RedisConnectionManager,
|
pub redis_pool: RedisConnectionManager,
|
||||||
pub kafka_producer: FutureProducer,
|
pub kafka_producer: FutureProducer,
|
||||||
pub zitadel_client: AuthServiceClient<tonic::transport::Channel>,
|
// pub zitadel_client: AuthServiceClient<tonic::transport::Channel>,
|
||||||
pub minio_client: MinioClient,
|
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,
|
exp: expiration,
|
||||||
iat: issued_at,
|
iat: issued_at,
|
||||||
email: user.email.clone(),
|
email: user.email.clone(),
|
||||||
username: user.username.clone(),
|
username: user.email.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
encode(
|
encode(
|
|
@ -15,6 +15,13 @@ thiserror= { workspace = true }
|
||||||
tracing= { workspace = true }
|
tracing= { workspace = true }
|
||||||
minio = { workspace = true }
|
minio = { workspace = true }
|
||||||
actix-web ={ 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]
|
[dev-dependencies]
|
||||||
rstest= { workspace = true }
|
rstest= { workspace = true }
|
||||||
tokio-test = "0.4"
|
tokio-test = "0.4"
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use actix_multipart::Multipart;
|
use actix_multipart::Multipart;
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use futures::{StreamExt, TryStreamExt};
|
use futures::{StreamExt, TryStreamExt};
|
||||||
|
use gb_core::models::AppState;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use uuid::Uuid;
|
use gb_core::models::AppError;
|
||||||
|
use gb_core::utils::{create_response, extract_user_id};
|
||||||
use crate::models::AppError;
|
|
||||||
use crate::utils::{create_response, extract_user_id};
|
|
||||||
|
|
||||||
#[actix_web::post("/files/upload")]
|
#[actix_web::post("/files/upload")]
|
||||||
pub async fn upload_file(
|
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 = { workspace = true }
|
||||||
tower-http = { workspace = true, features = ["cors", "trace"] }
|
tower-http = { workspace = true, features = ["cors", "trace"] }
|
||||||
actix-web = { workspace = true }
|
actix-web = { workspace = true }
|
||||||
|
dotenv = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rstest = { workspace = true }
|
rstest = { workspace = true }
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use actix_web::{middleware, web, App, HttpServer};
|
use actix_web::{middleware, web, App, HttpServer};
|
||||||
|
use gb_core::models;
|
||||||
use tracing_subscriber::fmt::format::FmtSpan;
|
use tracing_subscriber::fmt::format::FmtSpan;
|
||||||
|
use dotenv::dotenv;
|
||||||
use gb_core::config::AppConfig;
|
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]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
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 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 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 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 minio_client = init_minio(&config).await.expect("Failed to initialize Minio");
|
||||||
|
|
||||||
let app_state = web::Data::new(models::AppState {
|
let app_state = web::Data::new(models::AppState {
|
||||||
|
@ -29,24 +30,23 @@ async fn main() -> std::io::Result<()> {
|
||||||
db_pool,
|
db_pool,
|
||||||
redis_pool,
|
redis_pool,
|
||||||
kafka_producer,
|
kafka_producer,
|
||||||
zitadel_client,
|
|
||||||
minio_client,
|
minio_client,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start HTTP server
|
// Start HTTP server
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
let cors = Cors::default()
|
// let cors = Cors::default()
|
||||||
.allow_any_origin()
|
// .allow_any_origin()
|
||||||
.allow_any_method()
|
// .allow_any_method()
|
||||||
.allow_any_header()
|
// .allow_any_header()
|
||||||
.max_age(3600);
|
// .max_age(3600);
|
||||||
|
|
||||||
App::new()
|
App::new()
|
||||||
.wrap(middleware::Logger::default())
|
.wrap(middleware::Logger::default())
|
||||||
.wrap(middleware::Compress::default())
|
.wrap(middleware::Compress::default())
|
||||||
.wrap(cors)
|
// .wrap(cors)
|
||||||
.app_data(app_state.clone())
|
.app_data(app_state.clone())
|
||||||
.configure(files_router_configure)
|
.service(upload_file)
|
||||||
})
|
})
|
||||||
.bind((config.server.host.clone(), config.server.port))?
|
.bind((config.server.host.clone(), config.server.port))?
|
||||||
.run()
|
.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;
|
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