use clap::Parser;
use dialoguer::{theme::ColorfulTheme, Input, Password, Select};
use etwin_core::clock::SystemClock;
use etwin_core::email::EmailAddress;
use etwin_core::oauth::RfcOauthAccessTokenKey;
use etwin_core::twinoid::{TwinoidApiAuth, TwinoidClient, TwinoidCredentials, TwinoidPassword, TwinoidSession};
use etwin_core::types::AnyError;
use etwin_twinoid_client::http::HttpTwinoidClient;
use std::str::FromStr;
#[derive(Debug, Parser)]
pub struct Args {}
pub async fn run(_args: &Args) -> Result<(), AnyError> {
let clock = SystemClock;
let twinoid_client = HttpTwinoidClient::new(clock)?;
let scenario = vec!["api", "website"];
let scenario = Select::with_theme(&ColorfulTheme::default())
.with_prompt("Scenario?")
.items(&scenario)
.default(0)
.interact_opt()?;
match scenario {
Some(0) => {
let token: String = Input::with_theme(&ColorfulTheme::default())
.with_prompt("Access token?")
.interact_text()?;
let token: RfcOauthAccessTokenKey = token.parse()?;
let auth = TwinoidApiAuth::Token(token);
eprintln!("Fetching `me`");
let me = twinoid_client.get_me_short(auth).await?;
eprintln!("Fetched `me`:");
eprintln!("{:#?}", &me);
}
Some(1) => {
let session = auth_tid_creds(&twinoid_client).await?;
eprintln!("Acquired Twinoid session");
eprintln!("{:#?}", session);
}
_ => panic!("Failed to select scenario"),
};
Ok(())
}
pub async fn auth_tid_creds(tid_client: &HttpTwinoidClient<SystemClock>) -> Result<TwinoidSession, AnyError> {
let email: String = Input::with_theme(&ColorfulTheme::default())
.with_prompt("Email?")
.interact_text()?;
let email = EmailAddress::from_str(email.as_str())?;
let password: String = Password::with_theme(&ColorfulTheme::default())
.with_prompt("Password?")
.interact()?;
let password = TwinoidPassword::new(password.to_string());
let credentials = TwinoidCredentials { email, password };
eprintln!("Starting authentication");
let tid_session = tid_client.create_session(&credentials).await?;
Ok(tid_session)
}