pub use crate::internal::document_api::{
AssociationType, DocAccessEditErr, DocumentAccessResult, DocumentDecryptResult,
DocumentEncryptResult, DocumentListMeta, DocumentListResult, DocumentMetadataResult,
UserOrGroup, VisibleGroup, VisibleUser,
};
use crate::{
internal::{
document_api::{self, DocumentId, DocumentName},
group_api::GroupId,
user_api::UserId,
},
Result,
};
use itertools::{Either, Itertools};
use tokio::runtime::current_thread::Runtime;
#[derive(Debug, PartialEq, Clone)]
pub struct DocumentEncryptOpts {
id: Option<DocumentId>,
name: Option<DocumentName>,
grants: Vec<UserOrGroup>,
}
impl<'a> DocumentEncryptOpts {
pub fn new(
id: Option<DocumentId>,
name: Option<DocumentName>,
grants: Vec<UserOrGroup>,
) -> DocumentEncryptOpts {
DocumentEncryptOpts { id, name, grants }
}
}
impl Default for DocumentEncryptOpts {
fn default() -> Self {
DocumentEncryptOpts::new(None, None, vec![])
}
}
pub trait DocumentOps {
fn document_list(&self) -> Result<DocumentListResult>;
fn document_get_metadata(&self, id: &DocumentId) -> Result<DocumentMetadataResult>;
fn document_get_id_from_bytes(&self, encrypted_document: &[u8]) -> Result<DocumentId>;
fn document_encrypt(
&mut self,
document_data: &[u8],
encrypt_opts: &DocumentEncryptOpts,
) -> Result<DocumentEncryptResult>;
fn document_update_bytes(
&mut self,
id: &DocumentId,
new_document_data: &[u8],
) -> Result<DocumentEncryptResult>;
fn document_decrypt(&mut self, encrypted_document: &[u8]) -> Result<DocumentDecryptResult>;
fn document_update_name(
&self,
id: &DocumentId,
name: Option<&DocumentName>,
) -> Result<DocumentMetadataResult>;
fn document_grant_access(
&mut self,
document_id: &DocumentId,
grant_list: &Vec<UserOrGroup>,
) -> Result<DocumentAccessResult>;
fn document_revoke_access(
&self,
document_id: &DocumentId,
revoke_list: &Vec<UserOrGroup>,
) -> Result<DocumentAccessResult>;
}
impl DocumentOps for crate::IronOxide {
fn document_list(&self) -> Result<DocumentListResult> {
let mut rt = Runtime::new().unwrap();
rt.block_on(document_api::document_list(self.device.auth()))
}
fn document_get_metadata(&self, id: &DocumentId) -> Result<DocumentMetadataResult> {
let mut rt = Runtime::new().unwrap();
rt.block_on(document_api::document_get_metadata(self.device.auth(), id))
}
fn document_get_id_from_bytes(&self, encrypted_document: &[u8]) -> Result<DocumentId> {
document_api::get_id_from_bytes(encrypted_document)
}
fn document_encrypt(
&mut self,
document_data: &[u8],
encrypt_opts: &DocumentEncryptOpts,
) -> Result<DocumentEncryptResult> {
let mut rt = Runtime::new().unwrap();
let encrypt_opts = encrypt_opts.clone();
let (user_grants, group_grants) = partition_user_or_group(&encrypt_opts.grants);
rt.block_on(document_api::encrypt_document(
self.device.auth(),
&mut self.recrypt,
&self.user_master_pub_key,
&mut self.rng,
document_data,
encrypt_opts.id,
encrypt_opts.name,
&user_grants,
&group_grants,
))
}
fn document_update_bytes(
&mut self,
id: &DocumentId,
new_document_data: &[u8],
) -> Result<DocumentEncryptResult> {
let mut rt = Runtime::new().unwrap();
rt.block_on(document_api::document_update_bytes(
self.device.auth(),
&mut self.recrypt,
self.device.private_device_key(),
&mut self.rng,
id,
&new_document_data,
))
}
fn document_decrypt(&mut self, encrypted_document: &[u8]) -> Result<DocumentDecryptResult> {
let mut rt = Runtime::new().unwrap();
rt.block_on(document_api::decrypt_document(
self.device.auth(),
&mut self.recrypt,
self.device.private_device_key(),
encrypted_document,
))
}
fn document_update_name(
&self,
id: &DocumentId,
name: Option<&DocumentName>,
) -> Result<DocumentMetadataResult> {
let mut rt = Runtime::new().unwrap();
rt.block_on(document_api::update_document_name(
self.device.auth(),
id,
name,
))
}
fn document_grant_access(
&mut self,
id: &DocumentId,
grant_list: &Vec<UserOrGroup>,
) -> Result<DocumentAccessResult> {
let mut rt = Runtime::new().unwrap();
let (users, groups) = partition_user_or_group(grant_list);
rt.block_on(document_api::document_grant_access(
self.device.auth(),
&mut self.recrypt,
id,
&self.user_master_pub_key,
&self.device.private_device_key(),
&users,
&groups,
))
}
fn document_revoke_access(
&self,
id: &DocumentId,
revoke_list: &Vec<UserOrGroup>,
) -> Result<DocumentAccessResult> {
let mut rt = Runtime::new().unwrap();
rt.block_on(document_api::document_revoke_access(
self.device.auth(),
id,
revoke_list,
))
}
}
fn partition_user_or_group(uog_slice: &[UserOrGroup]) -> (Vec<UserId>, Vec<GroupId>) {
uog_slice
.into_iter()
.partition_map(|access_grant| match access_grant {
UserOrGroup::User { id } => Either::Left(id.clone()),
UserOrGroup::Group { id } => Either::Right(id.clone()),
})
}