mirror of
https://github.com/FliegendeWurst/KIT-ILIAS-downloader.git
synced 2024-08-28 04:04:18 +00:00
cli: Support for pass(1)
as credential storage
`pass(1)`[1] is a small CLI-based password manager. When passing `--pass-path edu/kit/uXXXX` to `KIT-ILIAS-Downloader`, it now attempts to retrieve the password from `pass(1)`. It is assumed that `pass(1)` is available in the `$PATH` of the process. If that's not the case, it errors out with an error like this: Error: credentials input failed Caused by: pass not found in $PATH! It's also taken care of the case where the value `--pass-path` is not present in the store, the error will look like this: Error: credentials input failed Caused by: `pass` failed with non-zero exit code 1: Error: edu/kit/uXXXX is not in the password store. Closes #32 [1] https://www.passwordstore.org/
This commit is contained in:
parent
f21c0249ed
commit
3a83840f15
35
src/cli.rs
35
src/cli.rs
@ -1,6 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize};
|
||||
|
||||
use anyhow::anyhow;
|
||||
@ -72,6 +74,10 @@ pub struct Opt {
|
||||
#[structopt(short = "P", long)]
|
||||
pub password: Option<String>,
|
||||
|
||||
/// Path inside `pass(1)` to the password for shibboleth.
|
||||
#[structopt(long)]
|
||||
pub pass_path: Option<String>,
|
||||
|
||||
/// ILIAS page to download
|
||||
#[structopt(long)]
|
||||
pub sync_url: Option<String>,
|
||||
@ -170,6 +176,35 @@ pub fn ask_user_pass(opt: &Opt) -> Result<(String, String)> {
|
||||
should_store = true;
|
||||
}
|
||||
}
|
||||
} else if let Some(pass_path) = &opt.pass_path {
|
||||
let pw_out = Command::new("pass")
|
||||
.arg("show")
|
||||
.arg(pass_path)
|
||||
.output()
|
||||
.map_err(|x| {
|
||||
if x.kind() == ErrorKind::NotFound {
|
||||
Error::new(ErrorKind::NotFound, "pass not found in $PATH!")
|
||||
} else {
|
||||
x
|
||||
}
|
||||
})?;
|
||||
if !pw_out.status.success() {
|
||||
return Err(Error::new(
|
||||
ErrorKind::Other,
|
||||
format!(
|
||||
"`pass` failed with non-zero exit code {}: {}",
|
||||
pw_out.status.code()
|
||||
.expect("Failed retrieving pass exit code!"),
|
||||
String::from_utf8(pw_out.stderr)
|
||||
.expect("Failed decoding stderr of pass!")
|
||||
)
|
||||
))?
|
||||
} else {
|
||||
pass = String::from_utf8(pw_out.stdout).map(|x| {
|
||||
x.trim_end().to_string()
|
||||
}).expect("utf-8 decode of `pass(1)`-output failed");
|
||||
should_store = false;
|
||||
}
|
||||
} else {
|
||||
pass = rpassword::prompt_password("Password: ").context("password prompt")?;
|
||||
should_store = true;
|
||||
|
Loading…
Reference in New Issue
Block a user