75 lines
2.3 KiB
Rust
75 lines
2.3 KiB
Rust
|
use std::path::PathBuf;
|
||
|
|
||
|
use keyfork_pinentry::{
|
||
|
self, default_binary, ConfirmationDialog, MessageDialog, PassphraseInput, SecretString,
|
||
|
};
|
||
|
|
||
|
#[derive(thiserror::Error, Debug)]
|
||
|
pub enum PinentryError {
|
||
|
#[error("No pinentry binary found")]
|
||
|
NoPinentryFound,
|
||
|
|
||
|
#[error("{0}")]
|
||
|
Internal(#[from] keyfork_pinentry::Error),
|
||
|
}
|
||
|
|
||
|
pub type Result<T, E = PinentryError> = std::result::Result<T, E>;
|
||
|
|
||
|
/// Display message dialogues, confirmation prompts, and passphrase inputs with keyfork-pinentry.
|
||
|
pub struct PromptManager {
|
||
|
program_title: String,
|
||
|
pinentry_binary: PathBuf,
|
||
|
}
|
||
|
|
||
|
impl PromptManager {
|
||
|
pub fn new(
|
||
|
program_title: impl Into<String>,
|
||
|
pinentry_binary: impl Into<Option<PathBuf>>,
|
||
|
) -> Result<Self> {
|
||
|
let path = match pinentry_binary.into() {
|
||
|
Some(p) => p,
|
||
|
None => default_binary()?,
|
||
|
};
|
||
|
std::fs::metadata(&path).map_err(|_| PinentryError::NoPinentryFound)?;
|
||
|
Ok(Self {
|
||
|
program_title: program_title.into(),
|
||
|
pinentry_binary: path,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
#[allow(dead_code)]
|
||
|
pub fn prompt_confirmation(&self, prompt: impl AsRef<str>) -> Result<bool> {
|
||
|
ConfirmationDialog::with_binary(self.pinentry_binary.clone())
|
||
|
.with_title(&self.program_title)
|
||
|
.confirm(prompt.as_ref())
|
||
|
.map_err(|e| e.into())
|
||
|
}
|
||
|
|
||
|
pub fn prompt_message(&self, prompt: impl AsRef<str>) -> Result<()> {
|
||
|
MessageDialog::with_binary(self.pinentry_binary.clone())
|
||
|
.with_title(&self.program_title)
|
||
|
.show_message(prompt.as_ref())
|
||
|
.map_err(|e| e.into())
|
||
|
}
|
||
|
|
||
|
pub fn prompt_passphrase(
|
||
|
&self,
|
||
|
prompt: impl AsRef<str>,
|
||
|
description: impl Into<Option<String>>,
|
||
|
) -> Result<SecretString> {
|
||
|
match description.into() {
|
||
|
Some(desc) => PassphraseInput::with_binary(self.pinentry_binary.clone())
|
||
|
.with_title(&self.program_title)
|
||
|
.with_prompt(prompt.as_ref())
|
||
|
.with_description(&desc)
|
||
|
.interact()
|
||
|
.map_err(|e| e.into()),
|
||
|
None => PassphraseInput::with_binary(self.pinentry_binary.clone())
|
||
|
.with_title(&self.program_title)
|
||
|
.with_prompt(prompt.as_ref())
|
||
|
.interact()
|
||
|
.map_err(|e| e.into()),
|
||
|
}
|
||
|
}
|
||
|
}
|