Skip to content

Commit

Permalink
wip: merge repository into model
Browse files Browse the repository at this point in the history
  • Loading branch information
ElaBosak233 committed Jul 30, 2024
1 parent e2ce4bc commit 8ec0047
Show file tree
Hide file tree
Showing 68 changed files with 1,621 additions and 948 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ tower-http = { version = "0.5", features = ["cors", "fs", "trace"] }
serde = { version = "1.0", features = ["derive"] }
tracing = { version = "0.1" }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tracing-appender = "0.2"
uuid = { version = "1.8", features = ["v4", "fast-rng", "macro-diagnostics"] }
sea-orm = { version = "0.12", features = [
"sqlx-mysql",
Expand Down Expand Up @@ -56,7 +57,10 @@ wsrx = { version = "0.2", features = ["server"] }
serde_yaml = "0.9.34"
kube = { version = "0.93", features = ["runtime", "derive"] }
k8s-openapi = { version = "0.22", features = ["latest"] }
reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false }
reqwest = { version = "0.12", features = [
"json",
"rustls-tls",
], default-features = false }
async-trait = { version = "0.1" }
ring = { version = "0.17" }
rustls = { version = "0.23", features = ["ring"] }
Expand Down
2 changes: 1 addition & 1 deletion assets/banner.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@

Commit: {{commit}}
Build At: {{build_at}}
GitHub: https://github.com/elabosak233/cloudsdale
GitHub: https://github.com/elabosak233/cloudsdale
7 changes: 6 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,10 @@ fn main() {
.trim()
);

println!("cargo:rustc-env=BUILD_AT={}", chrono::Utc::now().format("%Y-%m-%d %H:%M:%S UTC").to_string());
println!(
"cargo:rustc-env=BUILD_AT={}",
chrono::Utc::now()
.format("%Y-%m-%d %H:%M:%S UTC")
.to_string()
);
}
4 changes: 2 additions & 2 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
merge_derives = true
fn_params_layout = "Compressed"
max_width = 160
max_width = 100
tab_spaces = 4
reorder_imports = true

