diff --git a/Cargo.lock b/Cargo.lock
index c3cc6954..668d962c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -182,9 +182,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
-version = "1.8.1"
+version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a"
+checksum = "7d809780667f4410e7c41b07f52439b94d2bdf8528eeedc287fa38d3b7f95d82"
[[package]]
name = "bindgen"
@@ -519,18 +519,18 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.53"
+version = "4.5.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8"
+checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
-version = "4.5.53"
+version = "4.5.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00"
+checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00"
dependencies = [
"anstyle",
"clap_lex",
@@ -1499,7 +1499,7 @@ dependencies = [
"cfg-if",
"js-sys",
"libc",
- "wasi",
+ "wasi 0.11.1+wasi-snapshot-preview1",
"wasm-bindgen",
]
@@ -2340,9 +2340,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.178"
+version = "0.2.179"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
+checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f"
[[package]]
name = "libgit2-sys"
@@ -2546,7 +2546,7 @@ checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
dependencies = [
"libc",
"log",
- "wasi",
+ "wasi 0.11.1+wasi-snapshot-preview1",
"windows-sys 0.61.2",
]
@@ -2934,9 +2934,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "pest"
-version = "2.8.4"
+version = "2.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22"
+checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7"
dependencies = [
"memchr",
"ucd-trie",
@@ -2944,9 +2944,9 @@ dependencies = [
[[package]]
name = "pest_derive"
-version = "2.8.4"
+version = "2.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f"
+checksum = "68f9dbced329c441fa79d80472764b1a2c7e57123553b8519b36663a2fb234ed"
dependencies = [
"pest",
"pest_generator",
@@ -2954,9 +2954,9 @@ dependencies = [
[[package]]
name = "pest_generator"
-version = "2.8.4"
+version = "2.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625"
+checksum = "3bb96d5051a78f44f43c8f712d8e810adb0ebf923fc9ed2655a7f66f63ba8ee5"
dependencies = [
"pest",
"pest_meta",
@@ -2967,9 +2967,9 @@ dependencies = [
[[package]]
name = "pest_meta"
-version = "2.8.4"
+version = "2.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82"
+checksum = "602113b5b5e8621770cfd490cfd90b9f84ab29bd2b0e49ad83eb6d186cef2365"
dependencies = [
"pest",
"sha2",
@@ -3445,7 +3445,6 @@ dependencies = [
"gettext",
"glob",
"hex",
- "lazy_static",
"locale_config",
"man",
"ripasso",
@@ -3994,9 +3993,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
-version = "2.0.112"
+version = "2.0.113"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4"
+checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4"
dependencies = [
"proc-macro2",
"quote",
@@ -4270,9 +4269,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.48.0"
+version = "1.49.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
+checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
dependencies = [
"bytes",
"libc",
@@ -4294,9 +4293,9 @@ dependencies = [
[[package]]
name = "tokio-util"
-version = "0.7.17"
+version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594"
+checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
dependencies = [
"bytes",
"futures-core",
@@ -4627,6 +4626,15 @@ version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+[[package]]
+name = "wasi"
+version = "0.14.7+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c"
+dependencies = [
+ "wasip2",
+]
+
[[package]]
name = "wasip2"
version = "1.0.1+wasi-0.2.4"
@@ -4638,9 +4646,12 @@ dependencies = [
[[package]]
name = "wasite"
-version = "0.1.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
+checksum = "313fb64fed616e75426cf738284efe4e85017243bccfae42698be1d7fa9b05d5"
+dependencies = [
+ "wasi 0.14.7+wasi-0.2.4",
+]
[[package]]
name = "wasm-bindgen"
@@ -4792,9 +4803,9 @@ dependencies = [
[[package]]
name = "webpki-root-certs"
-version = "1.0.4"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee3e3b5f5e80bc89f30ce8d0343bf4e5f12341c51f3e26cbeecbc7c85443e85b"
+checksum = "36a29fc0408b113f68cf32637857ab740edfafdf460c326cd2afaa2d84cc05dc"
dependencies = [
"rustls-pki-types",
]
@@ -4807,9 +4818,9 @@ checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
[[package]]
name = "whoami"
-version = "1.6.1"
+version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d"
+checksum = "86dc1eeef7866078951fc09f1857d3d33a37432fe376d7ff45449c8bb50318c1"
dependencies = [
"libredox",
"wasite",
@@ -5442,9 +5453,9 @@ dependencies = [
[[package]]
name = "zmij"
-version = "1.0.7"
+version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de9211a9f64b825911bdf0240f58b7a8dac217fe260fc61f080a07f61372fbd5"
+checksum = "30e0d8dffbae3d840f64bda38e28391faef673a7b5a6017840f2a106c8145868"
[[package]]
name = "zune-core"
diff --git a/Cargo.toml b/Cargo.toml
index cc834610..650b7b77 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,7 +15,7 @@ gpgme = "0.11"
chrono = { version = "0.4", default-features = false, features = ["clock"] }
git2 = "0.20"
rand = "0.9"
-whoami = "1"
+whoami = "2"
toml = "0.9"
reqwest = { version = "0.13", features = ["blocking"] }
hex = "0.4"
@@ -36,6 +36,9 @@ flate2 = "1"
tar = "0.4"
criterion = "0.8"
+[lints.clippy]
+pedantic = "warn"
+
[workspace]
members = [
diff --git a/benches/library_benchmark.rs b/benches/library_benchmark.rs
index cbb34f6e..165f9038 100644
--- a/benches/library_benchmark.rs
+++ b/benches/library_benchmark.rs
@@ -30,12 +30,12 @@ fn cleanup(mut base_path: PathBuf, path_name: &str) -> Result<(), std::io::Error
fn pop_list(password_dir: PathBuf) -> pass::Result<()> {
let store = pass::PasswordStore::new(
"",
- &Some(password_dir),
- &None,
- &None,
- &None,
- &CryptoImpl::GpgMe,
- &None,
+ Some(&password_dir),
+ None,
+ None,
+ None,
+ CryptoImpl::GpgMe,
+ None,
)?;
let results = store.all_passwords().unwrap();
diff --git a/cursive/Cargo.toml b/cursive/Cargo.toml
index 80cc9c75..23a9ca4a 100644
--- a/cursive/Cargo.toml
+++ b/cursive/Cargo.toml
@@ -17,7 +17,6 @@ ripasso = { path = "../", version = "0.8.0" }
locale_config = "0.3"
unic-langid = "0.9"
gettext = "0.4"
-lazy_static = "1"
terminal_size = "0.4"
hex = "0.4"
zeroize = { version = "1", features = ["zeroize_derive", "alloc"] }
@@ -28,9 +27,12 @@ default-features = false
features = ["toml"]
[dev-dependencies]
-tempfile = "3.10.1"
+tempfile = "3"
chrono = { version = "0.4", default-features = false, features = ["clock"] }
[build-dependencies]
glob = "0.3"
man = "0.3"
+
+[lints.clippy]
+pedantic = "warn"
diff --git a/cursive/build.rs b/cursive/build.rs
index eb3e3075..0d0a1a3a 100644
--- a/cursive/build.rs
+++ b/cursive/build.rs
@@ -65,7 +65,7 @@ fn generate_man_page_file() {
dest_path.pop();
dest_path.pop();
dest_path.push("man-page");
- print!("creating directory: {:?} ", &dest_path);
+ print!("creating directory: {} ", dest_path.display());
let res = std::fs::create_dir(&dest_path);
if res.is_ok() {
println!("success");
@@ -73,7 +73,7 @@ fn generate_man_page_file() {
println!("error: {:?}", res.err().unwrap());
}
dest_path.push("cursive");
- print!("creating directory: {:?} ", &dest_path);
+ print!("creating directory: {} ", dest_path.display());
let res = std::fs::create_dir(&dest_path);
if res.is_ok() {
println!("success");
@@ -94,7 +94,7 @@ fn generate_translation_files() {
dest_path.pop();
dest_path.pop();
dest_path.push("translations");
- print!("creating directory: {:?} ", &dest_path);
+ print!("creating directory: {} ", dest_path.display());
let res = std::fs::create_dir(&dest_path);
if res.is_ok() {
println!("success");
@@ -102,7 +102,7 @@ fn generate_translation_files() {
println!("error: {:?}", res.err().unwrap());
}
dest_path.push("cursive");
- print!("creating directory: {:?} ", &dest_path);
+ print!("creating directory: {} ", dest_path.display());
let res = std::fs::create_dir(&dest_path);
if res.is_ok() {
println!("success");
@@ -128,8 +128,8 @@ fn generate_translation_files() {
filename.replace_range(3..4, "m");
print!(
- "generating .mo file for {:?} to {}/{} ",
- &file,
+ "generating .mo file for {} to {}/{} ",
+ file.display(),
dest_path.display(),
&filename
);
diff --git a/cursive/src/helpers.rs b/cursive/src/helpers.rs
index 5ce11856..f49763cc 100644
--- a/cursive/src/helpers.rs
+++ b/cursive/src/helpers.rs
@@ -14,7 +14,7 @@
along with this program. If not, see .
*/
-use std::sync::{Arc, Mutex};
+use std::sync::{Arc, LazyLock, Mutex};
use arboard::Clipboard;
use cursive::{
@@ -22,13 +22,11 @@ use cursive::{
event::Key,
views::{Checkbox, Dialog, EditView, OnEventView, RadioButton, TextView},
};
-use lazy_static::lazy_static;
use pass::Result;
use ripasso::{crypto::CryptoImpl, pass, pass::Recipient};
-lazy_static! {
- static ref CLIPBOARD: Arc> = Arc::new(Mutex::new(Clipboard::new().unwrap()));
-}
+static CLIPBOARD: LazyLock>> =
+ LazyLock::new(|| Arc::new(Mutex::new(Clipboard::new().unwrap())));
/// Displays an error in a cursive dialog
pub fn errorbox(ui: &mut Cursive, err: &pass::Error) {
@@ -52,7 +50,7 @@ pub fn errorbox(ui: &mut Cursive, err: &pass::Error) {
}
/// Copies content to the clipboard.
-pub fn set_clipboard(content: &String) -> Result<()> {
+pub fn set_clipboard(content: &str) -> Result<()> {
Ok(CLIPBOARD.lock().unwrap().set_text(content)?)
}
diff --git a/cursive/src/main.rs b/cursive/src/main.rs
index d38e85eb..56a33d3e 100644
--- a/cursive/src/main.rs
+++ b/cursive/src/main.rs
@@ -14,14 +14,7 @@
along with this program. If not, see .
*/
-use std::{
- collections::HashMap,
- path::{Path, PathBuf},
- process,
- sync::{Arc, Mutex},
- thread, time,
-};
-
+use config::Config;
use cursive::{
Cursive, CursiveExt,
direction::Orientation,
@@ -44,31 +37,39 @@ use ripasso::{
passphrase_generator::passphrase_generator,
password_generator::password_generator,
};
+use std::sync::{LazyLock, MutexGuard};
+use std::{
+ collections::HashMap,
+ path::{Path, PathBuf},
+ process,
+ sync::{Arc, Mutex},
+ thread, time,
+};
use unic_langid::LanguageIdentifier;
-mod helpers;
-mod wizard;
-
use crate::helpers::{
get_value_from_input, is_checkbox_checked, is_radio_button_selected, recipients_widths,
};
-use lazy_static::lazy_static;
use ripasso::crypto::Fingerprint;
+use ripasso::password_generator::PasswordGenerationCategory;
use zeroize::Zeroize;
-/// The 'pointer' to the current PasswordStore is of this convoluted type.
+mod helpers;
+mod wizard;
+
+/// The 'pointer' to the current `PasswordStore` is of this convoluted type.
type PasswordStoreType = Arc>>>;
/// The list of stores that the user have.
type StoreListType = Arc>>>>;
-lazy_static! {
- static ref CATALOG: gettext::Catalog = get_translation_catalog();
- static ref DEFAULT_TERMINAL_SIZE: (usize, usize) = match terminal_size::terminal_size() {
- Some((terminal_size::Width(w), terminal_size::Height(h))) =>
- (usize::from(w + 8), usize::from(h)),
+static CATALOG: LazyLock = LazyLock::new(get_translation_catalog);
+static DEFAULT_TERMINAL_SIZE: LazyLock<(usize, usize)> =
+ LazyLock::new(|| match terminal_size::terminal_size() {
+ Some((terminal_size::Width(w), terminal_size::Height(h))) => {
+ (usize::from(w + 8), usize::from(h))
+ }
_ => (0, 0),
- };
-}
+ });
fn screen_width(ui: &Cursive) -> usize {
match ui.screen_size().x {
@@ -134,7 +135,7 @@ fn page_up(ui: &mut Cursive) {
);
}
-fn copy(ui: &mut Cursive, store: PasswordStoreType) {
+fn copy(ui: &mut Cursive, store: &PasswordStoreType) {
let sel = ui
.find_name::>("results")
.unwrap()
@@ -155,14 +156,14 @@ fn copy(ui: &mut Cursive, store: PasswordStoreType) {
thread::spawn(|| {
thread::sleep(time::Duration::from_secs(40));
- helpers::set_clipboard(&String::new()).unwrap();
+ helpers::set_clipboard("").unwrap();
});
ui.call_on_name("status_bar", |l: &mut TextView| {
l.set_content(CATALOG.gettext("Copied password to copy buffer for 40 seconds"));
});
}
-fn copy_first_line(ui: &mut Cursive, store: PasswordStoreType) {
+fn copy_first_line(ui: &mut Cursive, store: &PasswordStoreType) {
let sel = ui
.find_name::>("results")
.unwrap()
@@ -183,7 +184,7 @@ fn copy_first_line(ui: &mut Cursive, store: PasswordStoreType) {
thread::spawn(|| {
thread::sleep(time::Duration::from_secs(40));
- helpers::set_clipboard(&String::new()).unwrap();
+ helpers::set_clipboard("").unwrap();
});
ui.call_on_name("status_bar", |l: &mut TextView| {
l.set_content(
@@ -192,7 +193,7 @@ fn copy_first_line(ui: &mut Cursive, store: PasswordStoreType) {
});
}
-fn copy_mfa(ui: &mut Cursive, store: PasswordStoreType) {
+fn copy_mfa(ui: &mut Cursive, store: &PasswordStoreType) {
let sel = ui
.find_name::>("results")
.unwrap()
@@ -229,7 +230,7 @@ fn copy_name(ui: &mut Cursive) {
if let Err(err) = || -> Result<()> {
let name = sel.name.split('/').next_back();
- helpers::set_clipboard(&name.unwrap_or("").to_string())?;
+ helpers::set_clipboard(name.unwrap_or(""))?;
Ok(())
}() {
helpers::errorbox(ui, &err);
@@ -241,7 +242,7 @@ fn copy_name(ui: &mut Cursive) {
});
}
-fn do_delete(ui: &mut Cursive, store: PasswordStoreType) {
+fn do_delete(ui: &mut Cursive, store: &PasswordStoreType) {
ui.call_on_name(
"results",
|l: &mut SelectView| -> Result<()> {
@@ -269,13 +270,14 @@ fn do_delete(ui: &mut Cursive, store: PasswordStoreType) {
ui.pop_layer();
}
-fn delete(ui: &mut Cursive, store: PasswordStoreType) {
+fn delete(ui: &mut Cursive, store: &PasswordStoreType) {
+ let store = store.clone();
ui.add_layer(CircularFocus::new(
Dialog::around(TextView::new(
CATALOG.gettext("Are you sure you want to delete the password?"),
))
.button(CATALOG.gettext("Yes"), move |ui: &mut Cursive| {
- do_delete(ui, store.clone());
+ do_delete(ui, &store);
ui.call_on_name("status_bar", |l: &mut TextView| {
l.set_content(CATALOG.gettext("Password deleted"));
});
@@ -299,7 +301,7 @@ fn get_selected_password_entry(ui: &mut Cursive) -> Option
Some(password_entry)
}
-fn show_file_history(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
+fn show_file_history(ui: &mut Cursive, store: &PasswordStoreType) -> Result<()> {
let password_entry_opt = get_selected_password_entry(ui);
if password_entry_opt.is_none() {
return Ok(());
@@ -345,7 +347,7 @@ fn show_file_history(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
Ok(())
}
-fn do_show_file_history(ui: &mut Cursive, store: PasswordStoreType) {
+fn do_show_file_history(ui: &mut Cursive, store: &PasswordStoreType) {
let res = show_file_history(ui, store);
if let Err(err) = res {
@@ -353,7 +355,7 @@ fn do_show_file_history(ui: &mut Cursive, store: PasswordStoreType) {
}
}
-fn do_password_save(ui: &mut Cursive, password: &str, store: PasswordStoreType, do_pop: bool) {
+fn do_password_save(ui: &mut Cursive, password: &str, store: &PasswordStoreType, do_pop: bool) {
let res = password_save(ui, password, store, do_pop);
if let Err(err) = res {
helpers::errorbox(ui, &err);
@@ -363,7 +365,7 @@ fn do_password_save(ui: &mut Cursive, password: &str, store: PasswordStoreType,
fn password_save(
ui: &mut Cursive,
password: &str,
- store: PasswordStoreType,
+ store: &PasswordStoreType,
do_pop: bool,
) -> Result<()> {
let password_entry_opt = get_selected_password_entry(ui);
@@ -376,7 +378,7 @@ fn password_save(
let r = password_entry.update(password.to_string(), &*store.lock()?.lock()?);
if let Err(err) = r {
- helpers::errorbox(ui, &err)
+ helpers::errorbox(ui, &err);
} else {
if do_pop {
ui.pop_layer();
@@ -391,14 +393,14 @@ fn password_save(
Ok(())
}
-fn do_open(ui: &mut Cursive, store: PasswordStoreType) {
+fn do_open(ui: &mut Cursive, store: &PasswordStoreType) {
let res = open(ui, store);
if let Err(err) = res {
helpers::errorbox(ui, &err);
}
}
-fn open(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
+fn open(ui: &mut Cursive, store: &PasswordStoreType) -> Result<()> {
let password_entry_opt = get_selected_password_entry(ui);
if password_entry_opt.is_none() {
return Ok(());
@@ -415,6 +417,7 @@ fn open(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
}
}
};
+ let store = store.clone();
let d = Dialog::around(TextArea::new().content(&password).with_name("editbox"))
.button(CATALOG.gettext("Save"), move |s| {
let mut new_secret = s
@@ -428,7 +431,7 @@ fn open(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
let mut confirmed_new_secret = s
.call_on_name("editbox", |e: &mut TextArea| e.get_content().to_string())
.unwrap();
- do_password_save(s, &confirmed_new_secret, store.clone(), true);
+ do_password_save(s, &confirmed_new_secret, &store, true);
confirmed_new_secret.zeroize();
})
.dismiss_button(CATALOG.gettext("Close"));
@@ -438,17 +441,17 @@ fn open(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
});
s.add_layer(ev);
} else {
- do_password_save(s, &new_secret, store.clone(), false);
- };
+ do_password_save(s, &new_secret, &store, false);
+ }
new_secret.zeroize();
})
.button(CATALOG.gettext("Generate Password"), move |s| {
- let mut new_password = password_generator(20, 0);
+ let mut new_password = password_generator(20, PasswordGenerationCategory::AsciiOnly);
s.call_on_name("editbox", |e: &mut TextArea| {
e.set_content(&new_password);
});
- new_password.zeroize()
+ new_password.zeroize();
})
@@ -456,7 +459,7 @@ fn open(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
let mut new_password = match passphrase_generator(6) {
Ok(words) => words.join(" "),
Err(err) => {
- helpers::errorbox(s, &ripasso::pass::Error::from(err));
+ helpers::errorbox(s, &err);
return;
}
};
@@ -476,7 +479,7 @@ fn open(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
Ok(())
}
-fn do_rename_file(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
+fn do_rename_file(ui: &mut Cursive, store: &PasswordStoreType) -> Result<()> {
let old_name = ui
.find_name::("old_name_input")
.unwrap()
@@ -517,7 +520,7 @@ fn do_rename_file(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
Ok(())
}
-fn rename_file_dialog(ui: &mut Cursive, store: PasswordStoreType) {
+fn rename_file_dialog(ui: &mut Cursive, store: &PasswordStoreType) {
let sel = ui
.find_name::>("results")
.unwrap()
@@ -556,12 +559,13 @@ fn rename_file_dialog(ui: &mut Cursive, store: PasswordStoreType) {
fields.add_child(old_name_fields);
fields.add_child(new_name_fields);
+ let store = store.clone();
let store2 = store.clone();
let d = Dialog::around(fields)
.title(CATALOG.gettext("Rename File"))
.button(CATALOG.gettext("Rename"), move |ui: &mut Cursive| {
- if let Err(e) = do_rename_file(ui, store.clone()) {
+ if let Err(e) = do_rename_file(ui, &store) {
helpers::errorbox(ui, &e);
}
})
@@ -572,7 +576,7 @@ fn rename_file_dialog(ui: &mut Cursive, store: PasswordStoreType) {
s.pop_layer();
})
.on_event(Key::Enter, move |ui: &mut Cursive| {
- if let Err(e) = do_rename_file(ui, store2.clone()) {
+ if let Err(e) = do_rename_file(ui, &store2) {
helpers::errorbox(ui, &e);
}
});
@@ -584,7 +588,7 @@ fn do_new_password_save(
s: &mut Cursive,
path: &str,
password: &str,
- store: PasswordStoreType,
+ store: &PasswordStoreType,
do_pop: bool,
) {
let res = new_password_save(s, path, password, store, do_pop);
@@ -597,7 +601,7 @@ fn new_password_save(
s: &mut Cursive,
path: &str,
password: &str,
- store: PasswordStoreType,
+ store: &PasswordStoreType,
do_pop: bool,
) -> Result<()> {
let entry = store
@@ -629,7 +633,7 @@ fn new_password_save(
Ok(())
}
-fn create_save(s: &mut Cursive, store: PasswordStoreType) {
+fn create_save(s: &mut Cursive, store: &PasswordStoreType) {
let password = get_value_from_input(s, "new_password_input");
if password.is_none() {
return;
@@ -654,9 +658,10 @@ fn create_save(s: &mut Cursive, store: PasswordStoreType) {
}
if password.contains("otpauth://") {
+ let store = store.clone();
let d = Dialog::around(TextView::new(CATALOG.gettext("It seems like you are trying to save a TOTP code to the password store. This will reduce your 2FA solution to just 1FA, do you want to proceed?")))
.button(CATALOG.gettext("Save"), move |s| {
- do_new_password_save(s, path.as_ref(), password.as_ref(), store.clone(), true);
+ do_new_password_save(s, path.as_ref(), password.as_ref(), &store, true);
})
.dismiss_button(CATALOG.gettext("Close"));
@@ -669,7 +674,109 @@ fn create_save(s: &mut Cursive, store: PasswordStoreType) {
do_new_password_save(s, path.as_ref(), password.as_ref(), store, false);
}
}
-fn create(ui: &mut Cursive, store: PasswordStoreType) {
+
+fn generate_password_callback(
+ category_value: &Arc>,
+ password_length: &Arc>,
+ s: &mut Cursive,
+) {
+ let category = *category_value.lock().unwrap();
+ let length = *password_length.lock().unwrap();
+ let category = if category == 0 {
+ PasswordGenerationCategory::AsciiOnly
+ } else {
+ PasswordGenerationCategory::AsciiExtended
+ };
+ let new_password = password_generator(length, category);
+
+ s.call_on_name("new_password_input", |e: &mut EditView| {
+ e.set_content(new_password);
+ });
+}
+
+fn generate_passphrase_callback(s: &mut Cursive) {
+ let new_password = match passphrase_generator(6) {
+ Ok(words) => words.join(" "),
+ Err(err) => {
+ helpers::errorbox(s, &err);
+ return;
+ }
+ };
+ s.call_on_name("new_password_input", |e: &mut EditView| {
+ e.set_content(new_password);
+ });
+}
+
+fn create_password_options_dialog(
+ category_value: &Arc>,
+ reveal_flag: &Arc>,
+ password_length: &Arc>,
+ s: &mut Cursive,
+) {
+ let mut select = SelectView::::new();
+ select.add_item("Category 0 (ASCII 33–126)", 0);
+ select.add_item("Category 1 (ASCII 33–255)", 1);
+ select.set_selection(*category_value.lock().unwrap());
+ let select = select.with_name("password_category");
+
+ let length_input = EditView::new()
+ .content(password_length.lock().unwrap().to_string())
+ .with_name("password_length")
+ .fixed_width(5);
+
+ let reveal_checkbox = LinearLayout::horizontal()
+ .child(Checkbox::new().on_change({
+ let reveal_flag = reveal_flag.clone();
+ move |siv, checked| {
+ siv.call_on_name("new_password_input", |e: &mut EditView| {
+ e.set_secret(!checked);
+ });
+ *reveal_flag.lock().unwrap() = checked;
+ }
+ }))
+ .child(TextView::new("Reveal password"));
+
+ let dialog_content = LinearLayout::vertical()
+ .child(select.scrollable().fixed_size((30, 5)))
+ .child(
+ LinearLayout::horizontal()
+ .child(TextView::new("Length: "))
+ .child(length_input),
+ )
+ .child(reveal_checkbox);
+
+ let save_selection = {
+ let category_value = category_value.clone();
+ let password_length = password_length.clone();
+ move |s: &mut Cursive| {
+ s.call_on_name("password_category", |view: &mut SelectView| {
+ if let Some(sel) = view.selection() {
+ *category_value.lock().unwrap() = *sel;
+ }
+ });
+
+ s.call_on_name("password_length", |view: &mut EditView| {
+ if let Ok(len) = view.get_content().parse::() {
+ *password_length.lock().unwrap() = len;
+ }
+ });
+
+ s.pop_layer();
+ }
+ };
+
+ let popup = OnEventView::new(
+ Dialog::around(dialog_content)
+ .title("Password Options")
+ .button("OK", save_selection.clone())
+ .dismiss_button("Cancel"),
+ )
+ .on_event(Key::Enter, save_selection);
+
+ s.add_layer(popup);
+}
+
+fn create(ui: &mut Cursive, store: &PasswordStoreType) {
let mut fields = LinearLayout::vertical();
let mut path_fields = LinearLayout::horizontal();
let mut password_fields = LinearLayout::horizontal();
@@ -715,6 +822,7 @@ fn create(ui: &mut Cursive, store: PasswordStoreType) {
let reveal_flag = Arc::new(Mutex::new(false));
let password_length = Arc::new(Mutex::new(20_usize));
+ let store = store.clone();
let d = Dialog::around(fields)
.title(CATALOG.gettext("Add new password"))
.button(CATALOG.gettext("Password Options"), {
@@ -722,97 +830,17 @@ fn create(ui: &mut Cursive, store: PasswordStoreType) {
let reveal_flag = reveal_flag.clone();
let password_length = password_length.clone();
move |s| {
- let mut select = SelectView::::new();
- select.add_item("Category 0 (ASCII 33–126)", 0);
- select.add_item("Category 1 (ASCII 33–255)", 1);
- select.set_selection(*category_value.lock().unwrap());
- let select = select.with_name("password_category");
-
- let length_input = EditView::new()
- .content(password_length.lock().unwrap().to_string())
- .with_name("password_length")
- .fixed_width(5);
-
- let reveal_checkbox = LinearLayout::horizontal()
- .child(cursive::views::Checkbox::new().on_change({
- let reveal_flag = reveal_flag.clone();
- move |siv, checked| {
- siv.call_on_name("new_password_input", |e: &mut EditView| {
- e.set_secret(!checked);
- });
- *reveal_flag.lock().unwrap() = checked;
- }
- }))
- .child(TextView::new("Reveal password"));
-
- let dialog_content = LinearLayout::vertical()
- .child(select.scrollable().fixed_size((30, 5)))
- .child(
- LinearLayout::horizontal()
- .child(TextView::new("Length: "))
- .child(length_input),
- )
- .child(reveal_checkbox);
-
- let save_selection = {
- let category_value = category_value.clone();
- let password_length = password_length.clone();
- move |s: &mut Cursive| {
- s.call_on_name("password_category", |view: &mut SelectView| {
- if let Some(sel) = view.selection() {
- *category_value.lock().unwrap() = *sel;
- }
- });
-
- s.call_on_name("password_length", |view: &mut EditView| {
- if let Ok(len) = view.get_content().parse::() {
- *password_length.lock().unwrap() = len;
- }
- });
-
- s.pop_layer();
- }
- };
-
- let popup = OnEventView::new(
- Dialog::around(dialog_content)
- .title("Password Options")
- .button("OK", save_selection.clone())
- .dismiss_button("Cancel"),
- )
- .on_event(Key::Enter, save_selection);
-
- s.add_layer(popup);
+ create_password_options_dialog(&category_value, &reveal_flag, &password_length, s);
}
})
- .button(CATALOG.gettext("Generate Password"), {
- let category_value = category_value.clone();
- let password_length = password_length.clone();
- move |s| {
- let category = *category_value.lock().unwrap();
- let length = *password_length.lock().unwrap();
- let new_password =
- ripasso::password_generator::password_generator(length, category);
-
- s.call_on_name("new_password_input", |e: &mut EditView| {
- e.set_content(new_password);
- });
- }
+ .button(CATALOG.gettext("Generate Password"), move |s| {
+ generate_password_callback(&category_value, &password_length, s);
})
.button(CATALOG.gettext("Generate Passphrase"), move |s| {
- let new_password = match ripasso::passphrase_generator::passphrase_generator(6) {
- Ok(words) => words.join(" "),
- Err(err) => {
- helpers::errorbox(s, &ripasso::pass::Error::from(err));
- return;
- }
- };
- s.call_on_name("new_password_input", |e: &mut EditView| {
- e.set_content(new_password);
- });
+ generate_passphrase_callback(s);
})
.button(CATALOG.gettext("Save"), move |ui: &mut Cursive| {
- create_save(ui, store.clone())
+ create_save(ui, &store);
})
.dismiss_button(CATALOG.gettext("Cancel"));
@@ -822,14 +850,14 @@ fn create(ui: &mut Cursive, store: PasswordStoreType) {
})
.on_event(Key::Enter, move |ui: &mut Cursive| {
if ui.screen_mut().len() == 1 {
- create_save(ui, store2.clone());
+ create_save(ui, &store2);
}
});
ui.add_layer(ev);
}
-fn delete_recipient(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
+fn delete_recipient(ui: &mut Cursive, store: &PasswordStoreType) -> Result<()> {
let mut l = ui
.find_name::>>("recipients")
.unwrap();
@@ -857,15 +885,16 @@ fn delete_recipient(ui: &mut Cursive, store: PasswordStoreType) -> Result<()> {
}
}
-fn delete_recipient_verification(ui: &mut Cursive, store: PasswordStoreType) {
+fn delete_recipient_verification(ui: &mut Cursive, store: &PasswordStoreType) {
+ let store = store.clone();
ui.add_layer(CircularFocus::new(
Dialog::around(TextView::new(
CATALOG.gettext("Are you sure you want to remove this person?"),
))
.button(CATALOG.gettext("Yes"), move |ui: &mut Cursive| {
- let res = delete_recipient(ui, store.clone());
+ let res = delete_recipient(ui, &store);
if let Err(err) = res {
- helpers::errorbox(ui, &err)
+ helpers::errorbox(ui, &err);
} else {
ui.pop_layer();
}
@@ -874,7 +903,7 @@ fn delete_recipient_verification(ui: &mut Cursive, store: PasswordStoreType) {
));
}
-fn add_recipient(ui: &mut Cursive, store: PasswordStoreType, config_path: &Path) -> Result<()> {
+fn add_recipient(ui: &mut Cursive, store: &PasswordStoreType, config_path: &Path) -> Result<()> {
let l = &*get_value_from_input(ui, "key_id_input").unwrap();
let dir = &*get_value_from_input(ui, "dir_id_input").unwrap();
@@ -891,30 +920,27 @@ fn add_recipient(ui: &mut Cursive, store: PasswordStoreType, config_path: &Path)
let dir_path = std::path::PathBuf::from(dir);
let res = store.add_recipient(&recipient, &dir_path, config_path);
- match res {
- Err(err) => helpers::errorbox(ui, &err),
- Ok(_) => {
- let all_recipients_res = store.recipients_for_path(&dir_path);
- match all_recipients_res {
- Err(err) => helpers::errorbox(ui, &err),
- Ok(recipients) => {
- let (max_width_key, max_width_name) = recipients_widths(&recipients);
-
- let mut recipients_view = ui
- .find_name::>>("recipients")
- .unwrap();
- recipients_view.add_item(
- render_recipient_label(&recipient, max_width_key, max_width_name),
- Some((dir_path, recipient)),
- );
-
- ui.pop_layer();
- ui.call_on_name("status_bar", |l: &mut TextView| {
- l.set_content(
- CATALOG.gettext("Added team member to password store"),
- );
- });
- }
+ if let Err(err) = res {
+ helpers::errorbox(ui, &err);
+ } else {
+ let all_recipients_res = store.recipients_for_path(&dir_path);
+ match all_recipients_res {
+ Err(err) => helpers::errorbox(ui, &err),
+ Ok(recipients) => {
+ let (max_width_key, max_width_name) = recipients_widths(&recipients);
+
+ let mut recipients_view = ui
+ .find_name::>>("recipients")
+ .unwrap();
+ recipients_view.add_item(
+ render_recipient_label(&recipient, max_width_key, max_width_name),
+ Some((dir_path, recipient)),
+ );
+
+ ui.pop_layer();
+ ui.call_on_name("status_bar", |l: &mut TextView| {
+ l.set_content(CATALOG.gettext("Added team member to password store"));
+ });
}
}
}
@@ -924,7 +950,7 @@ fn add_recipient(ui: &mut Cursive, store: PasswordStoreType, config_path: &Path)
Ok(())
}
-fn add_recipient_dialog(ui: &mut Cursive, store: PasswordStoreType, config_path: &Path) {
+fn add_recipient_dialog(ui: &mut Cursive, store: &PasswordStoreType, config_path: &Path) {
let mut all_fields = LinearLayout::vertical();
let mut recipient_fields = LinearLayout::horizontal();
let mut dir_fields = LinearLayout::horizontal();
@@ -954,13 +980,14 @@ fn add_recipient_dialog(ui: &mut Cursive, store: PasswordStoreType, config_path:
all_fields.add_child(recipient_fields);
all_fields.add_child(dir_fields);
+ let store = store.clone();
let config_path = config_path.to_path_buf();
let cf = CircularFocus::new(
Dialog::around(all_fields)
.button(CATALOG.gettext("Yes"), move |ui: &mut Cursive| {
- let res = add_recipient(ui, store.clone(), &config_path);
+ let res = add_recipient(ui, &store, &config_path);
if let Err(err) = res {
- helpers::errorbox(ui, &err)
+ helpers::errorbox(ui, &err);
}
})
.dismiss_button(CATALOG.gettext("Cancel")),
@@ -1008,8 +1035,8 @@ fn render_recipient_label(
)
}
-fn get_sub_dirs(dir: &PathBuf) -> Result> {
- let mut to_visit = vec![dir.clone()];
+fn get_sub_dirs(dir: &Path) -> Result> {
+ let mut to_visit = vec![dir.to_path_buf()];
let mut all = vec![PathBuf::from("./")];
while let Some(d) = to_visit.pop() {
for entry in std::fs::read_dir(d)? {
@@ -1027,7 +1054,7 @@ fn get_sub_dirs(dir: &PathBuf) -> Result> {
Ok(all)
}
-fn view_recipients(ui: &mut Cursive, store: PasswordStoreType, config_path: &Path) -> Result<()> {
+fn view_recipients(ui: &mut Cursive, store: &PasswordStoreType, config_path: &Path) -> Result<()> {
let sub_dirs = get_sub_dirs(&store.lock()?.lock()?.get_store_path());
if let Err(err) = sub_dirs {
helpers::errorbox(ui, &err);
@@ -1049,10 +1076,10 @@ fn view_recipients(ui: &mut Cursive, store: PasswordStoreType, config_path: &Pat
path_to_recipients.insert(dir.clone(), recipients_res?);
}
- view_recipients_for_many_dirs(ui, store, path_to_recipients, config_path);
+ view_recipients_for_many_dirs(ui, store, &path_to_recipients, config_path);
}
std::cmp::Ordering::Equal => {
- do_view_recipients_for_dir(ui, store, sub_dirs[0].clone(), config_path);
+ do_view_recipients_for_dir(ui, store, &sub_dirs[0], config_path);
}
std::cmp::Ordering::Less => {
helpers::errorbox(ui, &pass::Error::Generic("no subdirectories found"));
@@ -1062,7 +1089,7 @@ fn view_recipients(ui: &mut Cursive, store: PasswordStoreType, config_path: &Pat
Ok(())
}
-fn do_view_recipients(ui: &mut Cursive, store: PasswordStoreType, config_path: &Path) {
+fn do_view_recipients(ui: &mut Cursive, store: &PasswordStoreType, config_path: &Path) {
let res = view_recipients(ui, store, config_path);
if let Err(err) = res {
helpers::errorbox(ui, &err);
@@ -1071,15 +1098,15 @@ fn do_view_recipients(ui: &mut Cursive, store: PasswordStoreType, config_path: &
fn view_recipients_for_many_dirs(
ui: &mut Cursive,
- store: PasswordStoreType,
- path_to_recipients: HashMap>,
+ store: &PasswordStoreType,
+ path_to_recipients: &HashMap>,
config_path: &Path,
) {
let mut recipients_view = SelectView::