69 lines
2.5 KiB
Rust
69 lines
2.5 KiB
Rust
//! `relicario generate` — emit a fresh password or BIP39 passphrase.
|
|
|
|
use anyhow::Result;
|
|
|
|
pub fn cmd_generate(
|
|
length: Option<u32>,
|
|
bip39: bool,
|
|
words: Option<u32>,
|
|
symbols: Option<String>,
|
|
separator: Option<String>,
|
|
) -> Result<()> {
|
|
use relicario_core::{
|
|
generate_passphrase, generate_password, Capitalization, CharClasses,
|
|
GeneratorRequest, SymbolCharset,
|
|
};
|
|
|
|
// If we're inside a vault, unlock and pull `generator_defaults`. Outside
|
|
// a vault, this stays a fast standalone CSPRNG tool (no unlock prompt).
|
|
let vault_defaults: Option<GeneratorRequest> = if crate::helpers::vault_dir().is_ok() {
|
|
let vault = crate::session::UnlockedVault::unlock_interactive()?;
|
|
Some(vault.load_settings()?.generator_defaults)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
// `--bip39` flag forces Bip39 mode; otherwise use whatever mode the
|
|
// vault default is in (Random when no vault).
|
|
let use_bip39 = bip39 || matches!(vault_defaults, Some(GeneratorRequest::Bip39 { .. }));
|
|
|
|
let output = if use_bip39 {
|
|
let (def_words, def_sep, def_cap) = match &vault_defaults {
|
|
Some(GeneratorRequest::Bip39 { word_count, separator, capitalization }) => {
|
|
(*word_count, separator.clone(), *capitalization)
|
|
}
|
|
_ => (5, " ".to_string(), Capitalization::Lower),
|
|
};
|
|
generate_passphrase(&GeneratorRequest::Bip39 {
|
|
word_count: words.unwrap_or(def_words),
|
|
separator: separator.unwrap_or(def_sep),
|
|
capitalization: def_cap,
|
|
})?
|
|
} else {
|
|
let (def_length, def_classes, def_charset) = match &vault_defaults {
|
|
Some(GeneratorRequest::Random { length, classes, symbol_charset }) => {
|
|
(*length, *classes, symbol_charset.clone())
|
|
}
|
|
_ => (
|
|
20,
|
|
CharClasses { lower: true, upper: true, digits: true, symbols: true },
|
|
SymbolCharset::SafeOnly,
|
|
),
|
|
};
|
|
let symbol_charset = match symbols.as_deref() {
|
|
None => def_charset,
|
|
Some("safe") => SymbolCharset::SafeOnly,
|
|
Some("extended") => SymbolCharset::Extended,
|
|
Some(other) => SymbolCharset::Custom(other.to_string()),
|
|
};
|
|
generate_password(&GeneratorRequest::Random {
|
|
length: length.unwrap_or(def_length),
|
|
classes: def_classes,
|
|
symbol_charset,
|
|
})?
|
|
};
|
|
|
|
println!("{}", output.as_str());
|
|
Ok(())
|
|
}
|