diff --git a/Cargo.toml b/Cargo.toml index 42a97d9e..83fc1b4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,9 +7,8 @@ resolver = "2" cds-assets = { path = "crates/assets" } cds-media = { path = "crates/media" } cds-db = { path = "crates/db" } -cds-env = { path = "crates/env" } -cds-web = { path = "crates/web" } cds-config = { path = "crates/config" } +cds-web = { path = "crates/web" } cds-queue = { path = "crates/queue" } cds-metric = { path = "crates/metric" } cds-cache = { path = "crates/cache" } @@ -20,7 +19,6 @@ async-trait = { version = "0.1" } tokio = { version = "1.43", features = ["full"] } tokio-util = { version = "0.7.13" } futures = { version = "^0.3" } -futures-util = { version = "^0.3" } tower = { version = "0.5" } tower-http = { version = "0.6", features = ["cors", "fs", "trace"] } @@ -36,7 +34,6 @@ axum = { version = "0.8", features = [ ] } rust-embed = { version = "8.5" } mime = { version = "0.3" } -mime_guess = { version = "2.0" } wsrx = { version = "0.3", features = ["server"] } cookie = { version = "0.18.1" } tower_governor = { version = "0.6" } diff --git a/arts/favicon.webp b/arts/favicon.webp deleted file mode 100644 index cdbaf632..00000000 Binary files a/arts/favicon.webp and /dev/null differ diff --git a/assets/banner.txt b/assets/banner.txt deleted file mode 100644 index 5ca44c24..00000000 --- a/assets/banner.txt +++ /dev/null @@ -1,10 +0,0 @@ - _ _ _ _ - ___/ | ___ _ _ __| |___ __| | __ _/ | ___ - / __| |/ _ \| | | |/ _` / __|/ _` |/ _` | |/ _ \ -| (__| | (_) | |_| | (_| \__ \ (_| | (_| | | __/ - \___|_|\___/ \__,_|\__,_|___/\__,_|\__,_|_|\___| - Version {{version}} - -Commit: {{git_commit}} -Build At: {{build_at}} -GitHub: https://github.com/elabosak233/cdsctf diff --git a/crates/assets/embed/banner.txt b/crates/assets/embed/banner.txt new file mode 100644 index 00000000..599ac11d --- /dev/null +++ b/crates/assets/embed/banner.txt @@ -0,0 +1,10 @@ + ____ _ ____ _____ _____ + / ___|__| |___ / ___|_ _| ___| + | | / _` / __| | | | | |_ + | |__| (_| \__ \ |___ | | | _| + \____\__,_|___/\____| |_| |_| + Version {{version}} + +Commit: {{git_commit}} +Build At: {{build_at}} +GitHub: https://github.com/elabosak233/cdsctf diff --git a/crates/assets/embed/logo.svg b/crates/assets/embed/logo.svg new file mode 100644 index 00000000..cf76863e --- /dev/null +++ b/crates/assets/embed/logo.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/crates/assets/src/lib.rs b/crates/assets/src/lib.rs index d8250071..ebae6a1a 100644 --- a/crates/assets/src/lib.rs +++ b/crates/assets/src/lib.rs @@ -3,12 +3,12 @@ use std::fs; use rust_embed::Embed; #[derive(Embed)] -#[folder = "../assets/"] -pub struct Assets; +#[folder = "./embed/"] +pub struct Embeds; pub fn get(path: &str) -> Option> { if let Ok(file) = fs::read(format!("assets/{}", path)) { return Some(file); } - Assets::get(path).map(|e| e.data.into_owned()) + Embeds::get(path).map(|e| e.data.into_owned()) } diff --git a/crates/cache/Cargo.toml b/crates/cache/Cargo.toml index 80798b48..a19ec487 100644 --- a/crates/cache/Cargo.toml +++ b/crates/cache/Cargo.toml @@ -6,7 +6,7 @@ publish = false resolver = "2" [dependencies] -cds-env = {workspace = true} +cds-config = {workspace = true} fred = { workspace = true } once_cell = { workspace = true } diff --git a/crates/cache/src/lib.rs b/crates/cache/src/lib.rs index 3d7bccc4..ff2eadaf 100644 --- a/crates/cache/src/lib.rs +++ b/crates/cache/src/lib.rs @@ -72,7 +72,7 @@ pub async fn flush() -> Result<(), CacheError> { } pub async fn init() { - let config = Config::from_url(&cds_env::get_env().cache.url).unwrap(); + let config = Config::from_url(&cds_config::get_config().cache.url).unwrap(); let client = Client::new(config, None, None, None); client.init().await.unwrap(); diff --git a/crates/cluster/Cargo.toml b/crates/cluster/Cargo.toml index 6c7e1275..a7eb8dcd 100644 --- a/crates/cluster/Cargo.toml +++ b/crates/cluster/Cargo.toml @@ -6,7 +6,6 @@ publish = false resolver = "2" [dependencies] -cds-env = { workspace = true } cds-config = { workspace = true } cds-db = { workspace = true } diff --git a/crates/cluster/src/lib.rs b/crates/cluster/src/lib.rs index adaeb741..b6625e6f 100644 --- a/crates/cluster/src/lib.rs +++ b/crates/cluster/src/lib.rs @@ -1,8 +1,7 @@ pub mod traits; -use std::{collections::BTreeMap, process}; -use std::path::Path; -use anyhow::anyhow; +use std::{collections::BTreeMap, path::Path, process}; + use axum::extract::ws::WebSocket; use k8s_openapi::{ api::core::v1::{ @@ -14,9 +13,9 @@ use k8s_openapi::{ use kube::{ Client as K8sClient, Config, api::{Api, DeleteParams, ListParams, PostParams}, + config::Kubeconfig, runtime::wait::conditions, }; -use kube::config::Kubeconfig; use once_cell::sync::OnceCell; use tokio_util::codec::Framed; use tracing::{error, info}; @@ -30,9 +29,13 @@ pub fn get_k8s_client() -> K8sClient { } pub async fn init() -> Result<(), ClusterError> { - let result = Config::from_custom_kubeconfig(Kubeconfig::read_from( - Path::new(cds_env::get_env().cluster.kube_config_path.as_str()) - )?, &Default::default()).await; + let result = Config::from_custom_kubeconfig( + Kubeconfig::read_from(Path::new( + cds_config::get_config().cluster.kube_config_path.as_str(), + ))?, + &Default::default(), + ) + .await; if let Err(e) = result { error!( "Failed to create Kubernetes client from custom config: {:?}", @@ -52,11 +55,11 @@ pub async fn init() -> Result<(), ClusterError> { let namespace_api: Api = Api::all(get_k8s_client().clone()); let namespaces = namespace_api.list(&ListParams::default()).await?; if !namespaces.items.iter().any(|namespace| { - namespace.metadata.name == Some(cds_env::get_env().clone().cluster.namespace) + namespace.metadata.name == Some(cds_config::get_config().clone().cluster.namespace) }) { let namespace = Namespace { metadata: ObjectMeta { - name: Some(cds_env::get_env().clone().cluster.namespace), + name: Some(cds_config::get_config().clone().cluster.namespace), ..Default::default() }, ..Default::default() @@ -85,7 +88,7 @@ pub async fn create( let pod_api: Api = Api::namespaced( get_k8s_client(), - cds_env::get_env().cluster.namespace.as_str(), + cds_config::get_config().cluster.namespace.as_str(), ); let mut env_vars: Vec = env @@ -157,13 +160,13 @@ pub async fn create( let mut nats: Vec = Vec::new(); - match cds_env::get_env().cluster.proxy.is_enabled { + match cds_config::get_config().cluster.proxy.is_enabled { true => { for port in env.ports { nats.push(cds_db::entity::pod::Nat { src: format!("{}", port), dst: None, - proxy: cds_env::get_env().cluster.proxy.is_enabled, + proxy: cds_config::get_config().cluster.proxy.is_enabled, entry: None, }); } @@ -171,7 +174,7 @@ pub async fn create( false => { let service_api: Api = Api::namespaced( get_k8s_client(), - cds_env::get_env().cluster.namespace.as_str(), + cds_config::get_config().cluster.namespace.as_str(), ); let service_ports: Vec = env .ports @@ -208,10 +211,10 @@ pub async fn create( nats.push(cds_db::entity::pod::Nat { src: format!("{}", port.port), dst: Some(format!("{}", node_port)), - proxy: cds_env::get_env().cluster.proxy.is_enabled, + proxy: cds_config::get_config().cluster.proxy.is_enabled, entry: Some(format!( "{}:{}", - cds_config::get_config().await.cluster.entry, + cds_config::get_config().cluster.entry_host, node_port )), }); @@ -228,12 +231,12 @@ pub async fn create( pub async fn delete(name: String) { let pod_api: Api = Api::namespaced( get_k8s_client(), - cds_env::get_env().cluster.namespace.as_str(), + cds_config::get_config().cluster.namespace.as_str(), ); let _ = pod_api.delete(&name, &DeleteParams::default()).await; let service_api: Api = Api::namespaced( get_k8s_client(), - cds_env::get_env().cluster.namespace.as_str(), + cds_config::get_config().cluster.namespace.as_str(), ); let _ = service_api.delete(&name, &DeleteParams::default()).await; } @@ -241,7 +244,7 @@ pub async fn delete(name: String) { pub async fn wsrx(name: String, port: u16, ws: WebSocket) -> Result<(), ClusterError> { let pod_api: Api = Api::namespaced( get_k8s_client(), - cds_env::get_env().cluster.namespace.as_str(), + cds_config::get_config().cluster.namespace.as_str(), ); let mut pf = pod_api.portforward(&name, &[port]).await?; let pfw = pf.take_stream(port); diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml index b144b0b2..33fd20d5 100644 --- a/crates/config/Cargo.toml +++ b/crates/config/Cargo.toml @@ -6,9 +6,11 @@ publish = false resolver = "2" [dependencies] -cds-db = { workspace = true } -cds-cache = { workspace = true } - -sea-orm = { workspace = true } +once_cell = { workspace = true } serde = { workspace = true } -serde_json = { workspace = true } \ No newline at end of file +tokio = { workspace = true } +tracing = { workspace = true } +toml = { workspace = true } + +[lib] +path = "src/lib.rs" diff --git a/crates/config/src/auth/mod.rs b/crates/config/src/auth/mod.rs index b571be1c..0794c4d4 100644 --- a/crates/config/src/auth/mod.rs +++ b/crates/config/src/auth/mod.rs @@ -1,9 +1,7 @@ -pub mod registration; - -use sea_orm::FromJsonQueryResult; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Serialize, Deserialize, FromJsonQueryResult, PartialEq, Eq, Default)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct Config { - pub registration: registration::Config, + pub secret: String, + pub expiration: i64, } diff --git a/crates/config/src/auth/registration/email.rs b/crates/config/src/auth/registration/email.rs deleted file mode 100644 index 275b0636..00000000 --- a/crates/config/src/auth/registration/email.rs +++ /dev/null @@ -1,7 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)] -pub struct Config { - pub enabled: bool, - pub domains: Vec, -} diff --git a/crates/config/src/auth/registration/mod.rs b/crates/config/src/auth/registration/mod.rs deleted file mode 100644 index 53493aeb..00000000 --- a/crates/config/src/auth/registration/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod email; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)] -pub struct Config { - pub enabled: bool, - pub captcha: bool, - pub email: email::Config, -} diff --git a/crates/env/src/cache/mod.rs b/crates/config/src/cache/mod.rs similarity index 84% rename from crates/env/src/cache/mod.rs rename to crates/config/src/cache/mod.rs index fec9473d..b3301afd 100644 --- a/crates/env/src/cache/mod.rs +++ b/crates/config/src/cache/mod.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Env { +pub struct Config { pub url: String, } diff --git a/crates/config/src/cluster/mod.rs b/crates/config/src/cluster/mod.rs index 2b76ba39..fea258fd 100644 --- a/crates/config/src/cluster/mod.rs +++ b/crates/config/src/cluster/mod.rs @@ -1,11 +1,11 @@ +pub mod proxy; -pub mod strategy; - -use sea_orm::FromJsonQueryResult; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, Serialize, Deserialize, FromJsonQueryResult, PartialEq, Eq, Default)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct Config { - pub entry: String, - pub strategy: strategy::Config, + pub namespace: String, + pub kube_config_path: String, + pub proxy: proxy::Config, + pub entry_host: String, } diff --git a/crates/env/src/cluster/proxy/mod.rs b/crates/config/src/cluster/proxy/mod.rs similarity index 70% rename from crates/env/src/cluster/proxy/mod.rs rename to crates/config/src/cluster/proxy/mod.rs index 30bbcb92..e8a1707b 100644 --- a/crates/env/src/cluster/proxy/mod.rs +++ b/crates/config/src/cluster/proxy/mod.rs @@ -1,7 +1,6 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Env { +pub struct Config { pub is_enabled: bool, - pub traffic_capture: bool, } diff --git a/crates/config/src/cluster/strategy.rs b/crates/config/src/cluster/strategy.rs deleted file mode 100644 index 37b232c1..00000000 --- a/crates/config/src/cluster/strategy.rs +++ /dev/null @@ -1,7 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)] -pub struct Config { - pub parallel_limit: u64, - pub request_limit: u64, -} diff --git a/crates/env/src/db/mod.rs b/crates/config/src/db/mod.rs similarity index 92% rename from crates/env/src/db/mod.rs rename to crates/config/src/db/mod.rs index 067b08c2..ab535799 100644 --- a/crates/env/src/db/mod.rs +++ b/crates/config/src/db/mod.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Env { +pub struct Config { pub host: String, pub port: u16, pub dbname: String, diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs index 961a7d08..09b776bc 100644 --- a/crates/config/src/lib.rs +++ b/crates/config/src/lib.rs @@ -1,39 +1,46 @@ pub mod auth; +pub mod cache; pub mod cluster; -pub mod site; -pub mod traits; +pub mod db; +pub mod media; +pub mod meta; +pub mod metric; +pub mod queue; +pub mod server; -use cds_db::get_db; -use sea_orm::EntityTrait; +use std::{path::Path, process}; + +use once_cell::sync::OnceCell; use serde::{Deserialize, Serialize}; +use tokio::fs::{self}; +use tracing::error; + +static APP_CONFIG: OnceCell = OnceCell::new(); -#[derive(Clone, Debug, Serialize, Deserialize, Default)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct Config { - pub site: site::Config, + pub server: server::Config, pub auth: auth::Config, + pub db: db::Config, + pub queue: queue::Config, + pub cache: cache::Config, + pub metric: metric::Config, pub cluster: cluster::Config, -} - -impl From for Config { - fn from(config: cds_db::entity::config::Model) -> Self { - serde_json::from_value::(config.value).unwrap() - } + pub media: media::Config, + pub meta: meta::Config, } pub async fn init() { - let config = cds_cache::get::("config").await.unwrap(); - if config.is_none() { - let model = cds_db::entity::config::Entity::find() - .one(get_db()) - .await - .unwrap(); - if let Some(model) = model { - let _ = cds_cache::set("config", Config::from(model.clone())).await; - } + let target_path = Path::new("application.toml"); + if target_path.exists() { + let content = fs::read_to_string("application.toml").await.unwrap(); + APP_CONFIG.set(toml::from_str(&content).unwrap()).unwrap(); + } else { + error!("Configuration application.toml not found."); + process::exit(1); } } -pub async fn get_config() -> Config { - let config = cds_cache::get::("config").await.unwrap(); - config.clone().unwrap() +pub fn get_config() -> Config { + APP_CONFIG.get().unwrap().clone() } diff --git a/crates/env/src/media/mod.rs b/crates/config/src/media/mod.rs similarity index 84% rename from crates/env/src/media/mod.rs rename to crates/config/src/media/mod.rs index 46d453a7..dd6ac6b6 100644 --- a/crates/env/src/media/mod.rs +++ b/crates/config/src/media/mod.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Env { +pub struct Config { pub path: String, } diff --git a/crates/config/src/meta/mod.rs b/crates/config/src/meta/mod.rs new file mode 100644 index 00000000..d58c1fc1 --- /dev/null +++ b/crates/config/src/meta/mod.rs @@ -0,0 +1,8 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct Config { + pub title: String, + pub description: String, + pub logo_path: String, +} diff --git a/crates/env/src/metric/mod.rs b/crates/config/src/metric/mod.rs similarity index 87% rename from crates/env/src/metric/mod.rs rename to crates/config/src/metric/mod.rs index 79618ccd..10357f48 100644 --- a/crates/env/src/metric/mod.rs +++ b/crates/config/src/metric/mod.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Env { +pub struct Config { pub is_enabled: bool, pub namespace: String, } diff --git a/crates/env/src/queue/mod.rs b/crates/config/src/queue/mod.rs similarity index 91% rename from crates/env/src/queue/mod.rs rename to crates/config/src/queue/mod.rs index 73110e69..df9cfee0 100644 --- a/crates/env/src/queue/mod.rs +++ b/crates/config/src/queue/mod.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Env { +pub struct Config { pub host: String, pub port: u16, pub username: String, diff --git a/crates/env/src/server/mod.rs b/crates/config/src/server/mod.rs similarity index 86% rename from crates/env/src/server/mod.rs rename to crates/config/src/server/mod.rs index fe46f99f..0eaa06a8 100644 --- a/crates/env/src/server/mod.rs +++ b/crates/config/src/server/mod.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Env { +pub struct Config { pub host: String, pub port: u16, } diff --git a/crates/config/src/site/mod.rs b/crates/config/src/site/mod.rs deleted file mode 100644 index b3c50339..00000000 --- a/crates/config/src/site/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -use sea_orm::FromJsonQueryResult; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, Serialize, Deserialize, FromJsonQueryResult, PartialEq, Eq, Default)] -pub struct Config { - pub title: String, - pub description: String, - pub color: String, - pub favicon: String, -} diff --git a/crates/config/src/traits.rs b/crates/config/src/traits.rs deleted file mode 100644 index 833f25e7..00000000 --- a/crates/config/src/traits.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub trait Merge { - fn merge(self, other: Self) -> Self; -} diff --git a/crates/db/Cargo.toml b/crates/db/Cargo.toml index e26f7be8..2ba49627 100644 --- a/crates/db/Cargo.toml +++ b/crates/db/Cargo.toml @@ -6,7 +6,7 @@ publish = false resolver = "2" [dependencies] -cds-env = { workspace = true } +cds-config = { workspace = true } cds-cache = { workspace = true } async-trait = { workspace = true } diff --git a/crates/db/src/entity/challenge.rs b/crates/db/src/entity/challenge.rs index c77b3282..878ba15c 100644 --- a/crates/db/src/entity/challenge.rs +++ b/crates/db/src/entity/challenge.rs @@ -2,9 +2,9 @@ use std::collections::HashMap; use async_trait::async_trait; use sea_orm::{ - ActiveModelBehavior, ActiveModelTrait, ConnectionTrait, DbErr, DeriveActiveEnum, - DeriveEntityModel, DerivePrimaryKey, EntityTrait, EnumIter, FromJsonQueryResult, - PrimaryKeyTrait, Related, RelationDef, RelationTrait, Set, + ActiveModelBehavior, ConnectionTrait, DbErr, DeriveActiveEnum, DeriveEntityModel, + DerivePrimaryKey, EntityTrait, EnumIter, FromJsonQueryResult, PrimaryKeyTrait, Related, + RelationDef, RelationTrait, Set, }; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; diff --git a/crates/db/src/entity/config.rs b/crates/db/src/entity/config.rs deleted file mode 100644 index 612b2a24..00000000 --- a/crates/db/src/entity/config.rs +++ /dev/null @@ -1,25 +0,0 @@ -use async_trait::async_trait; -use sea_orm::entity::prelude::*; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize, Default)] -#[sea_orm(table_name = "configs")] -pub struct Model { - #[sea_orm(primary_key)] - pub id: i64, - #[sea_orm(column_type = "JsonBinary")] - pub value: serde_json::Value, -} - -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] -pub enum Relation {} - -#[async_trait] -impl ActiveModelBehavior for ActiveModel { - async fn after_save(model: Model, _db: &C, _insert: bool) -> Result - where - C: ConnectionTrait, { - let _ = cds_cache::set("config", model.value.clone()).await; - Ok(model) - } -} diff --git a/crates/db/src/entity/mod.rs b/crates/db/src/entity/mod.rs index ca898184..da3682e4 100644 --- a/crates/db/src/entity/mod.rs +++ b/crates/db/src/entity/mod.rs @@ -1,5 +1,4 @@ pub mod challenge; -pub mod config; pub mod game; pub mod game_challenge; pub mod game_team; diff --git a/crates/db/src/lib.rs b/crates/db/src/lib.rs index b9d9ac76..97904f8b 100644 --- a/crates/db/src/lib.rs +++ b/crates/db/src/lib.rs @@ -12,11 +12,11 @@ static DB: OnceCell = OnceCell::new(); pub async fn init() { let url = format!( "postgres://{}:{}@{}:{}/{}", - cds_env::get_env().db.username, - cds_env::get_env().db.password, - cds_env::get_env().db.host, - cds_env::get_env().db.port, - cds_env::get_env().db.dbname, + cds_config::get_config().db.username, + cds_config::get_config().db.password, + cds_config::get_config().db.host, + cds_config::get_config().db.port, + cds_config::get_config().db.dbname, ); let mut opt = ConnectOptions::new(url); opt.max_connections(100) diff --git a/crates/db/src/transfer/config.rs b/crates/db/src/transfer/config.rs deleted file mode 100644 index 9ab75cea..00000000 --- a/crates/db/src/transfer/config.rs +++ /dev/null @@ -1,18 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use crate::entity; - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] -pub struct Config { - pub id: i64, - pub value: serde_json::Value, -} - -impl From for Config { - fn from(model: entity::config::Model) -> Self { - Self { - id: model.id, - value: model.value, - } - } -} diff --git a/crates/db/src/transfer/mod.rs b/crates/db/src/transfer/mod.rs index 8dac3437..f2a1f3d1 100644 --- a/crates/db/src/transfer/mod.rs +++ b/crates/db/src/transfer/mod.rs @@ -1,5 +1,4 @@ pub mod challenge; -pub mod config; pub mod game; pub mod game_challenge; pub mod game_team; diff --git a/crates/env/Cargo.toml b/crates/env/Cargo.toml deleted file mode 100644 index 55b486ee..00000000 --- a/crates/env/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "cds-env" -version = "0.0.1" -edition = "2024" -publish = false -resolver = "2" - -[dependencies] -once_cell = { workspace = true } -serde = { workspace = true } -tokio = { workspace = true } -tracing = { workspace = true } -toml = { workspace = true } - -[lib] -path = "src/lib.rs" diff --git a/crates/env/src/auth/mod.rs b/crates/env/src/auth/mod.rs deleted file mode 100644 index fd4d350c..00000000 --- a/crates/env/src/auth/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Env { - pub secret: String, - pub expiration: i64, -} diff --git a/crates/env/src/cluster/mod.rs b/crates/env/src/cluster/mod.rs deleted file mode 100644 index ea8cec2f..00000000 --- a/crates/env/src/cluster/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod proxy; - -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Env { - pub namespace: String, - pub kube_config_path: String, - pub proxy: proxy::Env, -} diff --git a/crates/env/src/lib.rs b/crates/env/src/lib.rs deleted file mode 100644 index b15aa1bb..00000000 --- a/crates/env/src/lib.rs +++ /dev/null @@ -1,44 +0,0 @@ -pub mod server; -pub mod cache; -pub mod cluster; -pub mod db; -pub mod metric; -pub mod queue; -pub mod media; -pub mod auth; - -use std::{path::Path, process}; - -use once_cell::sync::OnceCell; -use serde::{Deserialize, Serialize}; -use tokio::fs::{self}; -use tracing::error; - -static APP_ENV: OnceCell = OnceCell::new(); - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct Env { - pub server: server::Env, - pub auth: auth::Env, - pub db: db::Env, - pub queue: queue::Env, - pub cache: cache::Env, - pub metric: metric::Env, - pub cluster: cluster::Env, - pub media: media::Env, -} - -pub async fn init() { - let target_path = Path::new("application.toml"); - if target_path.exists() { - let content = fs::read_to_string("application.toml").await.unwrap(); - APP_ENV.set(toml::from_str(&content).unwrap()).unwrap(); - } else { - error!("Environment configuration application.toml not found."); - process::exit(1); - } -} - -pub fn get_env() -> Env { - APP_ENV.get().unwrap().clone() -} diff --git a/crates/media/Cargo.toml b/crates/media/Cargo.toml index b49ed087..1942e47a 100644 --- a/crates/media/Cargo.toml +++ b/crates/media/Cargo.toml @@ -6,7 +6,7 @@ publish = false resolver = "2" [dependencies] -cds-env = { workspace = true } +cds-config = { workspace = true } ring = { workspace = true } tokio = { workspace = true } diff --git a/crates/media/src/lib.rs b/crates/media/src/lib.rs index 2ca0bf48..66f05c69 100644 --- a/crates/media/src/lib.rs +++ b/crates/media/src/lib.rs @@ -12,7 +12,7 @@ use crate::traits::MediaError; pub async fn get(path: String, filename: String) -> Result, MediaError> { let filepath = - PathBuf::from(cds_env::get_env().media.path).join(format!("{}/{}", path, filename)); + PathBuf::from(cds_config::get_config().media.path).join(format!("{}/{}", path, filename)); match File::open(&filepath).await { Ok(mut file) => { @@ -27,7 +27,7 @@ pub async fn get(path: String, filename: String) -> Result, MediaError> } pub async fn scan_dir(path: String) -> Result, MediaError> { - let filepath = PathBuf::from(cds_env::get_env().media.path).join(path); + let filepath = PathBuf::from(cds_config::get_config().media.path).join(path); let mut files = Vec::new(); if metadata(&filepath).await.is_err() { @@ -50,7 +50,7 @@ pub async fn scan_dir(path: String) -> Result, MediaError> { pub async fn save(path: String, filename: String, data: Vec) -> Result<(), MediaError> { let filepath = - PathBuf::from(cds_env::get_env().media.path).join(format!("{}/{}", path, filename)); + PathBuf::from(cds_config::get_config().media.path).join(format!("{}/{}", path, filename)); if let Some(parent) = filepath.parent() { if metadata(parent).await.is_err() { create_dir_all(parent).await?; @@ -63,7 +63,7 @@ pub async fn save(path: String, filename: String, data: Vec) -> Result<(), M pub async fn delete(path: String, filename: String) -> Result<(), MediaError> { let filepath = - PathBuf::from(cds_env::get_env().media.path).join(format!("{}/{}", path, filename)); + PathBuf::from(cds_config::get_config().media.path).join(format!("{}/{}", path, filename)); if metadata(&filepath).await.is_ok() { remove_file(&filepath).await?; } @@ -71,7 +71,7 @@ pub async fn delete(path: String, filename: String) -> Result<(), MediaError> { } pub async fn delete_dir(path: String) -> Result<(), MediaError> { - let filepath = PathBuf::from(cds_env::get_env().media.path).join(path); + let filepath = PathBuf::from(cds_config::get_config().media.path).join(path); if metadata(&filepath).await.is_ok() { remove_dir_all(&filepath).await?; } diff --git a/crates/metric/Cargo.toml b/crates/metric/Cargo.toml index c9a03091..5964014e 100644 --- a/crates/metric/Cargo.toml +++ b/crates/metric/Cargo.toml @@ -6,7 +6,7 @@ publish = false resolver = "2" [dependencies] -cds-env = { workspace = true } +cds-config = { workspace = true } prometheus = { workspace = true } once_cell = { workspace = true } \ No newline at end of file diff --git a/crates/metric/src/lib.rs b/crates/metric/src/lib.rs index 8fd0f307..dc436245 100644 --- a/crates/metric/src/lib.rs +++ b/crates/metric/src/lib.rs @@ -8,7 +8,7 @@ pub static HTTP_REQUEST_TOTAL: Lazy = Lazy::new(|| { "http_requests_total", "Total number of HTTP requests received", ) - .namespace(cds_env::get_env().metric.namespace.clone()); + .namespace(cds_config::get_config().metric.namespace.clone()); let counter = IntCounterVec::new(opts, &["method", "path"]).expect("metric can be created"); METRICS_REGISTRY .register(Box::new(counter.clone())) @@ -18,7 +18,7 @@ pub static HTTP_REQUEST_TOTAL: Lazy = Lazy::new(|| { pub static MEMORY_USAGE: Lazy = Lazy::new(|| { let opts = Opts::new("memory_usage_bytes", "Memory usage in bytes") - .namespace(cds_env::get_env().metric.namespace.clone()); + .namespace(cds_config::get_config().metric.namespace.clone()); let gauge = IntGauge::with_opts(opts).expect("metric can be created"); METRICS_REGISTRY.register(Box::new(gauge.clone())).unwrap(); gauge @@ -26,7 +26,7 @@ pub static MEMORY_USAGE: Lazy = Lazy::new(|| { pub static MEMORY_USAGE_RATIO: Lazy = Lazy::new(|| { let opts = Opts::new("memory_usage_ratio", "Memory usage ratio") - .namespace(cds_env::get_env().metric.namespace.clone()); + .namespace(cds_config::get_config().metric.namespace.clone()); let gauge = Gauge::with_opts(opts).expect("metric can be created"); METRICS_REGISTRY.register(Box::new(gauge.clone())).unwrap(); gauge @@ -34,7 +34,7 @@ pub static MEMORY_USAGE_RATIO: Lazy = Lazy::new(|| { pub static CPU_USAGE: Lazy = Lazy::new(|| { let opts = Opts::new("cpu_usage_percent", "CPU usage percentage") - .namespace(cds_env::get_env().metric.namespace.clone()); + .namespace(cds_config::get_config().metric.namespace.clone()); let gauge = IntGauge::with_opts(opts).expect("metric can be created"); METRICS_REGISTRY.register(Box::new(gauge.clone())).unwrap(); gauge diff --git a/crates/queue/Cargo.toml b/crates/queue/Cargo.toml index 2dfe6be8..d43e7879 100644 --- a/crates/queue/Cargo.toml +++ b/crates/queue/Cargo.toml @@ -6,7 +6,7 @@ publish = false resolver = "2" [dependencies] -cds-env = { workspace = true } +cds-config = { workspace = true } tracing = { workspace = true } serde = { workspace = true } diff --git a/crates/queue/src/lib.rs b/crates/queue/src/lib.rs index 092d2267..30c20977 100644 --- a/crates/queue/src/lib.rs +++ b/crates/queue/src/lib.rs @@ -57,16 +57,16 @@ pub async fn subscribe( pub async fn init() { let client = async_nats::ConnectOptions::new() - .require_tls(cds_env::get_env().queue.tls) + .require_tls(cds_config::get_config().queue.tls) .user_and_password( - cds_env::get_env().queue.username.clone(), - cds_env::get_env().queue.password.clone(), + cds_config::get_config().queue.username.clone(), + cds_config::get_config().queue.password.clone(), ) - .token(cds_env::get_env().queue.token.clone()) + .token(cds_config::get_config().queue.token.clone()) .connect(format!( "{}:{}", - cds_env::get_env().queue.host, - cds_env::get_env().queue.port + cds_config::get_config().queue.host, + cds_config::get_config().queue.port )) .await .unwrap(); diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml index 85006fa1..e785a546 100644 --- a/crates/server/Cargo.toml +++ b/crates/server/Cargo.toml @@ -7,9 +7,8 @@ resolver = "2" [dependencies] cds-assets = { workspace = true } -cds-env = { workspace = true } -cds-db = { workspace = true } cds-config = { workspace = true } +cds-db = { workspace = true } cds-cluster = { workspace = true } cds-queue = { workspace = true } cds-web = { workspace = true } diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs index 3ee54c1d..40861368 100644 --- a/crates/server/src/main.rs +++ b/crates/server/src/main.rs @@ -26,21 +26,19 @@ async fn bootstrap() { .expect(""); logger::init().await; - cds_env::init().await; + cds_config::init().await; cds_queue::init().await; cds_cache::init().await; cds_db::init().await; migrator::run().await; - - cds_config::init().await; let _ = cds_cluster::init().await; cds_web::init().await; let addr = format!( "{}:{}", - cds_env::get_env().server.host, - cds_env::get_env().server.port + cds_config::get_config().server.host, + cds_config::get_config().server.port ); let listener = tokio::net::TcpListener::bind(&addr).await; diff --git a/crates/server/src/migrator.rs b/crates/server/src/migrator.rs index 3a735e12..9cc65c18 100644 --- a/crates/server/src/migrator.rs +++ b/crates/server/src/migrator.rs @@ -5,7 +5,7 @@ use argon2::{ use cds_db::{entity, get_db}; use sea_orm::{ ActiveModelTrait, ActiveValue::Set, ConnectionTrait, DbConn, EntityTrait, PaginatorTrait, - Schema, sqlx::types::uuid, + Schema, }; use tracing::{error, info}; @@ -32,7 +32,6 @@ where pub async fn run() { create_tables!( get_db(), - entity::config::Entity, entity::user::Entity, entity::team::Entity, entity::user_team::Entity, @@ -45,7 +44,6 @@ pub async fn run() { ); init_admin().await; - init_config().await; } pub async fn init_admin() { @@ -67,45 +65,3 @@ pub async fn init_admin() { info!("Admin user created successfully."); } } - -pub async fn init_config() { - let total = entity::config::Entity::find() - .count(get_db()) - .await - .unwrap(); - if total == 0 { - let config = entity::config::ActiveModel { - value: Set(serde_json::to_value(cds_config::Config { - auth: cds_config::auth::Config { - registration: cds_config::auth::registration::Config { - enabled: true, - captcha: false, - email: cds_config::auth::registration::email::Config { - enabled: false, - domains: vec![], - }, - }, - }, - site: cds_config::site::Config { - title: String::from("CdsCTF"), - description: String::from( - "Reality is an illusion, the universe is a hologram.", - ), - color: String::from("#0C4497"), - favicon: String::from(""), - }, - cluster: cds_config::cluster::Config { - entry: String::from("127.0.0.1"), - strategy: cds_config::cluster::strategy::Config { - parallel_limit: 0, - request_limit: 0, - }, - }, - }) - .unwrap()), - ..Default::default() - }; - config.insert(get_db()).await.unwrap(); - info!("Default configuration created successfully."); - } -} diff --git a/crates/web/Cargo.toml b/crates/web/Cargo.toml index 84f082a0..56372f0e 100644 --- a/crates/web/Cargo.toml +++ b/crates/web/Cargo.toml @@ -7,10 +7,9 @@ resolver = "2" [dependencies] cds-db = { workspace = true } -cds-config = { workspace = true } cds-cluster = { workspace = true } cds-cache = { workspace = true } -cds-env = { workspace = true } +cds-config = { workspace = true } cds-media = { workspace = true } cds-metric = { workspace = true } cds-queue = { workspace = true } diff --git a/crates/web/src/middleware/mod.rs b/crates/web/src/middleware/mod.rs index 7e33bc57..974f45ac 100644 --- a/crates/web/src/middleware/mod.rs +++ b/crates/web/src/middleware/mod.rs @@ -38,7 +38,8 @@ pub async fn auth(mut req: Request, next: Next) -> Result = None; diff --git a/crates/web/src/router/api/config/mod.rs b/crates/web/src/router/api/config/mod.rs index f99a9dfa..1e10ad58 100644 --- a/crates/web/src/router/api/config/mod.rs +++ b/crates/web/src/router/api/config/mod.rs @@ -1,82 +1,33 @@ use axum::{ Router, body::Body, - extract::Multipart, http::{Response, StatusCode}, response::{IntoResponse, Redirect}, }; -use cds_config::get_config; -use cds_db::{entity::user::Group, get_db}; -use sea_orm::{ActiveModelTrait, ActiveValue::Set}; +use sea_orm::ActiveModelTrait; use serde::{Deserialize, Serialize}; -use serde_json::json; -use crate::{ - extract::{Extension, Json, Query}, - traits::{Ext, WebError, WebResponse}, - util::handle_image_multipart, -}; +use crate::traits::{WebError, WebResponse}; pub fn router() -> Router { Router::new() - .route("/", axum::routing::get(get)) - .route("/", axum::routing::put(update)) + .route("/meta", axum::routing::get(get_meta)) .route("/icon", axum::routing::get(get_icon)) - .route("/icon", axum::routing::post(save_icon)) - .route("/icon", axum::routing::delete(delete_icon)) } #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct GetRequest { - pub is_detailed: Option, -} - -pub async fn get( - Extension(ext): Extension, Query(params): Query, -) -> Result, WebError> { - match params.is_detailed { - Some(true) => { - let operator = ext.operator.ok_or(WebError::Unauthorized(json!("")))?; - if operator.group != Group::Admin { - return Err(WebError::Forbidden(json!(""))); - } - - Ok(WebResponse { - code: StatusCode::OK.as_u16(), - data: Some(get_config().await), - ..WebResponse::default() - }) - } - _ => { - let config = get_config().await; - - Ok(WebResponse { - code: StatusCode::OK.as_u16(), - data: Some(config), - ..WebResponse::default() - }) - } - } +pub struct Meta { + pub title: String, + pub description: String, } -pub async fn update( - Extension(ext): Extension, Json(body): Json, -) -> Result, WebError> { - let operator = ext.operator.ok_or(WebError::Unauthorized(json!("")))?; - if operator.group != Group::Admin { - return Err(WebError::Forbidden(json!(""))); - } - - let config = cds_db::entity::config::ActiveModel { - id: Set(1), - value: Set(json!(body)), - ..Default::default() - }; - - config.update(get_db()).await?; - +pub async fn get_meta() -> Result, WebError> { Ok(WebResponse { code: StatusCode::OK.as_u16(), + data: Some(Meta { + title: cds_config::get_config().meta.title, + description: cds_config::get_config().meta.description, + }), ..WebResponse::default() }) } @@ -91,40 +42,3 @@ pub async fn get_icon() -> impl IntoResponse { } } } - -pub async fn save_icon( - Extension(ext): Extension, multipart: Multipart, -) -> Result, WebError> { - let operator = ext.operator.ok_or(WebError::Unauthorized(json!("")))?; - if operator.group != Group::Admin { - return Err(WebError::Forbidden(json!(""))); - } - let path = String::from("configs"); - let filename = String::from("icon.webp"); - let data = handle_image_multipart(multipart).await?; - cds_media::delete(path.clone(), filename.clone()).await?; - let data = cds_media::util::img_convert_to_webp(data).await?; - cds_media::save(path, filename, data) - .await - .map_err(|_| WebError::InternalServerError(json!("")))?; - - Ok(WebResponse { - code: StatusCode::OK.as_u16(), - ..WebResponse::default() - }) -} - -pub async fn delete_icon(Extension(ext): Extension) -> Result, WebError> { - let operator = ext.operator.ok_or(WebError::Unauthorized(json!("")))?; - if operator.group != Group::Admin { - return Err(WebError::Forbidden(json!(""))); - } - let path = String::from("configs"); - let filename = String::from("icon.webp"); - cds_media::delete(path.clone(), filename.clone()).await?; - - Ok(WebResponse { - code: StatusCode::OK.as_u16(), - ..WebResponse::default() - }) -} diff --git a/crates/web/src/router/api/user/mod.rs b/crates/web/src/router/api/user/mod.rs index a8c922bc..2ab93d18 100644 --- a/crates/web/src/router/api/user/mod.rs +++ b/crates/web/src/router/api/user/mod.rs @@ -270,8 +270,7 @@ pub async fn login(Json(mut body): Json) -> Result cds_env::auth::Env { - if let Some(jwt) = cds_cache::get::("jwt") +pub async fn get_jwt_config() -> cds_config::auth::Config { + if let Some(jwt) = cds_cache::get::("jwt") .await .unwrap() { return jwt; } - let mut jwt = cds_env::get_env().auth.clone(); + let mut jwt = cds_config::get_config().auth.clone(); let re = Regex::new(r"\[([Uu][Uu][Ii][Dd])]").unwrap(); jwt.secret = re .replace_all(&jwt.secret, Uuid::new_v4().simple().to_string())