1#![deny(missing_docs)]
2#![forbid(unsafe_code)]
3#![cfg_attr(all(doc, CHANNEL_NIGHTLY), feature(doc_auto_cfg))]
4mod access_point;
6mod builder;
7mod change_password;
8mod encoding;
9mod error;
10pub mod secret;
11mod vault;
12
13pub use access_point::{AccessPoint, SecretAccess};
14pub use builder::{BuilderCredentials, VaultBuilder};
15pub use change_password::ChangePassword;
16pub use error::Error;
17pub use vault::{
18 Contents, EncryptedEntry, Header, SharedAccess, Summary, Vault, VaultMeta,
19};
20
21pub(crate) type Result<T> = std::result::Result<T, Error>;
22pub(crate) use vault::Auth;
23
24use sos_core::{constants::VAULT_EXT, Paths, PublicIdentity};
25use sos_vfs as vfs;
26use std::{
27 path::{Path, PathBuf},
28 sync::Arc,
29};
30
31#[doc(hidden)]
33pub async fn list_accounts(
34 paths: Option<&Paths>,
35) -> Result<Vec<PublicIdentity>> {
36 let mut identities = Vec::new();
37 let paths = if let Some(paths) = paths {
38 Arc::new(paths.clone())
39 } else {
40 Paths::new_client(Paths::data_dir()?)
41 };
42
43 if !vfs::try_exists(paths.identity_dir()).await? {
44 return Ok(Vec::new());
45 }
46
47 let mut dir = vfs::read_dir(paths.identity_dir()).await?;
48 while let Some(entry) = dir.next_entry().await? {
49 if let Some(ident) = read_public_identity(entry.path()).await? {
50 identities.push(ident);
51 }
52 }
53 identities.sort_by(|a, b| a.label().cmp(b.label()));
54 Ok(identities)
55}
56
57#[doc(hidden)]
59pub async fn read_public_identity(
60 path: impl AsRef<Path>,
61) -> Result<Option<PublicIdentity>> {
62 if let (Some(extension), Some(file_stem)) =
63 (path.as_ref().extension(), path.as_ref().file_stem())
64 {
65 if extension == VAULT_EXT {
66 let summary = Header::read_summary_file(path.as_ref()).await?;
67 return Ok(Some(PublicIdentity::new(
68 file_stem.to_string_lossy().parse()?,
69 summary.name().to_owned(),
70 )));
71 } else {
72 Ok(None)
73 }
74 } else {
75 Ok(None)
76 }
77}
78
79#[doc(hidden)]
82pub async fn list_local_folders(
83 paths: &Paths,
84) -> Result<Vec<(Summary, PathBuf)>> {
85 let vaults_dir = paths.vaults_dir();
86 let mut vaults = Vec::new();
87 let mut dir = vfs::read_dir(vaults_dir).await?;
88 while let Some(entry) = dir.next_entry().await? {
89 if let Some(extension) = entry.path().extension() {
90 if extension == VAULT_EXT {
91 let summary = Header::read_summary_file(entry.path()).await?;
92 vaults.push((summary, entry.path().to_path_buf()));
93 }
94 }
95 }
96 Ok(vaults)
97}