use ate::prelude::*;
use clap::Parser;
#[allow(unused_imports)]
use tracing::{debug, error, info, instrument, span, trace, warn, Level};
use ate_auth::helper::*;
use ate_auth::prelude::*;
#[derive(Parser)]
#[clap(version = "1.5", author = "John S. <johnathan.sharratt@gmail.com>")]
struct Opts {
#[clap(short, long, parse(from_occurrences))]
verbose: i32,
#[clap(short, long)]
debug: bool,
#[clap(subcommand)]
subcmd: SubCommand,
}
#[derive(Parser)]
enum SubCommand {
#[clap()]
Run(Run),
#[clap()]
Generate(Generate),
}
#[derive(Parser)]
struct Run {
#[clap(long, default_value = "~/ate/auth.key")]
auth_key_path: String,
#[clap(long, default_value = "~/ate/web.key")]
web_key_path: String,
#[clap(long, default_value = "~/ate/edge.key")]
edge_key_path: String,
#[clap(long, default_value = "~/ate/contract.key")]
contract_key_path: String,
#[clap(index = 1, default_value = "~/ate/auth")]
logs_path: String,
#[clap(short, long)]
backup_path: Option<String>,
#[clap(short, long, default_value = "ws://localhost:5001/auth")]
url: url::Url,
#[clap(short, long, default_value = "::")]
listen: IpAddr,
#[clap(short, long)]
node_id: Option<u32>,
}
#[derive(Parser)]
struct Generate {
#[clap(index = 1, default_value = "~/ate/")]
key_path: String,
#[clap(short, long, default_value = "256")]
strength: KeySize,
}
fn ctrl_channel() -> tokio::sync::watch::Receiver<bool> {
let (sender, receiver) = tokio::sync::watch::channel(false);
ctrlc_async::set_handler(move || {
let _ = sender.send(true);
})
.unwrap();
receiver
}
#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<(), AteError> {
let opts: Opts = Opts::parse();
ate::log_init(opts.verbose, opts.debug);
match opts.subcmd {
SubCommand::Run(run) => {
let root_write_key: PrivateSignKey = load_key(run.auth_key_path.clone(), ".write");
let root_read_key: EncryptKey = load_key(run.auth_key_path.clone(), ".read");
let root_cert_key: PrivateEncryptKey = load_key(run.auth_key_path.clone(), ".cert");
let web_key: EncryptKey = load_key(run.web_key_path.clone(), ".read");
let edge_key: EncryptKey = load_key(run.edge_key_path.clone(), ".read");
let contract_key: EncryptKey = load_key(run.contract_key_path.clone(), ".read");
let mut cfg_ate = conf_auth();
cfg_ate.log_path = Some(shellexpand::tilde(&run.logs_path).to_string());
if let Some(backup_path) = run.backup_path {
cfg_ate.backup_path = Some(shellexpand::tilde(&backup_path).to_string());
}
cfg_ate.compact_mode = CompactMode::Never;
let mut session = AteSessionUser::new();
session.user.add_read_key(&root_read_key);
session.user.add_write_key(&root_write_key);
let mut flow = ChainFlow::new(
&cfg_ate,
root_write_key,
session,
web_key,
edge_key,
contract_key,
&run.url,
);
flow.terms_and_conditions = Some(ate_auth::GENERIC_TERMS_AND_CONDITIONS.to_string());
let mut cfg_mesh =
ConfMesh::solo_from_url(&cfg_ate, &run.url, &run.listen, None, run.node_id).await?;
cfg_mesh.wire_protocol = StreamProtocol::parse(&run.url)?;
cfg_mesh.listen_certificate = Some(root_cert_key);
let server = create_server(&cfg_mesh).await?;
server.add_route(Box::new(flow), &cfg_ate).await?;
let mut exit = ctrl_channel();
while *exit.borrow() == false {
exit.changed().await.unwrap();
}
println!("Shutting down...");
server.shutdown().await;
println!("Goodbye!");
}
SubCommand::Generate(generate) => {
let mut key_path = generate.key_path.clone();
if key_path.ends_with("/") == false {
key_path += "/";
}
let read_key = EncryptKey::generate(generate.strength);
save_key(key_path.clone(), read_key, "auth.key.read");
let write_key = PrivateSignKey::generate(generate.strength);
save_key(key_path.clone(), write_key, "auth.key.write");
let cert_key = PrivateEncryptKey::generate(generate.strength);
save_key(key_path.clone(), cert_key, "auth.key.cert");
let web_key = EncryptKey::generate(generate.strength);
save_key(key_path.clone(), web_key, "web.key.read");
let edge_key = EncryptKey::generate(generate.strength);
save_key(key_path.clone(), edge_key, "edge.key.read");
let contract_key = EncryptKey::generate(generate.strength);
save_key(key_path.clone(), contract_key, "contract.key.read");
}
}
Ok(())
}