#![allow(unused_imports)]
use ate::prelude::*;
use error_chain::bail;
use std::io::stdout;
use std::io::Write;
use std::sync::Arc;
use tracing::{debug, error, info, instrument, span, trace, warn, Level};
use url::Url;
use crate::error::*;
use crate::helper::*;
use crate::opt::*;
use crate::prelude::*;
use crate::request::*;
#[allow(dead_code)]
pub async fn create_user_command(
registry: &Registry,
username: String,
password: String,
auth: Url,
accepted_terms: Option<String>,
) -> Result<CreateUserResponse, CreateError> {
let chain = registry.open_cmd(&auth).await?;
let prefix = format!("remote-login:{}:", username);
let read_key = password_to_read_key(&prefix, &password, 15, KeySize::Bit192);
let auth = match auth.domain() {
Some(a) => a.to_string(),
None => "ate".to_string(),
};
let request = CreateUserRequest {
auth,
email: username.clone(),
secret: read_key,
accepted_terms,
};
let response: Result<CreateUserResponse, CreateUserFailed> = chain.invoke(request).await?;
let result = response?;
debug!("key: {}", result.key);
Ok(result)
}
pub async fn main_create_user(
username: Option<String>,
password: Option<String>,
auth: Url,
) -> Result<CreateUserResponse, CreateError> {
let username = match username {
Some(a) => a,
None => {
#[cfg(not(feature = "force_tty"))]
if !is_tty_stdin() {
bail!(CreateErrorKind::InvalidArguments);
}
print!("Username: ");
stdout().lock().flush()?;
let mut s = String::new();
std::io::stdin()
.read_line(&mut s)
.expect("Did not enter a valid username");
s.trim().to_string()
}
};
let password = match password {
Some(a) => a,
None => {
#[cfg(not(feature = "force_tty"))]
if !is_tty_stdin() {
bail!(CreateErrorKind::InvalidArguments);
}
let ret1 = rpassword_wasi::prompt_password("Password: ").unwrap();
stdout().lock().flush()?;
let ret2 = rpassword_wasi::prompt_password("Password Again: ").unwrap();
if ret1 != ret2 {
bail!(CreateErrorKind::PasswordMismatch);
}
ret2
}
};
let registry = ate::mesh::Registry::new(&conf_cmd()).await.cement();
let result = match create_user_command(
®istry,
username.clone(),
password.clone(),
auth.clone(),
None,
)
.await
{
Ok(a) => a,
Err(CreateError(CreateErrorKind::AlreadyExists(msg), _)) => {
eprintln!("{}", msg);
std::process::exit(1);
}
Err(CreateError(CreateErrorKind::TermsAndConditions(terms), _)) => {
if !is_tty_stdin() {
bail!(CreateErrorKind::InvalidArguments);
}
println!("");
println!("{}", terms);
println!("");
println!(
"If you agree to the above terms and conditions then type the word 'agree' below"
);
let mut s = String::new();
std::io::stdin()
.read_line(&mut s)
.expect("Did not enter a valid response");
let agreement = s.trim().to_string().to_lowercase();
if agreement != "agree" {
eprintln!("You may only create an account by specifically agreeing to the terms");
eprintln!("and conditions laid out above - this can only be confirmed if you");
eprintln!("specifically type the word 'agree' which you did not enter hence");
eprintln!("an account can not be created. If this is a mistake then please");
eprintln!("try again.");
std::process::exit(1);
}
create_user_command(®istry, username, password, auth, Some(terms)).await?
}
Err(err) => {
bail!(err);
}
};
if is_tty_stdout() {
println!("User created (id={})", result.key);
println!("");
if let Some(message_of_the_day) = &result.message_of_the_day {
println!("{}", message_of_the_day.as_str());
println!("");
}
println!("Below is your Google Authenticator QR code - scan it on your phone and");
println!("save it as this code is the only way you can recover the account.");
println!("");
println!("{}", result.qr_code);
}
Ok(result)
}