Expand All @@ -9,4 +9,4 @@ reorder_imports = true
# condense_wildcard_suffixes = true
# imports_granularity = "Crate"
# brace_style = "PreferSameLine"
# group_imports = "StdExternalCrate"
# group_imports = "StdExternalCrate"
19 changes: 16 additions & 3 deletions src/captcha/recaptcha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,16 @@ struct RecaptchaRequest {
impl ICaptcha for Recaptcha {
fn new() -> Self {
return Recaptcha {
url: crate::config::get_app_config().captcha.recaptcha.url.clone(),
secret_key: crate::config::get_app_config().captcha.recaptcha.secret_key.clone(),
url: crate::config::get_app_config()
.captcha
.recaptcha
.url
.clone(),
secret_key: crate::config::get_app_config()
.captcha
.recaptcha
.secret_key
.clone(),
threshold: crate::config::get_app_config().captcha.recaptcha.threshold,
};
}
Expand All @@ -36,7 +44,12 @@ impl ICaptcha for Recaptcha {
};

let client = Client::new();
let resp = client.post(&self.url).json(&request_body).send().await.unwrap();
let resp = client
.post(&self.url)
.json(&request_body)
.send()
.await
.unwrap();

let response: serde_json::Value = resp.json().await.unwrap();

Expand Down
4 changes: 3 additions & 1 deletion src/captcha/traits.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
pub trait ICaptcha {
fn new() -> Self;
fn verify(&self, token: String, client_ip: String) -> impl std::future::Future<Output = bool> + Send;
fn verify(
&self, token: String, client_ip: String,
) -> impl std::future::Future<Output = bool> + Send;
}
19 changes: 16 additions & 3 deletions src/captcha/turnstile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,16 @@ struct TurnstileRequest {
impl ICaptcha for Turnstile {
fn new() -> Self {
return Turnstile {
url: crate::config::get_app_config().captcha.turnstile.url.clone(),
secret_key: crate::config::get_app_config().captcha.turnstile.secret_key.clone(),
url: crate::config::get_app_config()
.captcha
.turnstile
.url
.clone(),
secret_key: crate::config::get_app_config()
.captcha
.turnstile
.secret_key
.clone(),
};
}

Expand All @@ -34,7 +42,12 @@ impl ICaptcha for Turnstile {
};

let client = Client::new();
let resp = client.post(&self.url).json(&request_body).send().await.unwrap();
let resp = client
.post(&self.url)
.json(&request_body)
.send()
.await
.unwrap();

let response: serde_json::Value = resp.json().await.unwrap();

Expand Down
4 changes: 3 additions & 1 deletion src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ pub async fn init() {
let target_path = Path::new("application.yml");
if target_path.exists() {
let content = fs::read_to_string("application.yml").await.unwrap();
APP_CONFIG.set(serde_yaml::from_str(&content).unwrap()).unwrap();
APP_CONFIG
.set(serde_yaml::from_str(&content).unwrap())
.unwrap();
} else {
error!("Configuration application.yml not found.");
process::exit(1);
Expand Down
46 changes: 35 additions & 11 deletions src/container/docker.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use super::traits::Container;
use crate::{database::get_db, repository};
use crate::{database::get_db, model::pod};
use async_trait::async_trait;
use bollard::{
container::{Config, CreateContainerOptions, StartContainerOptions},
secret::{ContainerCreateResponse, HostConfig, PortBinding},
Docker as DockerClient,
};
use core::time;
use sea_orm::EntityTrait;
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
use std::{collections::HashMap, env, error::Error, process, sync::OnceLock};
use tracing::{error, info};

Expand All @@ -22,11 +22,22 @@ async fn daemon() {
tokio::spawn(async {
let interval = time::Duration::from_secs(10);
loop {
let (pods, _) = repository::pod::find(None, None, None, None, None, None, Some(false)).await.unwrap();
let pods = pod::Entity::find()
.filter(pod::Column::RemovedAt.lte(chrono::Utc::now().timestamp()))
.all(&get_db().await)
.await
.unwrap();
for pod in pods {
let _ = get_docker_client().stop_container(pod.name.clone().as_str(), None).await;
let _ = get_docker_client().remove_container(pod.name.clone().as_str(), None).await;
crate::model::pod::Entity::delete_by_id(pod.id).exec(&get_db().await).await.unwrap();
let _ = get_docker_client()
.stop_container(pod.name.clone().as_str(), None)
.await;
let _ = get_docker_client()
.remove_container(pod.name.clone().as_str(), None)
.await;
crate::model::pod::Entity::delete_by_id(pod.id)
.exec(&get_db().await)
.await
.unwrap();
info!("Cleaned up expired container: {0}", pod.name);
}
tokio::time::sleep(interval).await;
Expand Down Expand Up @@ -63,7 +74,8 @@ impl Container for Docker {
}

async fn create(
&self, name: String, challenge: crate::model::challenge::Model, injected_flag: crate::model::challenge::Flag,
&self, name: String, challenge: crate::model::challenge::Model,
injected_flag: crate::model::challenge::Flag,
) -> Result<Vec<crate::model::pod::Nat>, Box<dyn Error>> {
let port_bindings: HashMap<String, Option<Vec<PortBinding>>> = challenge
.ports
Expand All @@ -79,9 +91,17 @@ impl Container for Docker {
})
.collect();

let mut env_bindings: Vec<String> = challenge.envs.into_iter().map(|env| format!("{}:{}", env.key, env.value)).collect();
let mut env_bindings: Vec<String> = challenge
.envs
.into_iter()
.map(|env| format!("{}:{}", env.key, env.value))
.collect();

env_bindings.push(format!("{}:{}", injected_flag.env.unwrap_or("FLAG".to_string()), injected_flag.value));
env_bindings.push(format!(
"{}:{}",
injected_flag.env.unwrap_or("FLAG".to_string()),
injected_flag.value
));

let cfg = Config {
image: challenge.image_name.clone(),
Expand Down Expand Up @@ -132,7 +152,11 @@ impl Container for Docker {
}

async fn delete(&self, name: String) {
let _ = get_docker_client().stop_container(name.clone().as_str(), None).await;
let _ = get_docker_client().remove_container(name.clone().as_str(), None).await;
let _ = get_docker_client()
.stop_container(name.clone().as_str(), None)
.await;
let _ = get_docker_client()
.remove_container(name.clone().as_str(), None)
.await;
}
}
8 changes: 6 additions & 2 deletions src/container/k8s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ impl Container for K8s {
daemon().await;
}
Err(e) => {
error!("Failed to create Kubernetes client from custom config: {:?}", e);
error!(
"Failed to create Kubernetes client from custom config: {:?}",
e
);
process::exit(1);
}
},
Expand All @@ -71,7 +74,8 @@ impl Container for K8s {
}

async fn create(
&self, name: String, challenge: crate::model::challenge::Model, injected_flag: crate::model::challenge::Flag,
&self, name: String, challenge: crate::model::challenge::Model,
injected_flag: crate::model::challenge::Flag,
) -> Result<Vec<crate::model::pod::Nat>, Box<dyn Error>> {
let client = get_k8s_client().clone();
let pods: Api<Pod> = Api::namespaced(client, "default");
Expand Down
3 changes: 2 additions & 1 deletion src/container/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use std::error::Error;
pub trait Container: Send + Sync {
async fn init(&self);
async fn create(
&self, name: String, challenge: crate::model::challenge::Model, injected_flag: crate::model::challenge::Flag,
&self, name: String, challenge: crate::model::challenge::Model,
injected_flag: crate::model::challenge::Flag,
) -> Result<Vec<crate::model::pod::Nat>, Box<dyn Error>>;
async fn delete(&self, name: String);
}
27 changes: 22 additions & 5 deletions src/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ mod migration;

use bcrypt::{hash, DEFAULT_COST};
use once_cell::sync::Lazy;
use sea_orm::{ActiveModelTrait, ConnectOptions, Database, DatabaseConnection, EntityTrait, PaginatorTrait, Set};
use sea_orm::{
ActiveModelTrait, ConnectOptions, Database, DatabaseConnection, EntityTrait, PaginatorTrait,
Set,
};
use std::{process, time::Duration};
use tokio::sync::RwLock;
use tracing::{error, info};
Expand All @@ -12,8 +15,16 @@ use crate::config;
static DB: Lazy<RwLock<Option<DatabaseConnection>>> = Lazy::new(|| RwLock::new(None));

pub async fn init() {
let url = match crate::config::get_app_config().db.provider.to_lowercase().as_str() {
"sqlite" => format!("sqlite://{}?mode=rwc", crate::config::get_app_config().db.sqlite.path.clone()),
let url = match crate::config::get_app_config()
.db
.provider
.to_lowercase()
.as_str()
{
"sqlite" => format!(
"sqlite://{}?mode=rwc",
crate::config::get_app_config().db.sqlite.path.clone()
),
"mysql" => format!(
"mysql://{}:{}@{}:{}/{}",
crate::config::get_app_config().db.mysql.username,
Expand Down Expand Up @@ -63,7 +74,10 @@ pub async fn get_db() -> DatabaseConnection {
}

pub async fn init_admin() {
let total = crate::model::user::Entity::find().count(&get_db().await).await.unwrap();
let total = crate::model::user::Entity::find()
.count(&get_db().await)
.await
.unwrap();
if total == 0 {
let hashed_password = hash("123456".to_string(), DEFAULT_COST).unwrap();
let user = crate::model::user::ActiveModel {
Expand All @@ -80,7 +94,10 @@ pub async fn init_admin() {
}

pub async fn init_category() {
let total = crate::model::category::Entity::find().count(&get_db().await).await.unwrap();
let total = crate::model::category::Entity::find()
.count(&get_db().await)
.await
.unwrap();
if total == 0 {
let default_categories = vec![
crate::model::category::ActiveModel {
Expand Down
15 changes: 9 additions & 6 deletions src/logger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ pub fn init() {
.add_directive(Level::DEBUG.into())
.add_directive("docker_api=info".parse().unwrap());

let fmt_layer = tracing_subscriber::fmt::layer().with_target(false).with_filter(filter);
let fmt_layer = tracing_subscriber::fmt::layer()
.with_target(false)
.with_filter(filter);

// let file_layer = tracing_subscriber::fmt::layer()
// .with_ansi(false)
// .with_file(true)
// .with_line_number(true);
let file_appender = tracing_appender::rolling::daily("logs", "cds");
let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
let file_layer = tracing_subscriber::fmt::layer()
.with_ansi(false)
.with_writer(non_blocking);

tracing_subscriber::registry()
.with(fmt_layer)
// .with(file_layer)
.with(file_layer)
.init();

info!("Logger initialized successfully.");
Expand Down
20 changes: 16 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ mod logger;
mod media;
mod model;
mod proxy;
mod repository;
mod traits;
mod util;
mod web;
Expand All @@ -27,6 +26,10 @@ async fn main() {
.replace("{{build_at}}", env!("BUILD_AT"))
);

bootstrap().await;
}

async fn bootstrap() {
logger::init();
config::init().await;
database::init().await;
Expand All @@ -35,10 +38,19 @@ async fn main() {

info!("{:?}", util::jwt::get_secret().await);

let addr = format!("{}:{}", config::get_app_config().axum.host, config::get_app_config().axum.port);
let addr = format!(
"{}:{}",
config::get_app_config().axum.host,
config::get_app_config().axum.port
);
let listener = tokio::net::TcpListener::bind(&addr).await;

info!("Cloudsdale service has been started at {}. Enjoy your hacking challenges!", &addr);
info!(
"Cloudsdale service has been started at {}. Enjoy your hacking challenges!",
&addr
);

axum::serve(listener.unwrap(), web::get_app()).await.unwrap();
axum::serve(listener.unwrap(), web::get_app())
.await
.unwrap();
}
Loading

0 comments on commit 8ec0047

Please sign in to comment.