Revamp desktop usability and multiline fields
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
//! Storage-owned service boundary for the Iced desktop presentation adapter.
|
||||
|
||||
use std::{error::Error, fmt, path::Path};
|
||||
use std::{
|
||||
error::Error,
|
||||
fmt,
|
||||
path::Path,
|
||||
sync::{Arc, OnceLock},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
authentication::{
|
||||
@@ -120,6 +125,7 @@ impl Error for DesktopError {}
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DesktopStorage {
|
||||
config: Config,
|
||||
keys: Arc<OnceLock<KeyStore>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
@@ -299,9 +305,12 @@ impl DesktopMutationRequest {
|
||||
|
||||
impl DesktopStorage {
|
||||
pub fn load(explicit: Option<&Path>) -> Result<Self, DesktopError> {
|
||||
Config::load(explicit)
|
||||
.map(|config| Self { config })
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Configuration, error))
|
||||
let config = Config::load(explicit)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Configuration, error))?;
|
||||
Ok(Self {
|
||||
config,
|
||||
keys: Arc::new(OnceLock::new()),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn system() -> Result<DesktopBootstrap, DesktopError> {
|
||||
@@ -309,8 +318,7 @@ impl DesktopStorage {
|
||||
}
|
||||
|
||||
pub fn bootstrap(self) -> Result<DesktopBootstrap, DesktopError> {
|
||||
let keys = KeyStore::load(self.config.key_material())
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::KeyMaterial, error))?;
|
||||
let keys = self.keys()?;
|
||||
let handle = keys
|
||||
.resolve(self.config.default_key().as_str())
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::KeyMaterial, error))?;
|
||||
@@ -386,7 +394,10 @@ impl DesktopStorage {
|
||||
.config
|
||||
.with_settings(settings)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Configuration, error))?;
|
||||
let storage = Self { config };
|
||||
let storage = Self {
|
||||
config,
|
||||
keys: Arc::clone(&self.keys),
|
||||
};
|
||||
let keys = storage.keys()?;
|
||||
keys.resolve(storage.config.default_key().as_str())
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::KeyMaterial, error))?;
|
||||
@@ -411,7 +422,7 @@ impl DesktopStorage {
|
||||
pub fn tree(&self) -> Result<TreeModel, DesktopError> {
|
||||
let repository = self.repository()?;
|
||||
let keys = self.keys()?;
|
||||
VaultReader::new(&repository, &keys)
|
||||
VaultReader::new(&repository, keys)
|
||||
.list(&DirectoryPath::root())
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Read, error))
|
||||
}
|
||||
@@ -505,7 +516,7 @@ impl DesktopStorage {
|
||||
pub fn find(&self, request: &FindRequest) -> Result<FindResults, DesktopError> {
|
||||
let repository = self.repository()?;
|
||||
let keys = self.keys()?;
|
||||
VaultReader::new(&repository, &keys)
|
||||
VaultReader::new(&repository, keys)
|
||||
.find(&request.terms)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Read, error))
|
||||
}
|
||||
@@ -529,7 +540,7 @@ impl DesktopStorage {
|
||||
) -> Result<GrepResults, DesktopError> {
|
||||
let repository = self.repository()?;
|
||||
let keys = self.keys()?;
|
||||
VaultReader::new(&repository, &keys)
|
||||
VaultReader::new(&repository, keys)
|
||||
.grep(request, provider)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Read, error))
|
||||
}
|
||||
@@ -557,7 +568,7 @@ impl DesktopStorage {
|
||||
) -> Result<DesktopOtpCode, DesktopError> {
|
||||
let repository = self.repository()?;
|
||||
let keys = self.keys()?;
|
||||
let service = OtpService::new(&repository, &keys);
|
||||
let service = OtpService::new(&repository, keys);
|
||||
let uri = service
|
||||
.uri(entry, provider)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Otp, error))?;
|
||||
@@ -582,7 +593,7 @@ impl DesktopStorage {
|
||||
let tree = changed.then(|| self.tree()).transpose()?;
|
||||
let document = changed
|
||||
.then(|| {
|
||||
EntryDocumentService::new(&repository, &keys)
|
||||
EntryDocumentService::new(&repository, keys)
|
||||
.open(entry, provider)
|
||||
.map_err(DesktopError::document)
|
||||
})
|
||||
@@ -617,7 +628,7 @@ impl DesktopStorage {
|
||||
) -> Result<DesktopOtpUri, DesktopError> {
|
||||
let repository = self.repository()?;
|
||||
let keys = self.keys()?;
|
||||
let uri = OtpService::new(&repository, &keys)
|
||||
let uri = OtpService::new(&repository, keys)
|
||||
.uri(entry, provider)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Otp, error))?;
|
||||
let payload = SecretBytes::new(uri.encoded().expose().to_vec());
|
||||
@@ -680,11 +691,11 @@ impl DesktopStorage {
|
||||
let encoded = parsed.encoded().expose().to_vec();
|
||||
let repository = self.repository()?;
|
||||
let keys = self.keys()?;
|
||||
let exists = VaultWriter::new(&repository, &keys)
|
||||
let exists = VaultWriter::new(&repository, keys)
|
||||
.entry_exists(entry)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Otp, error))?;
|
||||
if exists {
|
||||
let mut document = EntryDocumentService::new(&repository, &keys)
|
||||
let mut document = EntryDocumentService::new(&repository, keys)
|
||||
.open(entry, provider)
|
||||
.map_err(DesktopError::document)?;
|
||||
if let Some(field) = otp_field(&document)? {
|
||||
@@ -708,7 +719,7 @@ impl DesktopStorage {
|
||||
.map_err(DesktopError::document)?;
|
||||
}
|
||||
self.save_document(&document)?;
|
||||
let document = EntryDocumentService::new(&repository, &keys)
|
||||
let document = EntryDocumentService::new(&repository, keys)
|
||||
.open(entry, provider)
|
||||
.map_err(DesktopError::document)?;
|
||||
return Ok(DesktopOtpMutation {
|
||||
@@ -725,7 +736,7 @@ impl DesktopStorage {
|
||||
};
|
||||
let input = OtpInput::line(encoded)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Otp, error))?;
|
||||
let service = OtpService::new(&repository, &keys);
|
||||
let service = OtpService::new(&repository, keys);
|
||||
let plan = service
|
||||
.prepare_insert(&request, input)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Otp, error))?;
|
||||
@@ -741,7 +752,7 @@ impl DesktopStorage {
|
||||
&mut committer,
|
||||
)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Otp, error))?;
|
||||
let document = EntryDocumentService::new(&repository, &keys)
|
||||
let document = EntryDocumentService::new(&repository, keys)
|
||||
.open(entry, provider)
|
||||
.map_err(DesktopError::document)?;
|
||||
Ok(DesktopOtpMutation {
|
||||
@@ -770,7 +781,7 @@ impl DesktopStorage {
|
||||
) -> Result<DesktopOtpMutation, DesktopError> {
|
||||
let repository = self.repository()?;
|
||||
let keys = self.keys()?;
|
||||
let mut document = EntryDocumentService::new(&repository, &keys)
|
||||
let mut document = EntryDocumentService::new(&repository, keys)
|
||||
.open(entry, provider)
|
||||
.map_err(DesktopError::document)?;
|
||||
let field = otp_field(&document)?.ok_or_else(|| {
|
||||
@@ -781,7 +792,7 @@ impl DesktopStorage {
|
||||
})?;
|
||||
document.remove(field).map_err(DesktopError::document)?;
|
||||
self.save_document(&document)?;
|
||||
let document = EntryDocumentService::new(&repository, &keys)
|
||||
let document = EntryDocumentService::new(&repository, keys)
|
||||
.open(entry, provider)
|
||||
.map_err(DesktopError::document)?;
|
||||
Ok(DesktopOtpMutation {
|
||||
@@ -818,7 +829,7 @@ impl DesktopStorage {
|
||||
GitIdentity::ironstorage(),
|
||||
)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Git, error))?;
|
||||
let mutator = TreeMutator::new(&repository, &keys);
|
||||
let mutator = TreeMutator::new(&repository, keys);
|
||||
match request {
|
||||
DesktopMutationRequest::Remove(request) => {
|
||||
mutator.remove(request, overwrite, &mut committer)
|
||||
@@ -892,7 +903,7 @@ impl DesktopStorage {
|
||||
replacement: &replacement.config,
|
||||
persisted: false,
|
||||
};
|
||||
let outcome = RecipientPolicyManager::new(&repository, &keys)
|
||||
let outcome = RecipientPolicyManager::new(&repository, keys)
|
||||
.apply_init(request, None, provider, &mut committer)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Repository, error))?;
|
||||
if !committer.persisted {
|
||||
@@ -922,7 +933,7 @@ impl DesktopStorage {
|
||||
) -> Result<EntryDocument, DesktopError> {
|
||||
let repository = self.repository()?;
|
||||
let keys = self.keys()?;
|
||||
if VaultWriter::new(&repository, &keys)
|
||||
if VaultWriter::new(&repository, keys)
|
||||
.entry_exists(entry)
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Document, error))?
|
||||
{
|
||||
@@ -931,7 +942,7 @@ impl DesktopStorage {
|
||||
format!("password-store entry already exists: {entry}"),
|
||||
));
|
||||
}
|
||||
EntryDocumentService::new(&repository, &keys)
|
||||
EntryDocumentService::new(&repository, keys)
|
||||
.open(entry, provider)
|
||||
.map_err(DesktopError::document)
|
||||
}
|
||||
@@ -943,7 +954,7 @@ impl DesktopStorage {
|
||||
) -> Result<EntryDocument, DesktopError> {
|
||||
let repository = self.repository()?;
|
||||
let keys = self.keys()?;
|
||||
EntryDocumentService::new(&repository, &keys)
|
||||
EntryDocumentService::new(&repository, keys)
|
||||
.open(entry, secrets)
|
||||
.map_err(DesktopError::document)
|
||||
}
|
||||
@@ -955,7 +966,7 @@ impl DesktopStorage {
|
||||
let mut committer =
|
||||
AutomaticEntryCommitter::for_entry(&repository, &entry, GitIdentity::ironstorage())
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Git, error))?;
|
||||
EntryDocumentService::new(&repository, &keys)
|
||||
EntryDocumentService::new(&repository, keys)
|
||||
.save_recoverable(document, None, &mut committer)
|
||||
.map_err(DesktopError::document)
|
||||
}
|
||||
@@ -976,9 +987,17 @@ impl DesktopStorage {
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::Repository, error))
|
||||
}
|
||||
|
||||
fn keys(&self) -> Result<KeyStore, DesktopError> {
|
||||
KeyStore::load(self.config.key_material())
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::KeyMaterial, error))
|
||||
fn keys(&self) -> Result<&KeyStore, DesktopError> {
|
||||
if let Some(keys) = self.keys.get() {
|
||||
return Ok(keys);
|
||||
}
|
||||
let keys = KeyStore::load(self.config.key_material())
|
||||
.map_err(|error| DesktopError::new(DesktopErrorKind::KeyMaterial, error))?;
|
||||
let _already_initialized = self.keys.set(keys);
|
||||
Ok(self
|
||||
.keys
|
||||
.get()
|
||||
.expect("the key store was initialized by this or another caller"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user