From 77ad5979634cdfc35e9d9ade5bdf4afa598ff52f Mon Sep 17 00:00:00 2001 From: reidlab Date: Sun, 27 Aug 2023 21:39:54 -0700 Subject: [PATCH 1/7] login endpoint is real!! --- readme.md | 10 ++--- src/endpoints/accounts.rs | 1 + src/endpoints/accounts/login_account.rs | 55 +++++++++++++++++++++++++ src/helpers.rs | 5 ++- src/helpers/accounts.rs | 17 ++++++++ src/main.rs | 1 + 6 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 src/endpoints/accounts/login_account.rs create mode 100644 src/helpers/accounts.rs diff --git a/readme.md b/readme.md index 767df3b..5072b14 100644 --- a/readme.md +++ b/readme.md @@ -1,10 +1,8 @@ # gdps-server -a [Geometry Dash](https://store.steampowered.com/app/322170/Geometry_Dash/) server reimplementation in [Rust](https://rust-lang.org), focusing on 1:1 recreations of vanilla GD features +a [Geometry Dash](https://store.steampowered.com/app/322170/Geometry_Dash/) server reimplementation in [Rust](https://rust-lang.org) -_this project is in early stages. it is NOT production ready._ - -_ONLY 2.2 is supported._ +this project is based off of (stolen from) the [crystal-gauntlet](https://git.oat.zone/oat/crystal-gauntlet) server ## why? @@ -28,7 +26,7 @@ _these features are implemented_ ### testing -- run `cargo run run` +- run `cargo run` ### building @@ -36,5 +34,5 @@ _these features are implemented_ ## todo -- add login endpoint....... NOW! +- cache hashed passwords - our passwords are a little insecure (`argon2(sha1(password + "mI29fmAnxgTs"))`) and there isnt anything we can do about this because gpj2 is forced like that!! thanks robtop!! (try and find a fix anyway lul) \ No newline at end of file diff --git a/src/endpoints/accounts.rs b/src/endpoints/accounts.rs index a335f67..fca82a6 100644 --- a/src/endpoints/accounts.rs +++ b/src/endpoints/accounts.rs @@ -1 +1,2 @@ +pub mod login_account; pub mod register_account; \ No newline at end of file diff --git a/src/endpoints/accounts/login_account.rs b/src/endpoints/accounts/login_account.rs new file mode 100644 index 0000000..c8e0f01 --- /dev/null +++ b/src/endpoints/accounts/login_account.rs @@ -0,0 +1,55 @@ +use password_auth::verify_password; +use rocket::form::Form; +use rocket::http::Status; +use rocket::response::status; + +use diesel::prelude::*; + +use crate::helpers; +use crate::db; + +#[derive(FromForm)] +pub struct FromLoginAccount { + userName: String, + password: String +} + +#[post("/memaddrefix/accounts/loginGJAccount.php", data = "")] +pub fn login_account(input: Form) -> status::Custom<&'static str> { + let connection = &mut db::establish_connection_pg(); + + if input.userName != helpers::clean::clean(input.userName.as_ref()) { + return status::Custom(Status::Ok, "-4") + } + + if input.password.len() < 6 { + return status::Custom(Status::Ok, "-8") + } + + if input.userName.len() < 3 { + return status::Custom(Status::Ok, "-9") + } + + { + use crate::schema::accounts::dsl::*; + + let account_id_gjp2_result = accounts + .select((id, gjp2)) + .filter(username.eq(input.userName.clone())) + .get_result::<(i32, String)>(connection); + + match account_id_gjp2_result { + Ok(account_id_gjp2) => { + let user_id = helpers::accounts::get_user_id_from_account_id(account_id_gjp2.0); + + match verify_password(helpers::gjp2::get_gjp2(input.password.clone()).as_bytes(), account_id_gjp2.1.as_str()) { + Ok(_) => return status::Custom(Status::Ok, + Box::leak(format!("{},{}", account_id_gjp2.0, user_id).into_boxed_str()) + ), + Err(_) => return status::Custom(Status::Ok, "-11") + }; + }, + Err(_) => return status::Custom(Status::Ok, "-1") + } + } +} \ No newline at end of file diff --git a/src/helpers.rs b/src/helpers.rs index 1302a7d..96f8dc1 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -1,2 +1,3 @@ -pub mod gjp2; -pub mod clean; \ No newline at end of file +pub mod accounts; +pub mod clean; +pub mod gjp2; \ No newline at end of file diff --git a/src/helpers/accounts.rs b/src/helpers/accounts.rs new file mode 100644 index 0000000..95d1230 --- /dev/null +++ b/src/helpers/accounts.rs @@ -0,0 +1,17 @@ +use diesel::prelude::*; + +use crate::db; + +pub fn get_user_id_from_account_id(ext_id: i32) -> i32 { + use crate::schema::users::dsl::*; + + let connection = &mut db::establish_connection_pg(); + + let user_id = users + .filter(udid.eq(ext_id.to_string()).or(account_id.eq(ext_id))) + .select(id) + .get_result::(connection) + .expect("No user associated with account?!?!?"); + + user_id +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index fead183..aca3f2b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,7 @@ fn rocket() -> _ { rocket::build().mount("/", routes![ index, + endpoints::accounts::login_account::login_account, endpoints::accounts::register_account::register_account ]) } \ No newline at end of file From fa1d23cb3e24214a122c215f9b268805f7ef63c8 Mon Sep 17 00:00:00 2001 From: reidlab Date: Mon, 28 Aug 2023 16:30:10 -0700 Subject: [PATCH 2/7] basic config system --- .gitignore | 4 ++- Cargo.lock | 1 + Cargo.toml | 1 + config.example.toml | 19 ++++++++++++ readme.md | 4 +-- src/config.rs | 34 ++++++++++++++++++++++ src/endpoints/accounts/register_account.rs | 5 ++++ src/main.rs | 20 ++++++++----- 8 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 config.example.toml create mode 100644 src/config.rs diff --git a/.gitignore b/.gitignore index 0b745e2..68b3e7e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /target -.env \ No newline at end of file + +.env +config.toml \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index e529cc9..a3d0865 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -413,6 +413,7 @@ dependencies = [ "rocket", "serde", "sha", + "toml", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 4c56fc5..7ca0d8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,4 @@ regex = "1.9.4" rocket = "=0.5.0-rc.3" serde = { version = "1.0.188", features = ["derive"] } sha = "1.0.3" +toml = "0.7.6" diff --git a/config.example.toml b/config.example.toml new file mode 100644 index 0000000..277ab04 --- /dev/null +++ b/config.example.toml @@ -0,0 +1,19 @@ +[general] +# if this path is encountered during path traversal, +# it will be removed. this is useful for instances +# where your absolute domain path is not long enough +# to replace boomlings.com, because you can then point +# it at a different, longer path to fill the gap +# +# example: +# boomlings.com/database/ +# example.com/aaaaaaaaaa/ +# ^^^^^^^^^^^ +# leaving blank will disable this +append_path = "" +# where can your server be accessible? +port = 8000 + +[accounts] +# allow new accounts to be created +allow_registration = true \ No newline at end of file diff --git a/readme.md b/readme.md index 5072b14..2fc460a 100644 --- a/readme.md +++ b/readme.md @@ -34,5 +34,5 @@ _these features are implemented_ ## todo -- cache hashed passwords -- our passwords are a little insecure (`argon2(sha1(password + "mI29fmAnxgTs"))`) and there isnt anything we can do about this because gpj2 is forced like that!! thanks robtop!! (try and find a fix anyway lul) \ No newline at end of file +- make the `append_path` option do something (atm doesnt work) +- move authorization logic to (./src/helpers/accounts.rs)[./src/helpers/accounts.rs] + cache authorization \ No newline at end of file diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..805c622 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,34 @@ +use serde::Deserialize; +use std::fs; +use std::sync::LazyLock; + +#[derive(Deserialize)] +pub struct Config { + pub general: ConfigGeneral, + pub accounts: ConfigAccounts +} + +#[derive(Deserialize)] +pub struct ConfigGeneral { + pub append_path: String, + pub port: u16 +} + +#[derive(Deserialize)] +pub struct ConfigAccounts { + pub allow_registration: 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"); + config +}); \ No newline at end of file diff --git a/src/endpoints/accounts/register_account.rs b/src/endpoints/accounts/register_account.rs index e4e5898..3623a54 100644 --- a/src/endpoints/accounts/register_account.rs +++ b/src/endpoints/accounts/register_account.rs @@ -5,6 +5,7 @@ use rocket::response::status; use diesel::prelude::*; use diesel::result::Error; +use crate::CONFIG; use crate::helpers; use crate::db; @@ -18,6 +19,10 @@ pub struct FormRegisterAccount { #[post("/memaddrefix/accounts/registerGJAccount.php", data = "")] pub fn register_account(input: Form) -> status::Custom<&'static str> { let connection = &mut db::establish_connection_pg(); + + if CONFIG.accounts.allow_registration == false { + return status::Custom(Status::Ok, "-1") + } if input.userName != helpers::clean::clean(input.userName.as_ref()) { return status::Custom(Status::Ok, "-4") diff --git a/src/main.rs b/src/main.rs index aca3f2b..013d063 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ #![feature(decl_macro)] +#![feature(lazy_cell)] #[macro_use] extern crate rocket; @@ -11,17 +12,22 @@ use helpers::*; mod endpoints; use endpoints::*; +mod config; +use config::*; + #[get("/")] fn index() -> String { - return String::from("index | coming soon to a localhost:8000 near u"); + return String::from("gdps-server | https://git.reidlab.online/reidlab/gdps-server"); } #[launch] fn rocket() -> _ { - rocket::build().mount("/", routes![ - index, - - endpoints::accounts::login_account::login_account, - endpoints::accounts::register_account::register_account - ]) + rocket::build() + .configure(rocket::Config::figment().merge(("port", CONFIG.general.port))) + .mount("/", routes![ + index, + + endpoints::accounts::login_account::login_account, + endpoints::accounts::register_account::register_account + ]) } \ No newline at end of file From 6bae7ef997421bb7666d30e6f1e11b5924dea751 Mon Sep 17 00:00:00 2001 From: reidlab Date: Mon, 28 Aug 2023 17:26:33 -0700 Subject: [PATCH 3/7] make append_path work, update todo --- config.example.toml | 4 ++-- readme.md | 4 ++-- src/endpoints/accounts/login_account.rs | 2 +- src/endpoints/accounts/register_account.rs | 2 +- src/main.rs | 5 +++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/config.example.toml b/config.example.toml index 277ab04..20e2599 100644 --- a/config.example.toml +++ b/config.example.toml @@ -9,8 +9,8 @@ # boomlings.com/database/ # example.com/aaaaaaaaaa/ # ^^^^^^^^^^^ -# leaving blank will disable this -append_path = "" +# leaving as "/" will disable this +append_path = "/" # where can your server be accessible? port = 8000 diff --git a/readme.md b/readme.md index 2fc460a..313aa4c 100644 --- a/readme.md +++ b/readme.md @@ -34,5 +34,5 @@ _these features are implemented_ ## todo -- make the `append_path` option do something (atm doesnt work) -- move authorization logic to (./src/helpers/accounts.rs)[./src/helpers/accounts.rs] + cache authorization \ No newline at end of file +- move authorization logic to (./src/helpers/accounts.rs)[./src/helpers/accounts.rs] +- make gjp2 authentication faster (bcrypt?) \ No newline at end of file diff --git a/src/endpoints/accounts/login_account.rs b/src/endpoints/accounts/login_account.rs index c8e0f01..8c52c0b 100644 --- a/src/endpoints/accounts/login_account.rs +++ b/src/endpoints/accounts/login_account.rs @@ -14,7 +14,7 @@ pub struct FromLoginAccount { password: String } -#[post("/memaddrefix/accounts/loginGJAccount.php", data = "")] +#[post("/accounts/loginGJAccount.php", data = "")] pub fn login_account(input: Form) -> status::Custom<&'static str> { let connection = &mut db::establish_connection_pg(); diff --git a/src/endpoints/accounts/register_account.rs b/src/endpoints/accounts/register_account.rs index 3623a54..583ca2a 100644 --- a/src/endpoints/accounts/register_account.rs +++ b/src/endpoints/accounts/register_account.rs @@ -16,7 +16,7 @@ pub struct FormRegisterAccount { email: String } -#[post("/memaddrefix/accounts/registerGJAccount.php", data = "")] +#[post("/accounts/registerGJAccount.php", data = "")] pub fn register_account(input: Form) -> status::Custom<&'static str> { let connection = &mut db::establish_connection_pg(); diff --git a/src/main.rs b/src/main.rs index 013d063..adcd126 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,8 +25,9 @@ fn rocket() -> _ { rocket::build() .configure(rocket::Config::figment().merge(("port", CONFIG.general.port))) .mount("/", routes![ - index, - + index, + ]) + .mount(CONFIG.general.append_path.as_str(), routes![ endpoints::accounts::login_account::login_account, endpoints::accounts::register_account::register_account ]) From 4358ec6483a8033c30efb67ec5813bf078b8a132 Mon Sep 17 00:00:00 2001 From: reidlab Date: Mon, 28 Aug 2023 17:31:25 -0700 Subject: [PATCH 4/7] add return statement --- src/helpers/accounts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/accounts.rs b/src/helpers/accounts.rs index 95d1230..2cd1b08 100644 --- a/src/helpers/accounts.rs +++ b/src/helpers/accounts.rs @@ -13,5 +13,5 @@ pub fn get_user_id_from_account_id(ext_id: i32) -> i32 { .get_result::(connection) .expect("No user associated with account?!?!?"); - user_id + return user_id } \ No newline at end of file From 80c884f48983104fcfd87566454d1bc042b0f518 Mon Sep 17 00:00:00 2001 From: reidlab Date: Tue, 29 Aug 2023 01:10:33 -0700 Subject: [PATCH 5/7] add some formatting shit --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/helpers.rs | 1 + src/helpers/format.rs | 16 ++++++++++++++++ 4 files changed, 25 insertions(+) create mode 100644 src/helpers/format.rs diff --git a/Cargo.lock b/Cargo.lock index a3d0865..aa19066 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -408,6 +408,7 @@ version = "0.0.0" dependencies = [ "diesel", "dotenvy", + "maplit", "password-auth", "regex", "rocket", @@ -655,6 +656,12 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + [[package]] name = "matchers" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 7ca0d8b..7b492b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] diesel = { version = "=2.1.0", features = ["postgres"] } dotenvy = "0.15.7" +maplit = "1.0.2" password-auth = "0.3.0" regex = "1.9.4" rocket = "=0.5.0-rc.3" diff --git a/src/helpers.rs b/src/helpers.rs index 96f8dc1..d4d9ee6 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -1,3 +1,4 @@ pub mod accounts; pub mod clean; +pub mod format; pub mod gjp2; \ No newline at end of file diff --git a/src/helpers/format.rs b/src/helpers/format.rs new file mode 100644 index 0000000..593fcf7 --- /dev/null +++ b/src/helpers/format.rs @@ -0,0 +1,16 @@ +use std::collections::HashMap; + +pub fn format(map: HashMap) -> String { + let mut result = String::new(); + + for (k, v) in map { + result.push_str(&format!("{}:{}", k, v.to_string())); + result.push(':'); + } + + if !result.is_empty() { + result.pop(); + } + + return result; +} \ No newline at end of file From 82aae1676630f75fef749315bd4150782c493150 Mon Sep 17 00:00:00 2001 From: reidlab Date: Tue, 29 Aug 2023 02:54:30 -0700 Subject: [PATCH 6/7] user search (i think) --- migrations/2023-08-27-090522_users/up.sql | 1 - src/db/models.rs | 1 - src/db/schema.rs | 1 - src/endpoints.rs | 3 +- src/endpoints/users.rs | 1 + src/endpoints/users/get_users.rs | 74 +++++++++++++++++++++++ src/main.rs | 5 +- 7 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 src/endpoints/users.rs create mode 100644 src/endpoints/users/get_users.rs diff --git a/migrations/2023-08-27-090522_users/up.sql b/migrations/2023-08-27-090522_users/up.sql index 026bb93..3230564 100644 --- a/migrations/2023-08-27-090522_users/up.sql +++ b/migrations/2023-08-27-090522_users/up.sql @@ -28,7 +28,6 @@ CREATE TABLE users ( wave INTEGER NOT NULL DEFAULT 0, robot INTEGER NOT NULL DEFAULT 0, spider INTEGER NOT NULL DEFAULT 0, - swing_copter INTEGER NOT NULL DEFAULT 0, explosion INTEGER NOT NULL DEFAULT 0, special INTEGER NOT NULL DEFAULT 0, glow INTEGER NOT NULL DEFAULT 0, diff --git a/src/db/models.rs b/src/db/models.rs index 239270a..304e140 100644 --- a/src/db/models.rs +++ b/src/db/models.rs @@ -62,7 +62,6 @@ pub struct User { pub wave: i32, pub robot: i32, pub spider: i32, - pub swing_copter: i32, pub explosion: i32, pub special: i32, pub glow: i32, diff --git a/src/db/schema.rs b/src/db/schema.rs index 232b06a..a56613f 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -47,7 +47,6 @@ diesel::table! { wave -> Int4, robot -> Int4, spider -> Int4, - swing_copter -> Int4, explosion -> Int4, special -> Int4, glow -> Int4, diff --git a/src/endpoints.rs b/src/endpoints.rs index 5184f86..5667352 100644 --- a/src/endpoints.rs +++ b/src/endpoints.rs @@ -1 +1,2 @@ -pub mod accounts; \ No newline at end of file +pub mod accounts; +pub mod users; \ No newline at end of file diff --git a/src/endpoints/users.rs b/src/endpoints/users.rs new file mode 100644 index 0000000..b244c93 --- /dev/null +++ b/src/endpoints/users.rs @@ -0,0 +1 @@ +pub mod get_users; \ No newline at end of file diff --git a/src/endpoints/users/get_users.rs b/src/endpoints/users/get_users.rs new file mode 100644 index 0000000..fe8530e --- /dev/null +++ b/src/endpoints/users/get_users.rs @@ -0,0 +1,74 @@ +use rocket::form::Form; +use rocket::http::Status; +use rocket::response::status; + +use diesel::prelude::*; +use diesel::result::Error; + +use crate::helpers; +use crate::db; + +#[derive(FromForm)] +pub struct FormGetUsers { + page: i64, + str: String +} + +#[post("/accounts/getGJUsers20.php", data = "")] +pub fn get_users(input: Form) -> status::Custom<&'static str> { + let connection = &mut db::establish_connection_pg(); + + // query users + use crate::schema::users::dsl::*; + use crate::models::User; + + let mut query = users.into_boxed(); + + match input.str.parse::() { + Ok(id_value) => query = query.filter(id.eq(id_value)), + Err(_) => query = query.filter(username.like(input.str.to_owned() + "%")) + }; + + let results = query + .order(stars.desc()) + .limit(10) + .offset(input.page * 10) + .get_result::(connection) + .expect("Fatal error loading users"); + + let response = helpers::format::format(hashmap! { + 1 => results.username, + 2 => results.id.to_string(), + 3 => results.stars.to_string(), + 4 => results.demons.to_string(), + 8 => results.creator_points.to_string(), + 9 => { + vec![ + results.cube, + results.ship, + results.ball, + results.ufo, + results.wave, + results.robot + ][results.icon_type as usize].to_string() + }, + 10 => results.color1.to_string(), + 11 => results.color2.to_string(), + 13 => results.coins.to_string(), + 14 => results.icon_type.to_string(), + 15 => results.special.to_string(), + 16 => { + match results.account_id { + Some(account_id_value) => account_id_value.to_string(), + None => match results.udid { + Some(udid_value) => udid_value.to_string(), + None => panic!("user has no account_id or udid?!?!?") + } + } + } + }); + + println!("{}", response); + + return status::Custom(Status::Ok, "1") +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index adcd126..bc0551e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ #![feature(decl_macro)] #![feature(lazy_cell)] +#[macro_use] extern crate maplit; #[macro_use] extern crate rocket; mod db; @@ -29,6 +30,8 @@ fn rocket() -> _ { ]) .mount(CONFIG.general.append_path.as_str(), routes![ endpoints::accounts::login_account::login_account, - endpoints::accounts::register_account::register_account + endpoints::accounts::register_account::register_account, + + endpoints::users::get_users::get_users ]) } \ No newline at end of file From 2d15914d1ad77eb918f4fde2d106a6892b103fc4 Mon Sep 17 00:00:00 2001 From: reidlab Date: Tue, 29 Aug 2023 03:00:06 -0700 Subject: [PATCH 7/7] update todo --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index 313aa4c..a6a70e9 100644 --- a/readme.md +++ b/readme.md @@ -34,5 +34,6 @@ _these features are implemented_ ## todo +- ___fix the fucking get users for usernames!!!!___ - move authorization logic to (./src/helpers/accounts.rs)[./src/helpers/accounts.rs] - make gjp2 authentication faster (bcrypt?) \ No newline at end of file