diff options
author | Cara Salter <cara@devcara.com> | 2022-06-28 16:45:16 -0400 |
---|---|---|
committer | Cara Salter <cara@devcara.com> | 2022-06-28 16:45:16 -0400 |
commit | 06b1533c226627950b57dc7c71a2d9baede85707 (patch) | |
tree | e98490f919ed422f95b63d3b1e303a73f215b1a6 /src | |
parent | a764356ba2934c8bc6114d079e687407dba7ccce (diff) | |
download | solarctl-0.3.0.tar.gz solarctl-0.3.0.zip |
auth: Login command and user authentication0.3.0
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/src/main.rs b/src/main.rs index e629d0d..70fd438 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,15 @@ +use std::fs; use std::process::Command; use clap::Parser; mod errors; use errors::CliError; +use reqwest::header; use tabular::{row, Table}; use reqwest::{blocking::Client, StatusCode}; use solarlib::planet::{Planet, Memory, CpuCount}; use solarlib::star::NewPlanet; +use serde::{Serialize, Deserialize}; /// Manage solard and homeworld instances #[derive(Parser)] @@ -19,6 +22,11 @@ struct Args { action: Action } +#[derive(Serialize, Deserialize)] +struct ServerConfig { + pub token: String +} + #[derive(clap::Subcommand)] enum Action { /// List planets on the server @@ -60,13 +68,33 @@ enum Action { /// The Sha256 hash of the ship ship: String + }, + + /// Goes through the first-time authentication process to create a token that expires after one + /// year, storing it in the process. + Login { + key: String } } fn main() { color_eyre::install().unwrap(); let args = Args::parse(); - let client = reqwest::blocking::Client::new(); + let xdg_dirs = xdg::BaseDirectories::with_profile("solarctl", args.server.clone()).unwrap(); + + let mut headers = header::HeaderMap::new(); + + if let Some(p) = xdg_dirs.find_config_file("config.json") { + let c = fs::read_to_string(p).unwrap(); + if let Ok(cfg) = serde_json::from_str::<ServerConfig>(&c) { + headers.insert(header::AUTHORIZATION, header::HeaderValue::from_str(&cfg.token).unwrap()); + } + + } else { + println!("No config file found! You will need to authenticate with the `login` subcommand"); + } + + let client = reqwest::blocking::ClientBuilder::new().default_headers(headers).build().unwrap(); let root = args.server.clone(); @@ -91,6 +119,9 @@ fn main() { }, Action::Create { max_mem, max_cpus, disk_size_mb, name, ship } => { create(root, client, max_mem, max_cpus, disk_size_mb, name, ship).unwrap(); + }, + Action::Login { key } => { + login(root, client, key); } }; } @@ -233,3 +264,39 @@ fn create(s: String, c: Client, mem: u64, cpus: u64, disk_size: u64, name: Strin Ok(()) } + +fn login(s: String, c: Client, k: String) -> Result<(), CliError> { + let url = format!("http://{}/auth/begin?key={}", s, k); + + println!("Obtaining token..."); + let res = c.post(url).send()?; + + match res.status() { + StatusCode::OK => { + let token = res.text()?; + let xdg_dirs = xdg::BaseDirectories::with_profile("solarctl", s).unwrap(); + + if let Some(p) = xdg_dirs.find_config_file("config.json") { + let cfg = ServerConfig { + token + }; + + fs::write(p, serde_json::to_string_pretty(&cfg).unwrap()).unwrap(); + + } else { + let p = xdg_dirs.place_config_file("config.json").unwrap(); + let cfg = ServerConfig { + token + }; + + fs::write(p, serde_json::to_string_pretty(&cfg).unwrap()).unwrap(); + } + + }, + _ => { + return Err(CliError::Cli(format!("Could not authenticate: {}", res.text()?))); + } + }; + + Ok(()) +} |