diff --git a/config.example.toml b/config.example.toml
index 16a518f..d0a834d 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -13,8 +13,6 @@
append_path = "/"
# where can your server be accessible?
port = 8000
-# your realip header, if you're behind a reverse proxy
-realip_header = "X-Real-IP"
[accounts]
# allow new accounts to be created
diff --git a/readme.md b/readme.md
index a5ec559..e316e8f 100644
--- a/readme.md
+++ b/readme.md
@@ -33,8 +33,9 @@ i've run out of ideas.
## todo
- User icons in account management pages
+- Flesh out account management page
- Account settings page
-- Better web design
+- Better web design (make formatting more consistant)
- Use chrono for dates in database, add recent
- 2.2's friends only unlisted
- Dailies, weeklies, events(?)
@@ -43,4 +44,8 @@ i've run out of ideas.
- Cache authentication
- Panic less
- Make a proper rank system (reuploading, uploading music, rating, etc.)
-- Swap to a better web framework
\ No newline at end of file
+- Use serde to make the forms whateverCaseThisIs rather than breaking our lint convention
+- Swap to `sqlx` im gonna be honest `diesel` is pretty shit.
+- Swap to `sqlite` from `postgres`. Postgres feels too clunky and it just solos honestly
+- Add back `realip` header support
+- Add configurable form limits
\ No newline at end of file
diff --git a/src/config.rs b/src/config.rs
index 4b73286..df09291 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,52 +1,27 @@
-use serde::Deserialize;
-
use std::fs;
use std::sync::LazyLock;
-#[derive(Deserialize)]
-pub struct Config {
- pub general: ConfigGeneral,
- pub accounts: ConfigAccounts,
- pub db: ConfigDB,
- pub levels: ConfigLevels
-}
+use toml::Table;
-#[derive(Deserialize)]
-pub struct ConfigGeneral {
- pub append_path: String,
- pub port: u16,
- pub realip_header: String
-}
+pub static CONFIG: LazyLock
= LazyLock::new(|| {
+ let toml_str = fs::read_to_string("config.toml").expect("error finding toml config");
+ let config: Table = toml::from_str(toml_str.as_str()).expect("error parsing toml config");
-#[derive(Deserialize)]
-pub struct ConfigAccounts {
- pub allow_registration: bool
-}
-
-#[derive(Deserialize)]
-pub struct ConfigDB {
- pub data_folder: String
-}
-
-#[derive(Deserialize)]
-pub struct ConfigLevels {
- pub max_objects: i32,
- pub blocklist: Vec,
- pub reupload: bool
-}
-
-impl Config {
- pub fn load_from_file(file_path: &str) -> Self {
- let toml_str = fs::read_to_string(file_path).expect("Error finding toml config:");
- let config: Config = toml::from_str(toml_str.as_str()).expect("Error parsing toml config:");
-
- return config;
- }
-}
-
-pub static CONFIG: LazyLock = LazyLock::new(|| {
- let config = Config::load_from_file("config.toml");
-
return config;
-});
\ No newline at end of file
+});
+
+pub fn config_get(key: &str) -> Option<&toml::Value> {
+ let this = &CONFIG;
+ let mut current = this.get(key)?;
+ for val in key.split(".").skip(1) {
+ current = current.as_table()?.get(val)?;
+ }
+ Some(current)
+}
+
+pub fn config_get_with_default>(key: &str, default: T) -> T {
+ config_get(key)
+ .and_then(|v| v.clone().try_into().ok())
+ .unwrap_or(default)
+}
\ No newline at end of file
diff --git a/src/endpoints/accounts/register_account.rs b/src/endpoints/accounts/register_account.rs
index de04a33..86776fd 100644
--- a/src/endpoints/accounts/register_account.rs
+++ b/src/endpoints/accounts/register_account.rs
@@ -7,7 +7,7 @@ use diesel::result::Error;
use password_auth::generate_hash;
-use crate::CONFIG;
+use crate::config;
use crate::helpers;
use crate::db;
@@ -22,7 +22,7 @@ pub struct FormRegisterAccount {
pub fn register_account(input: Form) -> status::Custom<&'static str> {
let connection = &mut db::establish_connection_pg();
- if CONFIG.accounts.allow_registration == false {
+ if config::config_get_with_default("accounts.allow_registration", true) == false {
return status::Custom(Status::Ok, "-1")
}
@@ -55,7 +55,7 @@ pub fn register_account(input: Form) -> status::Custom<&'st
use crate::schema::accounts::dsl::*;
let account_name_usage = accounts.filter(username.eq(input.userName.clone())).count().get_result::(connection) as Result;
- let account_name_used = account_name_usage.expect("Fatal database name query error") != 0;
+ let account_name_used = account_name_usage.expect("database name query error") != 0;
if account_name_used {
return status::Custom(Status::Ok, "-2")
}
@@ -70,7 +70,7 @@ pub fn register_account(input: Form) -> status::Custom<&'st
inserted_account = diesel::insert_into(accounts)
.values(&new_account)
.get_result::(connection)
- .expect("Fatal error saving the new account");
+ .expect("error saving the new account");
}
// user management
@@ -88,7 +88,7 @@ pub fn register_account(input: Form) -> status::Custom<&'st
diesel::insert_into(users)
.values(&new_user)
.get_result::(connection)
- .expect("Fatal error saving the new user");
+ .expect("error saving the new user");
}
return status::Custom(Status::Ok, "1")
diff --git a/src/endpoints/levels/download_level.rs b/src/endpoints/levels/download_level.rs
index 44d02a3..1949611 100644
--- a/src/endpoints/levels/download_level.rs
+++ b/src/endpoints/levels/download_level.rs
@@ -13,6 +13,7 @@ use std::fs;
use std::io::prelude::*;
use crate::helpers;
+use crate::config;
use crate::db;
#[derive(FromForm)]
@@ -98,7 +99,7 @@ pub fn download_level(input: Form) -> status::Custom<&'static
xor_pass = level.password.clone().unwrap_or(String::from("0"));
}
- let compressed_level_data = fs::read(format!("{}/{}/{}.lvl", crate::CONFIG.db.data_folder, "levels", level.id)).expect("couldnt read level file");
+ let compressed_level_data = fs::read(format!("{}/{}/{}.lvl", config::config_get_with_default("db.data_folder", "data"), "levels", level.id)).expect("couldnt read level file");
let uncompressed_level_data = String::from_utf8(if compressed_level_data.starts_with(&[0x1F, 0x8B]) {
// gzip!!
diff --git a/src/endpoints/levels/upload_level.rs b/src/endpoints/levels/upload_level.rs
index ece7568..a67206e 100644
--- a/src/endpoints/levels/upload_level.rs
+++ b/src/endpoints/levels/upload_level.rs
@@ -8,7 +8,7 @@ use base64::{Engine as _, engine::general_purpose};
use std::fs;
-use crate::config::CONFIG;
+use crate::config;
use crate::helpers;
use crate::db;
@@ -98,12 +98,12 @@ pub fn upload_level(input: Form) -> status::Custom<&'static str
}
// too many objects
- if objects_val > CONFIG.levels.max_objects as usize {
+ if config::config_get_with_default("levels.max_objects", 0) != 0 && objects_val > config::config_get_with_default("levels.max_objects", 0) {
return status::Custom(Status::Ok, "-1")
}
-
+
// forbidden object checking
- if let Some(_forbidden_object) = level_objects.iter().find(|obj| crate::CONFIG.levels.blocklist.contains(&obj.id())) {
+ if let Some(_forbidden_object) = level_objects.iter().find(|obj| config::config_get_with_default("levels.blocklist", Vec::new() as Vec).contains(&obj.id())) {
return status::Custom(Status::Ok, "-1")
}
@@ -158,7 +158,7 @@ pub fn upload_level(input: Form) -> status::Custom<&'static str
.get_result::(connection)
.expect("failed to update level");
- fs::write(format!("{}/levels/{}.lvl", crate::CONFIG.db.data_folder, updated_level.id), general_purpose::URL_SAFE.decode(input.levelString.clone()).expect("user provided invalid level string")).expect("couldnt write level to file");
+ fs::write(format!("{}/levels/{}.lvl", config::config_get_with_default("db.data_folder", "data"), updated_level.id), general_purpose::URL_SAFE.decode(input.levelString.clone()).expect("user provided invalid level string")).expect("couldnt write level to file");
return status::Custom(Status::Ok, Box::leak(input.levelID.to_string().into_boxed_str()))
} else {
@@ -194,7 +194,7 @@ pub fn upload_level(input: Form) -> status::Custom<&'static str
.get_result::(connection)
.expect("failed to insert level");
- fs::write(format!("{}/levels/{}.lvl", crate::CONFIG.db.data_folder, inserted_level.id), general_purpose::URL_SAFE.decode(input.levelString.clone()).expect("user provided invalid level string")).expect("couldnt write level to file");
+ fs::write(format!("{}/levels/{}.lvl", config::config_get_with_default("db.data_folder", "data"), inserted_level.id), general_purpose::URL_SAFE.decode(input.levelString.clone()).expect("user provided invalid level string")).expect("couldnt write level to file");
return status::Custom(Status::Ok, "1")
}
diff --git a/src/main.rs b/src/main.rs
index dcf71dc..58456e6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -38,15 +38,14 @@ fn rocket() -> _ {
crate::helpers::reupload::init();
// data directories
- // this is a bit scuffed
- fs::create_dir_all(&CONFIG.db.data_folder).expect("failed to create data directory!");
- fs::create_dir_all(format!("{}/levels", &CONFIG.db.data_folder)).expect("failed to create data directory for levels");
+ // unhardcore this maybe?
+ fs::create_dir_all(config::config_get_with_default("db.data_folder", "data")).expect("failed to create data directory!");
+ fs::create_dir_all(format!("{}/levels", config::config_get_with_default("db.data_folder", "data"))).expect("failed to create data directory for levels");
rocket::build()
// conf
.configure(rocket::Config::figment()
- .merge(("port", CONFIG.general.port))
- .merge(("ip_header", CONFIG.general.realip_header.as_str()))
+ .merge(("port", config::config_get_with_default("general.port", 8000)))
.merge(("limits", Limits::new().limit("forms", 10.megabytes()))))
// actual website
.mount("/", routes![
@@ -67,7 +66,7 @@ fn rocket() -> _ {
files
])
// https://www.youtube.com/watch?v=_pLrtsf5yfE
- .mount(CONFIG.general.append_path.as_str(), routes![
+ .mount(config::config_get_with_default("general.append_path", "/"), routes![
endpoints::accounts::login_account::login_account,
endpoints::accounts::register_account::register_account,
endpoints::accounts::update_account_settings::update_account_settings,
diff --git a/src/template_endpoints/reupload.rs b/src/template_endpoints/reupload.rs
index 36fa2f6..9ab1e2e 100644
--- a/src/template_endpoints/reupload.rs
+++ b/src/template_endpoints/reupload.rs
@@ -16,6 +16,7 @@ use diesel::prelude::*;
use crate::helpers;
use crate::db;
+use crate::config;
#[derive(Deserialize)]
struct LevelResults {
@@ -39,7 +40,7 @@ pub struct FormReupload {
pub async fn post_reupload(input: Form) -> Template {
let connection = &mut db::establish_connection_pg();
- let disabled = !crate::CONFIG.levels.reupload;
+ let disabled = !config::config_get_with_default("levels.reupload", true);
if !disabled {
let remote_level_id = input.level_id;
@@ -105,7 +106,7 @@ pub async fn post_reupload(input: Form) -> Template {
.get_result::(connection)
.expect("failed to insert level");
- fs::write(format!("{}/levels/{}.lvl", crate::CONFIG.db.data_folder, inserted_level.id), general_purpose::URL_SAFE.decode(level_data.get("k4").expect("no level data?!").as_bytes()).expect("user provided invalid level string")).expect("couldnt write level to file");
+ fs::write(format!("{}/levels/{}.lvl", config::config_get_with_default("db.data_folder", "data"), inserted_level.id), general_purpose::URL_SAFE.decode(level_data.get("k4").expect("no level data?!").as_bytes()).expect("user provided invalid level string")).expect("couldnt write level to file");
return Template::render("reupload", context! {
level_id: inserted_level.id
@@ -119,7 +120,7 @@ pub async fn post_reupload(input: Form) -> Template {
#[get("/tools/reupload")]
pub fn get_reupload() -> Template {
- let disabled = !crate::CONFIG.levels.reupload;
+ let disabled = !config::config_get_with_default("levels.reupload", true);
Template::render("reupload", context! {
disabled: disabled