pushin more endpoints and stuff in

This commit is contained in:
JP Stringham
2026-03-07 07:45:15 -05:00
parent 5e2aeaf19e
commit 29f1ca8dee
6 changed files with 240 additions and 17 deletions

View File

@@ -1,9 +1,15 @@
pub mod admin; pub mod admin;
pub mod setup; pub mod setup;
use std::io::Write;
use serde::{Deserialize, Serialize};
use crate::json_types::*; use crate::json_types::*;
#[derive(Debug)] const SAVE_PATH: &str = "mas_admin_rs_settings.json";
#[derive(Debug, Serialize, Deserialize)]
pub struct App { pub struct App {
matrix_base_url: String, matrix_base_url: String,
mas_base_url: String, mas_base_url: String,
@@ -23,6 +29,18 @@ impl App {
} }
} }
pub fn try_load_from_file() -> Result<Self, ()> {
let Ok(f) = std::fs::read_to_string(SAVE_PATH) else {
println!("Couldn't open save");
return Err(());
};
match serde_json::from_str::<Self>(&f) {
Ok(app) => Ok(app),
Err(_) => Err(()),
}
}
pub fn admin_api_ready(&self) -> bool { pub fn admin_api_ready(&self) -> bool {
self.auth_metadata.is_some() self.auth_metadata.is_some()
&& self.client_registration.is_some() && self.client_registration.is_some()
@@ -45,4 +63,12 @@ impl App {
crate::quick_format_bool(self.admin_api_ready()) crate::quick_format_bool(self.admin_api_ready())
); );
} }
pub fn save_to_file(&self) {
let mut f = std::fs::File::create(SAVE_PATH).unwrap();
let json = serde_json::to_string_pretty::<App>(&self).unwrap();
f.write(json.as_bytes()).unwrap();
}
} }

View File

@@ -1,7 +1,6 @@
pub mod server; pub mod server;
pub mod user_reg_tokens; pub mod user_reg_tokens;
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";
use crate::json_types::*; use crate::json_types::*;

View File

@@ -0,0 +1,72 @@
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, token: Option<String>, usage_limit: Option<u32>) {
let auth_token = self
.auth_token
.as_ref()
.expect("Need auth token to perform this action");
let json = serde_json::to_string_pretty(&(token, usage_limit)).unwrap();
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(json);
// 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 UpstreamOauthLinksCommands {
List,
Add,
}

View File

@@ -1,6 +1,7 @@
const USER_REG_TOKENS_ENDPT: &str = "/api/admin/v1/user-registration-tokens"; const USER_REG_TOKENS_ENDPT: &str = "/api/admin/v1/user-registration-tokens";
use clap::Subcommand; use clap::Subcommand;
use serde::{Deserialize, Serialize};
use crate::json_types::prettify_json_str; use crate::json_types::prettify_json_str;
@@ -34,12 +35,17 @@ impl App {
println!("{}", json); println!("{}", json);
} }
pub fn create_user_reg_token(&self) { pub fn create_user_reg_token(&self, token: Option<String>, usage_limit: Option<u32>) {
let auth_token = self let auth_token = self
.auth_token .auth_token
.as_ref() .as_ref()
.expect("Need auth token to perform this action"); .expect("Need auth token to perform this action");
let value = CreateRequest { token, usage_limit };
let json = serde_json::to_string_pretty(&value).unwrap();
println!("{json}");
let url = format!("{}{USER_REG_TOKENS_ENDPT}", self.mas_base_url); let url = format!("{}{USER_REG_TOKENS_ENDPT}", self.mas_base_url);
let client = reqwest::blocking::Client::new(); let client = reqwest::blocking::Client::new();
@@ -52,19 +58,81 @@ impl App {
format!("Bearer {}", auth_token.access_token.clone()), format!("Bearer {}", auth_token.access_token.clone()),
) )
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.body("{}"); .body(json);
// println!("Req {:?}", req); // println!("Req {:?}", req);
let res = req.send().unwrap(); let res = req.send().unwrap();
let json = prettify_json_str(res.text().unwrap().as_str()).unwrap(); if res.status().is_success() {
println!("{}", json); let json = prettify_json_str(res.text().unwrap().as_str()).unwrap();
println!("{}", json);
} else {
println!("Err: {:?}", res.text().unwrap());
}
}
pub fn update_user_reg_token(&self, id: String, usage_limit: u32) {
let auth_token = self
.auth_token
.as_ref()
.expect("Need auth token to perform this action");
let value = UpdateRequest { usage_limit };
let json = serde_json::to_string_pretty(&value).unwrap();
println!("{json}");
let url = format!("{}{USER_REG_TOKENS_ENDPT}/{id}", self.mas_base_url);
let client = reqwest::blocking::Client::new();
let req = client
.put(url)
.header("Accept", "application/json")
.header(
"Authorization",
format!("Bearer {}", auth_token.access_token.clone()),
)
.header("Content-Type", "application/json")
.body(json);
// println!("Req {:?}", req);
let res = req.send().unwrap();
if res.status().is_success() {
let json = prettify_json_str(res.text().unwrap().as_str()).unwrap();
println!("{}", json);
} else {
println!("Err: {:?}", res.text().unwrap());
}
} }
} }
#[derive(Debug, Subcommand, PartialEq, Eq)] #[derive(Debug, Subcommand, PartialEq, Eq)]
pub enum UserRegTokensCommands { pub enum UserRegTokensCommands {
List, List,
Create, Create {
#[arg(long, short)]
token: Option<String>,
#[arg(long, short)]
usage_limit: Option<u32>,
},
Update {
id: String,
usage_limit: u32,
},
}
#[derive(Debug, Serialize, Deserialize)]
struct CreateRequest {
#[serde(skip_serializing_if = "Option::is_none")]
token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
usage_limit: Option<u32>,
}
#[derive(Debug, Serialize, Deserialize)]
struct UpdateRequest {
usage_limit: u32,
} }

