Collect flag-parsing logic into PluginFlags struct

This commit is contained in:
Jack Grigg
2021-04-26 18:09:31 +12:00
parent d4eae4d631
commit d9b4fba546
+39 -16
View File
@@ -1,3 +1,5 @@
use std::convert::{TryFrom, TryInto};
use age_plugin::run_state_machine; use age_plugin::run_state_machine;
use dialoguer::{Confirm, Input, Select}; use dialoguer::{Confirm, Input, Select};
use gumdrop::Options; use gumdrop::Options;
@@ -5,7 +7,7 @@ use yubikey_piv::{
certificate::PublicKeyInfo, certificate::PublicKeyInfo,
key::{RetiredSlotId, SlotId}, key::{RetiredSlotId, SlotId},
policy::{PinPolicy, TouchPolicy}, policy::{PinPolicy, TouchPolicy},
Key, Readers, Key, Readers, Serial,
}; };
mod builder; mod builder;
@@ -105,7 +107,19 @@ struct PluginOptions {
touch_policy: Option<String>, touch_policy: Option<String>,
} }
fn generate(opts: PluginOptions) -> Result<(), Error> { struct PluginFlags {
serial: Option<Serial>,
slot: Option<RetiredSlotId>,
name: Option<String>,
pin_policy: Option<PinPolicy>,
touch_policy: Option<TouchPolicy>,
force: bool,
}
impl TryFrom<PluginOptions> for PluginFlags {
type Error = Error;
fn try_from(opts: PluginOptions) -> Result<Self, Self::Error> {
let serial = opts.serial.map(|s| s.into()); let serial = opts.serial.map(|s| s.into());
let slot = opts.slot.map(util::ui_to_slot).transpose()?; let slot = opts.slot.map(util::ui_to_slot).transpose()?;
let pin_policy = opts let pin_policy = opts
@@ -117,13 +131,25 @@ fn generate(opts: PluginOptions) -> Result<(), Error> {
.map(util::touch_policy_from_string) .map(util::touch_policy_from_string)
.transpose()?; .transpose()?;
let mut yubikey = yubikey::open(serial)?; Ok(PluginFlags {
serial,
slot,
name: opts.name,
pin_policy,
touch_policy,
force: opts.force,
})
}
}
let (stub, recipient, metadata) = builder::IdentityBuilder::new(slot) fn generate(flags: PluginFlags) -> Result<(), Error> {
.with_name(opts.name) let mut yubikey = yubikey::open(flags.serial)?;
.with_pin_policy(pin_policy)
.with_touch_policy(touch_policy) let (stub, recipient, metadata) = builder::IdentityBuilder::new(flags.slot)
.force(opts.force) .with_name(flags.name)
.with_pin_policy(flags.pin_policy)
.with_touch_policy(flags.touch_policy)
.force(flags.force)
.build(&mut yubikey)?; .build(&mut yubikey)?;
util::print_identity(stub, recipient, metadata); util::print_identity(stub, recipient, metadata);
@@ -131,11 +157,8 @@ fn generate(opts: PluginOptions) -> Result<(), Error> {
Ok(()) Ok(())
} }
fn identity(opts: PluginOptions) -> Result<(), Error> { fn identity(flags: PluginFlags) -> Result<(), Error> {
let serial = opts.serial.map(|s| s.into()); let mut yubikey = yubikey::open(flags.serial)?;
let slot = opts.slot.map(util::ui_to_slot).transpose()?;
let mut yubikey = yubikey::open(serial)?;
let mut keys = Key::list(&mut yubikey)?.into_iter().filter_map(|key| { let mut keys = Key::list(&mut yubikey)?.into_iter().filter_map(|key| {
// - We only use the retired slots. // - We only use the retired slots.
@@ -148,7 +171,7 @@ fn identity(opts: PluginOptions) -> Result<(), Error> {
} }
}); });
let (key, slot, recipient) = if let Some(slot) = slot { let (key, slot, recipient) = if let Some(slot) = flags.slot {
keys.find(|(_, s, _)| s == &slot) keys.find(|(_, s, _)| s == &slot)
.ok_or(Error::SlotHasNoIdentity(slot)) .ok_or(Error::SlotHasNoIdentity(slot))
} else { } else {
@@ -252,9 +275,9 @@ fn main() -> Result<(), Error> {
println!("age-plugin-yubikey {}", env!("CARGO_PKG_VERSION")); println!("age-plugin-yubikey {}", env!("CARGO_PKG_VERSION"));
Ok(()) Ok(())
} else if opts.generate { } else if opts.generate {
generate(opts) generate(opts.try_into()?)
} else if opts.identity { } else if opts.identity {
identity(opts) identity(opts.try_into()?)
} else if opts.list { } else if opts.list {
list(false) list(false)
} else if opts.list_all { } else if opts.list_all {