diff --git a/src/app.rs b/src/app.rs index 34cf36f..ab81e1e 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,9 +1,5 @@ pub mod admin; - -use std::time::{Duration, Instant}; - -use colored::{ColoredString, Colorize}; -use reqwest::StatusCode; +pub mod setup; use crate::json_types::*; @@ -38,183 +34,4 @@ impl App { crate::quick_format_bool(self.client_registration.is_some()) ); } - - pub fn get_auth_metadata(&mut self) { - const METADATA_ENDPT: &str = "/_matrix/client/unstable/org.matrix.msc2965/auth_metadata"; - - let client = reqwest::blocking::Client::new(); - - let req = client - .get(format!("{}{METADATA_ENDPT}", self.matrix_base_url)) - .header("Accept", "application/json"); - - let res = req.send().unwrap(); - - let Ok(metadata) = serde_json::from_str::(&res.text().unwrap()) else { - panic!("Could not get metadata..."); - }; - - // println!("{}", serde_json::to_string_pretty(&metadata).unwrap()); - - self.auth_metadata = Some(metadata); - } - - pub fn register_client(&mut self) { - let auth_metadata = self - .auth_metadata - .as_ref() - .expect("Can't register client without getting auth metadata"); - - let crr = ClientRegisterReq { - client_name: "JP CLI Tool".to_owned(), - client_uri: "https://myclitool.supersaturn.space/".to_owned(), - grant_types: vec![ - "urn:ietf:params:oauth:grant-type:device_code".to_owned(), - "refresh_token".to_owned(), - ], - application_type: "native".to_owned(), - token_endpoint_auth_method: "none".to_owned(), - }; - - let json = serde_json::to_string(&crr).unwrap(); - let client = reqwest::blocking::Client::new(); - - let req = client - .post(auth_metadata.registration_endpoint.as_str()) - .header("Accept", "application/json") - .header("Content-Type", "application/json") - .body(json); - - let res = req.send().unwrap(); - - let Ok(crres) = serde_json::from_str::(&res.text().unwrap()) else { - panic!("Could not get metadata..."); - }; - - // println!("{}", serde_json::to_string_pretty(&crres).unwrap()); - - self.client_registration = Some(crres); - } - - pub fn authorize_device(&mut self) { - let auth_metadata = self - .auth_metadata - .as_ref() - .expect("Can't authorize device without auth metadata"); - - let client_registration = self - .client_registration - .as_ref() - .expect("Can't authorize device without client registration"); - - let client = reqwest::blocking::Client::new(); - - let req = client - .post(&auth_metadata.device_authorization_endpoint) - .header("Content-Type", "application/x-www-form-urlencoded") - .header("Accept", "application/json") - .form(&[ - ("client_id", client_registration.client_id.as_str()), - ( - "scope", - "urn:mas:admin urn:synapse:admin:* urn:matrix:client:api:*", - ), - ]); - - // println!("Req: {:?}\n\n", req); - - let res = req.send().unwrap(); - - let Ok(device_grant) = serde_json::from_str::(&res.text().unwrap()) else { - panic!("Could not get device grant") - }; - - println!("Device Grant: {:?}", device_grant); - - webbrowser::open(&device_grant.verification_uri_complete).unwrap(); - - let start = Instant::now(); - let expiry = Duration::from_secs(device_grant.expires_in); - let interval = Duration::from_secs(device_grant.interval); - loop { - std::thread::sleep(interval); - - if start.elapsed() > expiry { - println!("Request expired!"); - break; - } - - let req = client - .post(&auth_metadata.token_endpoint) - .header("Content-Type", "application/x-www-form-urlencoded") - .header("Accept", "application/json") - .form(&[ - ("client_id", client_registration.client_id.as_str()), - ("device_code", device_grant.device_code.as_str()), - ("grant_type", "urn:ietf:params:oauth:grant-type:device_code"), - ]); - - let res = req.send().unwrap(); - let status = res.status(); - let res_text = res.text().unwrap(); - - match status { - StatusCode::OK => { - let token = serde_json::from_str::(&res_text) - .expect("Couldn't decode auth token"); - println!("{:?}", token); - println!("Authorized!"); - self.auth_token = Some(token); - break; - } - _ => { - println!("...\n\n{}\n\n...", res_text); - println!("Waiting for auth..."); - } - } - } - } - - pub fn refresh_auth(&mut self) { - let auth_metadata = self - .auth_metadata - .as_ref() - .expect("Can't refresh without auth"); - - let client_registration = self - .client_registration - .as_ref() - .expect("Can't refresh without registration.."); - - let auth_token = self - .auth_token - .as_ref() - .expect("Can't refresh without auth"); - - let client = reqwest::blocking::Client::new(); - - let req = client - .post(&auth_metadata.token_endpoint) - .header("Content-Type", "application/x-www-form-urlencoded") - .header("Accept", "application/json") - .form(&[ - ("client_id", client_registration.client_id.as_str()), - ("refresh_token", auth_token.refresh_token.as_str()), - ("grant_type", "refresh_token"), - ]); - - let res = req.send().unwrap(); - let status = res.status(); - let res_text = res.text().unwrap(); - - if status != StatusCode::OK { - panic!("Error refreshing token"); - } - - let token = serde_json::from_str::(&res_text) - .expect("Couldn't decode auth token"); - println!("{:?}", token); - println!("Authorized!"); - self.auth_token = Some(token); - } } diff --git a/src/app/setup.rs b/src/app/setup.rs index e69de29..27ab3a8 100644 --- a/src/app/setup.rs +++ b/src/app/setup.rs @@ -0,0 +1,187 @@ +use super::App; + +use std::time::{Duration, Instant}; + +use crate::json_types::*; +use reqwest::StatusCode; + +impl App { + pub fn get_auth_metadata(&mut self) { + const METADATA_ENDPT: &str = "/_matrix/client/unstable/org.matrix.msc2965/auth_metadata"; + + let client = reqwest::blocking::Client::new(); + + let req = client + .get(format!("{}{METADATA_ENDPT}", self.matrix_base_url)) + .header("Accept", "application/json"); + + let res = req.send().unwrap(); + + let Ok(metadata) = serde_json::from_str::(&res.text().unwrap()) else { + panic!("Could not get metadata..."); + }; + + // println!("{}", serde_json::to_string_pretty(&metadata).unwrap()); + + self.auth_metadata = Some(metadata); + } + + pub fn register_client(&mut self) { + let auth_metadata = self + .auth_metadata + .as_ref() + .expect("Can't register client without getting auth metadata"); + + let crr = ClientRegisterReq { + client_name: "JP CLI Tool".to_owned(), + client_uri: "https://myclitool.supersaturn.space/".to_owned(), + grant_types: vec![ + "urn:ietf:params:oauth:grant-type:device_code".to_owned(), + "refresh_token".to_owned(), + ], + application_type: "native".to_owned(), + token_endpoint_auth_method: "none".to_owned(), + }; + + let json = serde_json::to_string(&crr).unwrap(); + let client = reqwest::blocking::Client::new(); + + let req = client + .post(auth_metadata.registration_endpoint.as_str()) + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .body(json); + + let res = req.send().unwrap(); + + let Ok(crres) = serde_json::from_str::(&res.text().unwrap()) else { + panic!("Could not get metadata..."); + }; + + // println!("{}", serde_json::to_string_pretty(&crres).unwrap()); + + self.client_registration = Some(crres); + } + + pub fn authorize_device(&mut self) { + let auth_metadata = self + .auth_metadata + .as_ref() + .expect("Can't authorize device without auth metadata"); + + let client_registration = self + .client_registration + .as_ref() + .expect("Can't authorize device without client registration"); + + let client = reqwest::blocking::Client::new(); + + let req = client + .post(&auth_metadata.device_authorization_endpoint) + .header("Content-Type", "application/x-www-form-urlencoded") + .header("Accept", "application/json") + .form(&[ + ("client_id", client_registration.client_id.as_str()), + ( + "scope", + "urn:mas:admin urn:synapse:admin:* urn:matrix:client:api:*", + ), + ]); + + // println!("Req: {:?}\n\n", req); + + let res = req.send().unwrap(); + + let Ok(device_grant) = serde_json::from_str::(&res.text().unwrap()) else { + panic!("Could not get device grant") + }; + + println!("Device Grant: {:?}", device_grant); + + webbrowser::open(&device_grant.verification_uri_complete).unwrap(); + + let start = Instant::now(); + let expiry = Duration::from_secs(device_grant.expires_in); + let interval = Duration::from_secs(device_grant.interval); + loop { + std::thread::sleep(interval); + + if start.elapsed() > expiry { + println!("Request expired!"); + break; + } + + let req = client + .post(&auth_metadata.token_endpoint) + .header("Content-Type", "application/x-www-form-urlencoded") + .header("Accept", "application/json") + .form(&[ + ("client_id", client_registration.client_id.as_str()), + ("device_code", device_grant.device_code.as_str()), + ("grant_type", "urn:ietf:params:oauth:grant-type:device_code"), + ]); + + let res = req.send().unwrap(); + let status = res.status(); + let res_text = res.text().unwrap(); + + match status { + StatusCode::OK => { + let token = serde_json::from_str::(&res_text) + .expect("Couldn't decode auth token"); + println!("{:?}", token); + println!("Authorized!"); + self.auth_token = Some(token); + break; + } + _ => { + println!("...\n\n{}\n\n...", res_text); + println!("Waiting for auth..."); + } + } + } + } + + pub fn refresh_auth(&mut self) { + let auth_metadata = self + .auth_metadata + .as_ref() + .expect("Can't refresh without auth"); + + let client_registration = self + .client_registration + .as_ref() + .expect("Can't refresh without registration.."); + + let auth_token = self + .auth_token + .as_ref() + .expect("Can't refresh without auth"); + + let client = reqwest::blocking::Client::new(); + + let req = client + .post(&auth_metadata.token_endpoint) + .header("Content-Type", "application/x-www-form-urlencoded") + .header("Accept", "application/json") + .form(&[ + ("client_id", client_registration.client_id.as_str()), + ("refresh_token", auth_token.refresh_token.as_str()), + ("grant_type", "refresh_token"), + ]); + + let res = req.send().unwrap(); + let status = res.status(); + let res_text = res.text().unwrap(); + + if status != StatusCode::OK { + panic!("Error refreshing token"); + } + + let token = serde_json::from_str::(&res_text) + .expect("Couldn't decode auth token"); + println!("{:?}", token); + println!("Authorized!"); + self.auth_token = Some(token); + } +}