1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use crate::api::{EventHandler, EventSubscription, PasswordGeneratorParam};
use std::sync::Arc;

mod config;
mod error;
pub mod local;
pub mod pw_generator;
mod remote;
mod secrets_provider;

#[cfg(unix)]
pub mod unix;

pub use self::config::{config_file, StoreConfig};
pub use self::error::*;

use crate::secrets_store::SecretsStore;

pub trait ClipboardControl {
  fn is_done(&self) -> ServiceResult<bool>;

  fn currently_providing(&self) -> ServiceResult<Option<String>>;

  fn provide_next(&self) -> ServiceResult<()>;

  fn destroy(&self) -> ServiceResult<()>;
}

/// Main entrypoint for all interactions with the t-rust-less system
pub trait TrustlessService: std::fmt::Debug {
  /// List all store configurations
  fn list_stores(&self) -> ServiceResult<Vec<StoreConfig>>;

  /// Create or update a store configuration
  fn upsert_store_config(&self, store_config: StoreConfig) -> ServiceResult<()>;

  /// Delete a store configuration
  /// (This will only delete the configuration, the store itself will be left untouched)
  fn delete_store_config(&self, name: &str) -> ServiceResult<()>;

  /// Open a store
  fn open_store(&self, name: &str) -> ServiceResult<Arc<dyn SecretsStore>>;

  /// Get the name of the store that should be opened by default
  fn get_default_store(&self) -> ServiceResult<Option<String>>;

  /// Set the name of the store that should be opened by default
  fn set_default_store(&self, name: &str) -> ServiceResult<()>;

  fn secret_to_clipboard(
    &self,
    store_name: &str,
    block_id: &str,
    properties: &[&str],
    display_name: &str,
  ) -> ServiceResult<Arc<dyn ClipboardControl>>;

  fn add_event_handler(&self, handler: Box<dyn EventHandler>) -> ServiceResult<Box<dyn EventSubscription>>;

  fn generate_id(&self) -> ServiceResult<String>;

  fn generate_password(&self, param: PasswordGeneratorParam) -> ServiceResult<String>;

  fn check_autolock(&self);
}

pub fn create_service() -> ServiceResult<Arc<dyn TrustlessService>> {
  #[cfg(unix)]
  {
    if let Some(remote) = self::unix::try_remote_service()? {
      return Ok(Arc::new(remote));
    }
  }
  Ok(Arc::new(self::local::LocalTrustlessService::new()?))
}