View File

@@ -9,9 +9,6 @@
mod app; mod app;
pub mod json_types; pub mod json_types;
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 rustyline::{DefaultEditor, error::ReadlineError};
@@ -28,8 +25,6 @@ use crate::app::{
const MATRIX_SERVER_BASE_URL: &str = "https://matrix.supersaturn.space"; const MATRIX_SERVER_BASE_URL: &str = "https://matrix.supersaturn.space";
const MAS_SERVER_BASE_URL: &str = "https://mas.supersaturn.space"; const MAS_SERVER_BASE_URL: &str = "https://mas.supersaturn.space";
const CLIENT_SECRET: &str = "asdjfja2392ijf23923ndflkas01812j312k3j_18127";
fn main() { fn main() {
//curl --header "Authorization: Bearer syt_anA_YRbjQUlvKVDuAfIDIdPW_0k2VVC" -X GET http://127.0.0.1:8008/_synapse/admin/v2/users/@jp:matrix.supersaturn.space //curl --header "Authorization: Bearer syt_anA_YRbjQUlvKVDuAfIDIdPW_0k2VVC" -X GET http://127.0.0.1:8008/_synapse/admin/v2/users/@jp:matrix.supersaturn.space
// let access_token = "Bearer mat_zA80YL1OafucuRGgdZSPIILCSquto2_nT9b73"; // let access_token = "Bearer mat_zA80YL1OafucuRGgdZSPIILCSquto2_nT9b73";
@@ -37,9 +32,21 @@ fn main() {
println!("{}", "Welcome to auth tools CLI".bright_cyan()); println!("{}", "Welcome to auth tools CLI".bright_cyan());
println!("{} {MATRIX_SERVER_BASE_URL}\n\n", "Homeserver:".green()); println!("{} {MATRIX_SERVER_BASE_URL}\n\n", "Homeserver:".green());
let mut app = App::new(MATRIX_SERVER_BASE_URL, MAS_SERVER_BASE_URL); let mut app = match App::try_load_from_file() {
app.get_auth_metadata(); Ok(a) => {
app.register_client(); println!("Loaded existing app.");
a
}
Err(_) => {
println!("No saved settings found, loading.");
let mut a = App::new(MATRIX_SERVER_BASE_URL, MAS_SERVER_BASE_URL);
a.get_auth_metadata();
a.register_client();
a
}
};
app.print_status(); app.print_status();
@@ -88,6 +95,23 @@ fn main() {
continue; continue;
} }
Commands::Save => {
app.save_to_file();
continue;
}
Commands::Load => {
app = match App::try_load_from_file() {
Ok(a) => a,
Err(_) => {
println!("Could not load settings from file.");
continue;
}
}
}
Commands::Quit => {
println!("Goodbye.");
break;
}
_ => { _ => {
if !app.admin_api_ready() { if !app.admin_api_ready() {
println!( println!(
@@ -100,14 +124,21 @@ fn main() {
} }
match cli.command { match cli.command {
Commands::Setup(_) => unreachable!("Blocked by above match"), Commands::Setup(_) | Commands::Load | Commands::Save | Commands::Quit => {
unreachable!("Blocked by above match")
}
Commands::Server(sub) => match sub.command { Commands::Server(sub) => match sub.command {
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 { Commands::UserRegistrationTokens(sub) => match sub.command {
UserRegTokensCommands::List => app.list_user_reg_tokens(), UserRegTokensCommands::List => app.list_user_reg_tokens(),
UserRegTokensCommands::Create => app.create_user_reg_token(), UserRegTokensCommands::Create { token, usage_limit } => {
app.create_user_reg_token(token, usage_limit);
}
UserRegTokensCommands::Update { id, usage_limit } => {
app.update_user_reg_token(id, usage_limit);
}
}, },
Commands::ShowOauthLinks => app.show_oauth_links(), Commands::ShowOauthLinks => app.show_oauth_links(),
} }
@@ -144,6 +175,9 @@ enum Commands {
#[command(arg_required_else_help = true)] #[command(arg_required_else_help = true)]
UserRegistrationTokens(UserRegTokensArgs), UserRegistrationTokens(UserRegTokensArgs),
ShowOauthLinks, ShowOauthLinks,
Save,
Load,
Quit,
} }
#[derive(Debug, Parser)] #[derive(Debug, Parser)]

View File

@@ -0,0 +1,24 @@
{
"matrix_base_url": "https://matrix.supersaturn.space",
"mas_base_url": "https://mas.supersaturn.space",
"auth_metadata": {
"device_authorization_endpoint": "https://mas.supersaturn.space/oauth2/device",
"token_endpoint": "https://mas.supersaturn.space/oauth2/token",
"registration_endpoint": "https://mas.supersaturn.space/oauth2/registration"
},
"client_registration": {
"client_id": "01KK1Z6GHZSNB4V1BPDQVYP696",
"client_id_issued_at": 1772814025,
"grant_types": [
"refresh_token",
"urn:ietf:params:oauth:grant-type:device_code"
]
},
"auth_token": {
"token_type": "Bearer",
"access_token": "mat_FEHVueqxGCnuVRwBD0mPKpP9xcMuvo_gKwmE3",
"refresh_token": "mar_tHwdr8Lr1SoQlmwM6r8uqVvt8WbUYN_EmYTG4",
"expires_in": 300,
"scope": "urn:mas:admin urn:matrix:client:api:* urn:synapse:admin:*"
}
}