Skip to content

Commit effd184

Browse files
committed
feat: use new argument to be able to set database path by commandline
1 parent 9fafde3 commit effd184

File tree

5 files changed

+45
-35
lines changed

5 files changed

+45
-35
lines changed

src/main.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use interface::event::{Event, EventHandler};
77
use interface::handlers::handle_key_events;
88
use interface::ui::Tui;
99
use otp::otp_element::{OTPDatabase, CURRENT_DATABASE_VERSION};
10+
use path::init_path;
1011
use ratatui::prelude::CrosstermBackend;
1112
use ratatui::Terminal;
1213
use reading::{get_elements_from_input, get_elements_from_stdin, ReadResult};
@@ -24,7 +25,9 @@ mod path;
2425
mod reading;
2526
mod utils;
2627

27-
fn init(read_password_from_stdin: bool) -> color_eyre::Result<ReadResult> {
28+
fn init(args: &CotpArgs) -> color_eyre::Result<ReadResult> {
29+
init_path(args);
30+
2831
match utils::init_app() {
2932
Ok(first_run) => {
3033
if first_run {
@@ -38,7 +41,7 @@ fn init(read_password_from_stdin: bool) -> color_eyre::Result<ReadResult> {
3841
let save_result = database.save_with_pw(&pw);
3942
pw.zeroize();
4043
save_result.map(|(key, salt)| (database, key, salt.to_vec()))
41-
} else if read_password_from_stdin {
44+
} else if args.password_from_stdin {
4245
get_elements_from_stdin()
4346
} else {
4447
get_elements_from_input()
@@ -52,7 +55,7 @@ fn main() -> AppResult<()> {
5255
color_eyre::install()?;
5356

5457
let cotp_args: CotpArgs = CotpArgs::parse();
55-
let (database, mut key, salt) = match init(cotp_args.password_from_stdin) {
58+
let (database, mut key, salt) = match init(&cotp_args) {
5659
Ok(v) => v,
5760
Err(e) => {
5861
println!("{e}");

src/otp/otp_element.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{fs::File, io::Write, vec};
44

55
use crate::crypto::cryptography::{argon_derive_key, encrypt_string_with_key, gen_salt};
66
use crate::otp::otp_error::OtpError;
7-
use crate::path::get_db_path;
7+
use crate::path::DATABASE_PATH;
88
use data_encoding::BASE32_NOPAD;
99
use qrcode::render::unicode;
1010
use qrcode::QrCode;
@@ -69,7 +69,7 @@ impl OTPDatabase {
6969
fn overwrite_database_key(&self, key: &Vec<u8>, salt: &[u8]) -> Result<(), std::io::Error> {
7070
let json: &str = &serde_json::to_string(&self)?;
7171
let encrypted = encrypt_string_with_key(json.to_string(), key, salt).unwrap();
72-
let mut file = File::create(get_db_path())?;
72+
let mut file = File::create(DATABASE_PATH.get().unwrap())?;
7373
match serde_json::to_string(&encrypted) {
7474
Ok(content) => {
7575
file.write_all(content.as_bytes())?;

src/path.rs

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,26 @@ use std::path::PathBuf;
33
use std::sync::OnceLock;
44
use std::{env, fs};
55

6+
use crate::arguments::CotpArgs;
7+
68
const CURRENT_DB_PATH: &str = "./db.cotp";
79
const XDG_PATH: &str = "cotp/db.cotp";
810
const HOME_PATH: &str = ".cotp/db.cotp";
911

10-
static ONCE_COMPUTED_PATH: OnceLock<PathBuf> = OnceLock::new();
12+
pub static DATABASE_PATH: OnceLock<PathBuf> = OnceLock::new();
1113

12-
pub fn get_db_path() -> PathBuf {
13-
env::var("COTP_DB_PATH")
14-
.map(PathBuf::from)
15-
.unwrap_or_else(|_| get_default_db_path())
14+
/// Initialize singleton database path
15+
pub fn init_path(args: &CotpArgs) -> PathBuf {
16+
DATABASE_PATH
17+
.get_or_init(|| {
18+
args.database_path
19+
.as_ref()
20+
.map(String::from)
21+
.or(env::var("COTP_DB_PATH").ok())
22+
.map(PathBuf::from)
23+
.unwrap_or_else(|| get_default_db_path())
24+
})
25+
.to_owned()
1626
}
1727

1828
// Pushing an absolute path to a PathBuf replaces the entire PathBuf: https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push
@@ -26,26 +36,21 @@ fn get_default_db_path() -> PathBuf {
2636

2737
let home_path = home_dir().map(|path| path.join(HOME_PATH));
2838

29-
ONCE_COMPUTED_PATH
30-
.get_or_init(|| {
31-
data_dir()
32-
.map(PathBuf::from)
33-
.map(|p| p.join(XDG_PATH))
34-
.map(|xdg| {
35-
if !xdg.exists() {
36-
if let Some(home) = &home_path {
37-
if home.exists() {
38-
fs::create_dir_all(xdg.parent().unwrap())
39-
.expect("Failed to create dir");
40-
fs::copy(home, xdg.as_path())
41-
.expect("Failed on copy from legacy dir to XDG_DATA_HOME");
42-
}
43-
}
39+
data_dir()
40+
.map(PathBuf::from)
41+
.map(|p| p.join(XDG_PATH))
42+
.map(|xdg| {
43+
if !xdg.exists() {
44+
if let Some(home) = &home_path {
45+
if home.exists() {
46+
fs::create_dir_all(xdg.parent().unwrap()).expect("Failed to create dir");
47+
fs::copy(home, xdg.as_path())
48+
.expect("Failed on copy from legacy dir to XDG_DATA_HOME");
4449
}
45-
xdg
46-
})
47-
.or(home_path)
48-
.unwrap_or(portable_path)
50+
}
51+
}
52+
xdg
4953
})
50-
.to_owned()
54+
.or(home_path)
55+
.unwrap_or(portable_path)
5156
}

src/reading.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::crypto;
22
use crate::otp::otp_element::{OTPDatabase, OTPElement};
3-
use crate::path::get_db_path;
3+
use crate::path::DATABASE_PATH;
44
use crate::utils;
55
use color_eyre::eyre::{eyre, ErrReport};
66
use std::fs::read_to_string;
@@ -28,7 +28,8 @@ fn get_elements_with_password(mut password: String) -> color_eyre::Result<ReadRe
2828
}
2929

3030
pub fn read_decrypted_text(password: &str) -> color_eyre::Result<(String, Vec<u8>, Vec<u8>)> {
31-
let encrypted_contents = read_to_string(get_db_path()).map_err(ErrReport::from)?;
31+
let encrypted_contents =
32+
read_to_string(DATABASE_PATH.get().unwrap()).map_err(ErrReport::from)?;
3233
if encrypted_contents.is_empty() {
3334
return match delete_db() {
3435
Ok(_) => Err(eyre!(
@@ -58,5 +59,5 @@ pub fn read_from_file(password: &str) -> color_eyre::Result<ReadResult> {
5859
}
5960

6061
fn delete_db() -> io::Result<()> {
61-
std::fs::remove_file(get_db_path())
62+
std::fs::remove_file(DATABASE_PATH.get().unwrap())
6263
}

src/utils.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
use crate::path::get_db_path;
21
use std::time::{SystemTime, UNIX_EPOCH};
32

3+
use crate::path::DATABASE_PATH;
4+
45
pub fn init_app() -> Result<bool, ()> {
5-
let db_path = get_db_path();
6+
let db_path = DATABASE_PATH.get().unwrap(); // Safe to unwrap because we initialize
67
let db_dir = db_path.parent().unwrap();
78
if !db_dir.exists() {
89
if let Err(_e) = std::fs::create_dir_all(db_dir) {

0 commit comments

Comments
 (0)