Skip to main content

passless_rs/storage/pass/init/
uninitialized.rs

1//! Initial uninitialized state
2
3use super::directory_created::DirectoryCreated;
4
5use crate::notification::{YesNoResult, show_info_notification, show_yes_no_notification};
6use crate::storage::pass::GpgBackend;
7use crate::util::create_secure_dir_all;
8
9use passless_core::error::{Error, Result};
10
11use std::path::PathBuf;
12
13use log::{debug, info, warn};
14
15pub struct Uninitialized {
16    pub(super) store_path: PathBuf,
17    pub(super) gpg_backend: GpgBackend,
18}
19
20impl Uninitialized {
21    pub fn new(store_path: PathBuf, gpg_backend: GpgBackend) -> Self {
22        Self {
23            store_path,
24            gpg_backend,
25        }
26    }
27
28    /// Check if already initialized; returns special error if yes (success case)
29    pub fn check_if_initialized(self) -> Result<Self> {
30        let gpg_id_file = self.store_path.join(".gpg-id");
31
32        if gpg_id_file.exists() {
33            debug!(
34                "Password store already initialized at {:?}",
35                self.store_path
36            );
37            return Err(Error::Config("ALREADY_INITIALIZED".to_string()));
38        }
39
40        info!("Password store not initialized at {:?}", self.store_path);
41        Ok(self)
42    }
43
44    pub fn prompt_user(self, allow_create_without_prompt: bool) -> Result<DirectoryCreated> {
45        if !allow_create_without_prompt {
46            match show_yes_no_notification(
47                "Password Store Not Initialized",
48                &format!(
49                    "The password store directory does not exist at:\n{}\n\nWould you like to initialize it now?",
50                    self.store_path.display()
51                ),
52            ) {
53                Ok(YesNoResult::Accepted) => info!("User agreed to initialize"),
54                Ok(YesNoResult::Denied) => {
55                    warn!("Initialization cancelled by user");
56                    let _ = show_info_notification(
57                        "Initialization Cancelled",
58                        "Password store initialization cancelled by user",
59                    );
60                    return Err(Error::Config("Initialization cancelled".to_string()));
61                }
62                Err(e) => {
63                    warn!("Failed to show initialization prompt: {}", e);
64                    return Err(Error::Config(format!("Failed to prompt: {}", e)));
65                }
66            }
67        }
68
69        if !self.store_path.exists() {
70            create_secure_dir_all(&self.store_path).map_err(|e| {
71                let msg = format!("Failed to create store directory: {}", e);
72                let _ = crate::notification::show_error_notification("Initialization Failed", &msg);
73                Error::Storage(msg)
74            })?;
75            info!("Created store directory at {:?}", self.store_path);
76        }
77
78        Ok(DirectoryCreated {
79            store_path: self.store_path,
80            gpg_backend: self.gpg_backend,
81            allow_create_without_prompt,
82        })
83    }
84}