#![allow(unused_imports)]
use ate::prelude::*;
use chrono::Duration;
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::*;
use super::*;
pub async fn main_session_sudo(
token_string: Option<String>,
token_file_path: Option<String>,
code: Option<String>,
auth_url: Option<url::Url>,
) -> Result<AteSessionSudo, SudoError> {
let session = main_session_start(token_string, token_file_path, auth_url.clone()).await?;
let session = match session {
AteSessionType::Group(a) => a.inner,
AteSessionType::User(a) => AteSessionInner::User(a),
AteSessionType::Sudo(a) => AteSessionInner::Sudo(a),
AteSessionType::Nothing => AteSessionInner::Nothing,
};
Ok(match session {
AteSessionInner::User(a) => {
if let Some(auth) = auth_url {
main_sudo(a, code, auth).await?
} else {
AteSessionSudo::default()
}
}
AteSessionInner::Sudo(a) => a,
AteSessionInner::Nothing => AteSessionSudo::new()
})
}
pub async fn sudo_command(
registry: &Registry,
session: &AteSessionUser,
authenticator_code: String,
auth: Url,
) -> Result<AteSessionSudo, SudoError> {
let chain = registry.open_cmd(&auth).await?;
let login = SudoRequest {
session: session.clone(),
authenticator_code,
};
let response: Result<SudoResponse, SudoFailed> = chain.invoke(login).await?;
let result = response?;
Ok(result.authority)
}
pub async fn main_sudo(
session: AteSessionUser,
code: Option<String>,
auth: Url,
) -> Result<AteSessionSudo, SudoError> {
let registry = ate::mesh::Registry::new(&conf_cmd()).await.cement();
let code = match code {
Some(a) => a,
None => {
if !is_tty_stdin() {
bail!(SudoErrorKind::InvalidArguments);
}
eprint!("Authenticator Code: ");
stdout().lock().flush()?;
let mut s = String::new();
std::io::stdin()
.read_line(&mut s)
.expect("Did not enter a valid code");
s.trim().to_string()
}
};
let response = sudo_command(®istry, &session, code.clone(), auth.clone()).await;
let ret = match response {
Ok(a) => a,
Err(SudoError(SudoErrorKind::AccountLocked(duration), _)) => {
if duration > Duration::days(1).to_std().unwrap() {
eprintln!(
"This account has been locked for {} days",
(duration.as_secs() as u64 / 86400u64)
);
} else if duration > Duration::hours(1).to_std().unwrap() {
eprintln!(
"This account has been locked for {} hours",
(duration.as_secs() as u64 / 3600u64)
);
} else if duration > Duration::minutes(1).to_std().unwrap() {
eprintln!(
"This account has been locked for {} minutes",
(duration.as_secs() as u64 / 60u64)
);
} else {
eprintln!(
"This account has been locked for {} seconds",
(duration.as_secs() as u64)
);
}
std::process::exit(1);
}
Err(SudoError(SudoErrorKind::WrongCode, _)) => {
eprintln!("The authentication code was incorrect");
eprintln!("(Warning! Repeated failed attempts will trigger a short ban)");
std::process::exit(1);
}
Err(SudoError(SudoErrorKind::NotFound(username), _)) => {
eprintln!("Account does not exist ({})", username);
std::process::exit(1);
}
Err(SudoError(SudoErrorKind::Unverified(username), _)) => {
eprintln!(
"The account ({}) has not yet been verified - please check your email.",
username
);
std::process::exit(1);
}
Err(err) => {
bail!(err);
}
};
Ok(ret)
}