Lots of functionality, including command history

This commit is contained in:
JP Stringham
2026-03-06 17:57:25 -05:00
parent 0218923390
commit 5e2aeaf19e
6 changed files with 247 additions and 12 deletions

136
Cargo.lock generated
View File

@@ -174,6 +174,15 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" 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]] [[package]]
name = "cmake" name = "cmake"
version = "0.1.57" version = "0.1.57"
@@ -260,6 +269,12 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "endian-type"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
[[package]] [[package]]
name = "enum-iterator" name = "enum-iterator"
version = "2.3.0" version = "2.3.0"
@@ -286,6 +301,33 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 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]] [[package]]
name = "find-msvc-tools" name = "find-msvc-tools"
version = "0.1.9" version = "0.1.9"
@@ -420,6 +462,15 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 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]] [[package]]
name = "http" name = "http"
version = "1.4.0" version = "1.4.0"
@@ -710,6 +761,12 @@ version = "0.2.182"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
[[package]]
name = "linux-raw-sys"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
[[package]] [[package]]
name = "litemap" name = "litemap"
version = "0.8.1" version = "0.8.1"
@@ -736,6 +793,7 @@ dependencies = [
"colored", "colored",
"enum-iterator", "enum-iterator",
"reqwest", "reqwest",
"rustyline",
"serde", "serde",
"serde_json", "serde_json",
"shlex", "shlex",
@@ -771,6 +829,27 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" 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]] [[package]]
name = "objc2" name = "objc2"
version = "0.6.4" version = "0.6.4"
@@ -930,6 +1009,16 @@ version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 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]] [[package]]
name = "rand" name = "rand"
version = "0.9.2" version = "0.9.2"
@@ -1021,6 +1110,19 @@ version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" 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]] [[package]]
name = "rustls" name = "rustls"
version = "0.23.37" version = "0.23.37"
@@ -1102,6 +1204,28 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" 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]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.23" version = "1.0.23"
@@ -1480,6 +1604,18 @@ version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" 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]] [[package]]
name = "untrusted" name = "untrusted"
version = "0.9.0" version = "0.9.0"

View File

@@ -8,6 +8,7 @@ clap = { version = "4.5.60", features = ["derive"] }
colored = "3.1.1" colored = "3.1.1"
enum-iterator = "2.3.0" enum-iterator = "2.3.0"
reqwest = { version = "0.13.2", features = ["blocking", "form"] } reqwest = { version = "0.13.2", features = ["blocking", "form"] }
rustyline = "17.0.2"
serde = { version = "1.0.228", features = ["derive"] } serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149" serde_json = "1.0.149"
shlex = "1.3.0" shlex = "1.3.0"

5
createuserregtoken.json Normal file
View File

@@ -0,0 +1,5 @@
{
"token": "string",
"usage_limit": 0,
"expires_at": "2026-03-06T22:36:06.337Z"
}

View File

@@ -1,4 +1,6 @@
pub mod server; pub mod server;
pub mod user_reg_tokens;
const USERS_ENDPT: &str = "/api/admin/v1/users"; const USERS_ENDPT: &str = "/api/admin/v1/users";
const OAUTH_LINKS_ENDPT: &str = "/api/admin/v1/upstream-oauth-links"; const OAUTH_LINKS_ENDPT: &str = "/api/admin/v1/upstream-oauth-links";

View File

@@ -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,
}

View File

@@ -14,8 +14,13 @@ use std::io::Write;
use clap::{CommandFactory, Parser, Subcommand}; use clap::{CommandFactory, Parser, Subcommand};
use colored::{ColoredString, Colorize}; 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 // google oauth
// 754241279547-kk48of2t6eu5vol85hn6op3ofpp3em76.apps.googleusercontent.com // 754241279547-kk48of2t6eu5vol85hn6op3ofpp3em76.apps.googleusercontent.com
@@ -40,10 +45,23 @@ fn main() {
print_menu(); print_menu();
let mut rl = DefaultEditor::new().unwrap();
loop { loop {
let input = readline().unwrap(); let input = match rl.readline("> ") {
Ok(line) => line,
Err(ReadlineError::Interrupted) => {
println!("Goodbye.");
break;
}
_ => {
continue;
}
};
let input = input.trim(); let input = input.trim();
rl.add_history_entry(input).unwrap();
if input.is_empty() { if input.is_empty() {
continue; continue;
} }
@@ -87,6 +105,10 @@ fn main() {
ServerCommands::ShowSiteConfig => app.show_site_config(), ServerCommands::ShowSiteConfig => app.show_site_config(),
ServerCommands::ShowVersion => app.show_version(), 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(), Commands::ShowOauthLinks => app.show_oauth_links(),
} }
} }
@@ -103,16 +125,6 @@ fn print_menu() {
cli.print_long_help().unwrap(); cli.print_long_help().unwrap();
} }
fn readline() -> Result<String, String> {
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)] #[derive(Debug, clap::Parser)]
#[command(multicall = true)] #[command(multicall = true)]
struct Cli { struct Cli {
@@ -128,6 +140,9 @@ enum Commands {
#[command(subcommand_help_heading = "Get site config and version")] #[command(subcommand_help_heading = "Get site config and version")]
#[command(arg_required_else_help = true)] #[command(arg_required_else_help = true)]
Server(ServerCommandArgs), Server(ServerCommandArgs),
#[command(subcommand_help_heading = "Manage user registration tokens")]
#[command(arg_required_else_help = true)]
UserRegistrationTokens(UserRegTokensArgs),
ShowOauthLinks, ShowOauthLinks,
} }
@@ -143,6 +158,12 @@ struct ServerCommandArgs {
command: ServerCommands, command: ServerCommands,
} }
#[derive(Debug, Parser)]
struct UserRegTokensArgs {
#[command(subcommand)]
command: UserRegTokensCommands,
}
fn quick_format_bool(b: bool) -> ColoredString { fn quick_format_bool(b: bool) -> ColoredString {
match b { match b {
true => "true".bright_green(), true => "true".bright_green(),