aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
blob: a566ec6de4630e5261db513574965c12b4290578 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#![feature(async_fn_in_trait)]

mod timestamp;
mod bayou;
mod config;
mod cryptoblob;
mod imap;
mod k2v_util;
mod lmtp;
mod login;
mod mail;
mod server;
mod storage;

use std::path::PathBuf;

use anyhow::Result;
use clap::{Parser, Subcommand};

use config::*;
use server::Server;

#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
    #[clap(subcommand)]
    command: Command,
}

#[derive(Subcommand, Debug)]
enum Command {
    /// Runs the IMAP+LMTP server daemon
    Server {
        #[clap(short, long, env = "CONFIG_FILE", default_value = "aerogramme.toml")]
        config_file: PathBuf,
    },
    Test,
}

#[derive(Parser, Debug)]
struct UserSecretsArgs {
    /// User secret
    #[clap(short = 'U', long, env = "USER_SECRET")]
    user_secret: String,
    /// Alternate user secrets (comma-separated list of strings)
    #[clap(long, env = "ALTERNATE_USER_SECRETS", default_value = "")]
    alternate_user_secrets: String,
}

#[tokio::main]
async fn main() -> Result<()> {
    if std::env::var("RUST_LOG").is_err() {
        std::env::set_var("RUST_LOG", "main=info,aerogramme=info,k2v_client=info")
    }

    // Abort on panic (same behavior as in Go)
    std::panic::set_hook(Box::new(|panic_info| {
        eprintln!("{}", panic_info);
        eprintln!("{:?}", backtrace::Backtrace::new());
        std::process::abort();
    }));

    tracing_subscriber::fmt::init();

    let args = Args::parse();

    match args.command {
        Command::Server { config_file } => {
            let config = read_config(config_file)?;

            let server = Server::new(config).await?;
            server.run().await?;
        }
        Command::Test => {
            use std::collections::HashMap;
            use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
            println!("--- message pack ---\n{:?}\n--- end  ---\n", rmp_serde::to_vec(&Config {
                lmtp: None,
                imap: Some(ImapConfig { bind_addr: SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 8080) }),
                login_ldap: None,
                login_static: Some(HashMap::from([
                    ("alice".into(), LoginStaticUser {
                        password: "hash".into(),
                        user_secret: "hello".into(),
                        alternate_user_secrets: vec![],
                        email_addresses: vec![],
                        master_key: None,
                        secret_key: None,
                        storage: StaticStorage::Garage(StaticGarageConfig {
                            s3_endpoint: "http://".into(),
                            k2v_endpoint: "http://".into(),
                            aws_region: "garage".into(),
                            aws_access_key_id: "GK...".into(),
                            aws_secret_access_key: "xxx".into(),
                            bucket: "aerogramme".into(),
                        }),
                    })
                ])),
            }).unwrap()); 
        }
    }

    Ok(())
}