-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
532 additions
and
502 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
//! Adds backup archive functions to network account. | ||
use super::network_account::LocalAccount; | ||
use crate::client::{NetworkAccount, Result}; | ||
use sos_sdk::account::{ | ||
archive::{Inventory, RestoreOptions}, | ||
AccountInfo, | ||
}; | ||
use std::path::{Path, PathBuf}; | ||
use tokio::io::{AsyncRead, AsyncSeek}; | ||
|
||
impl NetworkAccount { | ||
/// Create a backup archive containing the | ||
/// encrypted data for the account. | ||
pub async fn export_backup_archive<P: AsRef<Path>>( | ||
&self, | ||
path: P, | ||
) -> Result<()> { | ||
Ok(self.account.export_backup_archive(path).await?) | ||
} | ||
|
||
/// Read the inventory from an archive. | ||
pub async fn restore_archive_inventory< | ||
R: AsyncRead + AsyncSeek + Unpin, | ||
>( | ||
buffer: R, | ||
) -> Result<Inventory> { | ||
Ok(LocalAccount::restore_archive_inventory(buffer).await?) | ||
} | ||
|
||
/// Import from an archive file. | ||
pub async fn restore_backup_archive<P: AsRef<Path>>( | ||
owner: Option<&mut NetworkAccount>, | ||
path: P, | ||
options: RestoreOptions, | ||
data_dir: Option<PathBuf>, | ||
) -> Result<AccountInfo> { | ||
Ok(LocalAccount::restore_backup_archive( | ||
owner.map(|o| &mut o.account), | ||
path, | ||
options, | ||
data_dir, | ||
) | ||
.await?) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
//! Adds contacts functions to network account. | ||
use crate::client::{NetworkAccount, Result}; | ||
use sos_sdk::{ | ||
account::contacts::ContactImportProgress, | ||
vault::{secret::SecretId, Summary}, | ||
}; | ||
use std::path::Path; | ||
|
||
impl NetworkAccount { | ||
/// Get an avatar JPEG image for a contact in the current | ||
/// open folder. | ||
pub async fn load_avatar( | ||
&mut self, | ||
secret_id: &SecretId, | ||
folder: Option<Summary>, | ||
) -> Result<Option<Vec<u8>>> { | ||
Ok(self.account.load_avatar(secret_id, folder).await?) | ||
} | ||
|
||
/// Export a contact secret to vCard file. | ||
pub async fn export_vcard_file<P: AsRef<Path>>( | ||
&mut self, | ||
path: P, | ||
secret_id: &SecretId, | ||
folder: Option<Summary>, | ||
) -> Result<()> { | ||
Ok(self | ||
.account | ||
.export_vcard_file(path, secret_id, folder) | ||
.await?) | ||
} | ||
|
||
/// Export all contacts to a single vCard. | ||
pub async fn export_all_vcards<P: AsRef<Path>>( | ||
&mut self, | ||
path: P, | ||
) -> Result<()> { | ||
Ok(self.account.export_all_vcards(path).await?) | ||
} | ||
|
||
/// Import vCards from a string buffer. | ||
pub async fn import_vcard( | ||
&mut self, | ||
content: &str, | ||
progress: impl Fn(ContactImportProgress), | ||
) -> Result<()> { | ||
Ok(self.account.import_vcard(content, progress).await?) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
//! Adds functions for listening to change notifications using | ||
//! a websocket connection. | ||
use crate::client::{ | ||
account::remote::{NetworkAccountReceiver, NetworkAccountSender}, | ||
Error, ListenOptions, NetworkAccount, Origin, RemoteBridge, Result, | ||
WebSocketHandle, | ||
}; | ||
use futures::{select, FutureExt}; | ||
use sos_sdk::prelude::SecureAccessKey; | ||
use std::sync::Arc; | ||
|
||
use super::network_account::LocalAccount; | ||
|
||
impl NetworkAccount { | ||
/// Listen for changes on a remote origin. | ||
pub async fn listen( | ||
&self, | ||
origin: &Origin, | ||
options: ListenOptions, | ||
) -> Result<WebSocketHandle> { | ||
let remotes = self.remotes.read().await; | ||
if let Some(remote) = remotes.get(origin) { | ||
if let Some(remote) = | ||
remote.as_any().downcast_ref::<RemoteBridge>() | ||
{ | ||
let remote = Arc::new(remote.clone()); | ||
let (handle, rx, tx) = RemoteBridge::listen(remote, options); | ||
self.spawn_remote_bridge_channels(rx, tx); | ||
|
||
// Store the listeners so we can | ||
// close the connections on sign out | ||
let mut listeners = self.listeners.lock().await; | ||
listeners.push(handle.clone()); | ||
|
||
Ok(handle) | ||
} else { | ||
unreachable!(); | ||
} | ||
} else { | ||
Err(Error::OriginNotFound(origin.clone())) | ||
} | ||
} | ||
|
||
fn spawn_remote_bridge_channels( | ||
&self, | ||
mut rx: NetworkAccountReceiver, | ||
tx: NetworkAccountSender, | ||
) { | ||
if self.account.is_authenticated() { | ||
let user = self.user().unwrap(); | ||
let keeper = user.identity().keeper(); | ||
let secret_key = user.identity().signer().to_bytes(); | ||
|
||
// TODO: needs shutdown hook so this loop exits | ||
// TODO: when the websocket connection is closed | ||
tokio::task::spawn(async move { | ||
loop { | ||
select!( | ||
event = rx | ||
.secure_access_key_rx | ||
.recv() | ||
.fuse() => { | ||
if let Some((folder_id, secure_key)) = event { | ||
|
||
// Decrypt the secure access key received | ||
// when creating or importing a folder, | ||
// must be done here as the remote bridge | ||
// does not have access to the private key | ||
// (account signing key) | ||
let access_key = SecureAccessKey::decrypt( | ||
&secure_key, | ||
secret_key.clone(), | ||
) | ||
.await?; | ||
|
||
// Save the access key for the synced folder | ||
let identity = Arc::clone(&keeper); | ||
LocalAccount::save_folder_password( | ||
identity, | ||
&folder_id, | ||
access_key.clone(), | ||
) | ||
.await?; | ||
|
||
tx.access_key_tx.send(access_key).await?; | ||
} | ||
} | ||
event = rx | ||
.remove_vault_rx | ||
.recv() | ||
.fuse() => { | ||
if let Some(folder_id) = event { | ||
// When a folder is removed via remote | ||
// bridge changes we need to clean up the | ||
// passphrase | ||
let identity = Arc::clone(&keeper); | ||
LocalAccount::remove_folder_password( | ||
identity, | ||
&folder_id, | ||
) | ||
.await?; | ||
} | ||
} | ||
) | ||
} | ||
Ok::<(), Error>(()) | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
//! Adds migration functions to network account. | ||
use crate::client::{NetworkAccount, Result}; | ||
use sos_sdk::vault::Summary; | ||
use std::path::Path; | ||
|
||
#[cfg(feature = "migrate")] | ||
use sos_migrate::{import::ImportTarget, AccountExport, AccountImport}; | ||
|
||
#[cfg(feature = "migrate")] | ||
impl NetworkAccount { | ||
/// Write a zip archive containing all the secrets | ||
/// for the account unencrypted. | ||
/// | ||
/// Used to migrate an account to another app. | ||
pub async fn export_unsafe_archive<P: AsRef<Path>>( | ||
&self, | ||
path: P, | ||
) -> Result<()> { | ||
let migration = AccountExport::new(&self.account); | ||
Ok(migration.export_unsafe_archive(path).await?) | ||
} | ||
|
||
/// Import secrets from another app. | ||
#[cfg(feature = "migrate")] | ||
pub async fn import_file( | ||
&mut self, | ||
target: ImportTarget, | ||
) -> Result<Summary> { | ||
let _ = self.sync_lock.lock().await; | ||
let mut migration = AccountImport::new(&mut self.account); | ||
Ok(migration.import_file(target).await?) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.