From 5e2aeaf19ec329ad6bf76d382cd01ce67675b774 Mon Sep 17 00:00:00 2001 From: JP Stringham Date: Fri, 6 Mar 2026 17:57:25 -0500 Subject: [PATCH] Lots of functionality, including command history --- Cargo.lock | 136 +++++++++++++++++++++++++++++++ Cargo.toml | 1 + createuserregtoken.json | 5 ++ src/app/admin.rs | 2 + src/app/admin/user_reg_tokens.rs | 70 ++++++++++++++++ src/main.rs | 45 +++++++--- 6 files changed, 247 insertions(+), 12 deletions(-) create mode 100644 createuserregtoken.json create mode 100644 src/app/admin/user_reg_tokens.rs diff --git a/Cargo.lock b/Cargo.lock index eea6929..b2a3877 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,6 +174,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" +[[package]] +name = "clipboard-win" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" +dependencies = [ + "error-code", +] + [[package]] name = "cmake" version = "0.1.57" @@ -260,6 +269,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + [[package]] name = "enum-iterator" version = "2.3.0" @@ -286,6 +301,33 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "error-code" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" + +[[package]] +name = "fd-lock" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" +dependencies = [ + "cfg-if", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "find-msvc-tools" version = "0.1.9" @@ -420,6 +462,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "http" version = "1.4.0" @@ -710,6 +761,12 @@ version = "0.2.182" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + [[package]] name = "litemap" version = "0.8.1" @@ -736,6 +793,7 @@ dependencies = [ "colored", "enum-iterator", "reqwest", + "rustyline", "serde", "serde_json", "shlex", @@ -771,6 +829,27 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "objc2" version = "0.6.4" @@ -930,6 +1009,16 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + [[package]] name = "rand" version = "0.9.2" @@ -1021,6 +1110,19 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + [[package]] name = "rustls" version = "0.23.37" @@ -1102,6 +1204,28 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "rustyline" +version = "17.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e902948a25149d50edc1a8e0141aad50f54e22ba83ff988cf8f7c9ef07f50564" +dependencies = [ + "bitflags", + "cfg-if", + "clipboard-win", + "fd-lock", + "home", + "libc", + "log", + "memchr", + "nix", + "radix_trie", + "unicode-segmentation", + "unicode-width", + "utf8parse", + "windows-sys 0.60.2", +] + [[package]] name = "ryu" version = "1.0.23" @@ -1480,6 +1604,18 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index a7b82de..e04fac6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ clap = { version = "4.5.60", features = ["derive"] } colored = "3.1.1" enum-iterator = "2.3.0" reqwest = { version = "0.13.2", features = ["blocking", "form"] } +rustyline = "17.0.2" serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0.149" shlex = "1.3.0" diff --git a/createuserregtoken.json b/createuserregtoken.json new file mode 100644 index 0000000..2762d08 --- /dev/null +++ b/createuserregtoken.json @@ -0,0 +1,5 @@ +{ + "token": "string", + "usage_limit": 0, + "expires_at": "2026-03-06T22:36:06.337Z" +} \ No newline at end of file diff --git a/src/app/admin.rs b/src/app/admin.rs index e06cf4a..29d283e 100644 --- a/src/app/admin.rs +++ b/src/app/admin.rs @@ -1,4 +1,6 @@ pub mod server; +pub mod user_reg_tokens; + const USERS_ENDPT: &str = "/api/admin/v1/users"; const OAUTH_LINKS_ENDPT: &str = "/api/admin/v1/upstream-oauth-links"; diff --git a/src/app/admin/user_reg_tokens.rs b/src/app/admin/user_reg_tokens.rs new file mode 100644 index 0000000..901dde5 --- /dev/null +++ b/src/app/admin/user_reg_tokens.rs @@ -0,0 +1,70 @@ +const USER_REG_TOKENS_ENDPT: &str = "/api/admin/v1/user-registration-tokens"; + +use clap::Subcommand; + +use crate::json_types::prettify_json_str; + +use super::super::App; + +impl App { + pub fn list_user_reg_tokens(&self) { + let auth_token = self + .auth_token + .as_ref() + .expect("Need auth token to perform this action"); + + let url = format!("{}{USER_REG_TOKENS_ENDPT}", self.mas_base_url); + + let client = reqwest::blocking::Client::new(); + + let req = client + .get(url) + .header("Accept", "application/json") + .header( + "Authorization", + format!("Bearer {}", auth_token.access_token.clone()), + ) + .header("Content-Type", "application/json"); + + // println!("Req {:?}", req); + + let res = req.send().unwrap(); + + let json = prettify_json_str(res.text().unwrap().as_str()).unwrap(); + println!("{}", json); + } + + pub fn create_user_reg_token(&self) { + let auth_token = self + .auth_token + .as_ref() + .expect("Need auth token to perform this action"); + + let url = format!("{}{USER_REG_TOKENS_ENDPT}", self.mas_base_url); + + let client = reqwest::blocking::Client::new(); + + let req = client + .post(url) + .header("Accept", "application/json") + .header( + "Authorization", + format!("Bearer {}", auth_token.access_token.clone()), + ) + .header("Content-Type", "application/json") + .body("{}"); + + // println!("Req {:?}", req); + + let res = req.send().unwrap(); + + let json = prettify_json_str(res.text().unwrap().as_str()).unwrap(); + println!("{}", json); + } +} + +#[derive(Debug, Subcommand, PartialEq, Eq)] +pub enum UserRegTokensCommands { + List, + Create, +} diff --git a/src/main.rs b/src/main.rs index 24c3e5e..6d7f002 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,8 +14,13 @@ use std::io::Write; use clap::{CommandFactory, Parser, Subcommand}; use colored::{ColoredString, Colorize}; +use rustyline::{DefaultEditor, error::ReadlineError}; -use crate::app::{App, admin::server::ServerCommands, setup::SetupCommands}; +use crate::app::{ + App, + admin::{server::ServerCommands, user_reg_tokens::UserRegTokensCommands}, + setup::SetupCommands, +}; // google oauth // 754241279547-kk48of2t6eu5vol85hn6op3ofpp3em76.apps.googleusercontent.com @@ -40,10 +45,23 @@ fn main() { print_menu(); + let mut rl = DefaultEditor::new().unwrap(); + loop { - let input = readline().unwrap(); + let input = match rl.readline("> ") { + Ok(line) => line, + Err(ReadlineError::Interrupted) => { + println!("Goodbye."); + break; + } + _ => { + continue; + } + }; let input = input.trim(); + rl.add_history_entry(input).unwrap(); + if input.is_empty() { continue; } @@ -87,6 +105,10 @@ fn main() { ServerCommands::ShowSiteConfig => app.show_site_config(), ServerCommands::ShowVersion => app.show_version(), }, + Commands::UserRegistrationTokens(sub) => match sub.command { + UserRegTokensCommands::List => app.list_user_reg_tokens(), + UserRegTokensCommands::Create => app.create_user_reg_token(), + }, Commands::ShowOauthLinks => app.show_oauth_links(), } } @@ -103,16 +125,6 @@ fn print_menu() { cli.print_long_help().unwrap(); } -fn readline() -> Result { - write!(std::io::stdout(), "> ").map_err(|e| e.to_string())?; - std::io::stdout().flush().map_err(|e| e.to_string())?; - let mut buffer = String::new(); - std::io::stdin() - .read_line(&mut buffer) - .map_err(|e| e.to_string())?; - Ok(buffer) -} - #[derive(Debug, clap::Parser)] #[command(multicall = true)] struct Cli { @@ -128,6 +140,9 @@ enum Commands { #[command(subcommand_help_heading = "Get site config and version")] #[command(arg_required_else_help = true)] Server(ServerCommandArgs), + #[command(subcommand_help_heading = "Manage user registration tokens")] + #[command(arg_required_else_help = true)] + UserRegistrationTokens(UserRegTokensArgs), ShowOauthLinks, } @@ -143,6 +158,12 @@ struct ServerCommandArgs { command: ServerCommands, } +#[derive(Debug, Parser)] +struct UserRegTokensArgs { + #[command(subcommand)] + command: UserRegTokensCommands, +} + fn quick_format_bool(b: bool) -> ColoredString { match b { true => "true".bright_green(),