aboutsummaryrefslogblamecommitdiff
path: root/src/future_rest_admin_api.txt
blob: 19ece27951a1fe63965d84ca5e088ebae3f79032 (plain) (tree)













































































































































































                                                                                                                                                       
        Command::FirstLogin {
            creds,
            user_secrets,
        } => {
            let creds = make_storage_creds(creds);
            let user_secrets = make_user_secrets(user_secrets);

            println!("Please enter your password for key decryption.");
            println!("If you are using LDAP login, this must be your LDAP password.");
            println!("If you are using the static login provider, enter any password, and this will also become your password for local IMAP access.");
            let password = rpassword::prompt_password("Enter password: ")?;
            let password_confirm = rpassword::prompt_password("Confirm password: ")?;
            if password != password_confirm {
                bail!("Passwords don't match.");
            }

            CryptoKeys::init(&creds, &user_secrets, &password).await?;

            println!("");
            println!("Cryptographic key setup is complete.");
            println!("");
            println!("If you are using the static login provider, add the following section to your .toml configuration file:");
            println!("");
            dump_config(&password, &creds);
        }
        Command::InitializeLocalKeys { creds } => {
            let creds = make_storage_creds(creds);

            println!("Please enter a password for local IMAP access.");
            println!("This password is not used for key decryption, your keys will be printed below (do not lose them!)");
            println!(
                "If you plan on using LDAP login, stop right here and use `first-login` instead"
            );
            let password = rpassword::prompt_password("Enter password: ")?;
            let password_confirm = rpassword::prompt_password("Confirm password: ")?;
            if password != password_confirm {
                bail!("Passwords don't match.");
            }

            let master = gen_key();
            let (_, secret) = gen_keypair();
            let keys = CryptoKeys::init_without_password(&creds, &master, &secret).await?;

            println!("");
            println!("Cryptographic key setup is complete.");
            println!("");
            println!("Add the following section to your .toml configuration file:");
            println!("");
            dump_config(&password, &creds);
            dump_keys(&keys);
        }
        Command::AddPassword {
            creds,
            user_secrets,
            gen,
        } => {
            let creds = make_storage_creds(creds);
            let user_secrets = make_user_secrets(user_secrets);

            let existing_password =
                rpassword::prompt_password("Enter existing password to decrypt keys: ")?;
            let new_password = if gen {
                let password = base64::encode_config(
                    &u128::to_be_bytes(thread_rng().gen())[..10],
                    base64::URL_SAFE_NO_PAD,
                );
                println!("Your new password: {}", password);
                println!("Keep it safe!");
                password
            } else {
                let password = rpassword::prompt_password("Enter new password: ")?;
                let password_confirm = rpassword::prompt_password("Confirm new password: ")?;
                if password != password_confirm {
                    bail!("Passwords don't match.");
                }
                password
            };

            let keys = CryptoKeys::open(&creds, &user_secrets, &existing_password).await?;
            keys.add_password(&creds, &user_secrets, &new_password)
                .await?;
            println!("");
            println!("New password added successfully.");
        }
        Command::DeletePassword {
            creds,
            user_secrets,
            allow_delete_all,
        } => {
            let creds = make_storage_creds(creds);
            let user_secrets = make_user_secrets(user_secrets);

            let existing_password = rpassword::prompt_password("Enter password to delete: ")?;

            let keys = match allow_delete_all {
                true => Some(CryptoKeys::open(&creds, &user_secrets, &existing_password).await?),
                false => None,
            };

            CryptoKeys::delete_password(&creds, &existing_password, allow_delete_all).await?;

            println!("");
            println!("Password was deleted successfully.");

            if let Some(keys) = keys {
                println!("As a reminder, here are your cryptographic keys:");
                dump_keys(&keys);
            }
        }
        Command::ShowKeys {
            creds,
            user_secrets,
        } => {
            let creds = make_storage_creds(creds);
            let user_secrets = make_user_secrets(user_secrets);

            let existing_password = rpassword::prompt_password("Enter key decryption password: ")?;

            let keys = CryptoKeys::open(&creds, &user_secrets, &existing_password).await?;
            dump_keys(&keys);
        }
    }

    Ok(())
}

fn make_storage_creds(c: StorageCredsArgs) -> StorageCredentials {
    let s3_region = Region {
        name: c.region.clone(),
        endpoint: c.s3_endpoint,
    };
    let k2v_region = Region {
        name: c.region,
        endpoint: c.k2v_endpoint,
    };
    StorageCredentials {
        k2v_region,
        s3_region,
        aws_access_key_id: c.aws_access_key_id,
        aws_secret_access_key: c.aws_secret_access_key,
        bucket: c.bucket,
    }
}

fn make_user_secrets(c: UserSecretsArgs) -> UserSecrets {
    UserSecrets {
        user_secret: c.user_secret,
        alternate_user_secrets: c
            .alternate_user_secrets
            .split(',')
            .map(|x| x.trim())
            .filter(|x| !x.is_empty())
            .map(|x| x.to_string())
            .collect(),
    }
}

fn dump_config(password: &str, creds: &StorageCredentials) {
    println!("[login_static.users.<username>]");
    println!(
        "password = \"{}\"",
        hash_password(password).expect("unable to hash password")
    );
    println!("aws_access_key_id = \"{}\"", creds.aws_access_key_id);
    println!(
        "aws_secret_access_key = \"{}\"",
        creds.aws_secret_access_key
    );
}

fn dump_keys(keys: &CryptoKeys) {
    println!("master_key = \"{}\"", base64::encode(&keys.master));
    println!("secret_key = \"{}\"", base64::encode(&keys.secret));
}