pub use crate::internal::{
document_api::{
AssociationType, DocAccessEditErr, DocumentAccessResult, DocumentDecryptResult,
DocumentDecryptUnmanagedResult, DocumentEncryptResult, DocumentEncryptUnmanagedResult,
DocumentId, DocumentListMeta, DocumentListResult, DocumentMetadataResult, DocumentName,
UserOrGroup, VisibleGroup, VisibleUser,
},
group_api::{
GroupAccessEditErr, GroupAccessEditResult, GroupCreateResult, GroupGetResult, GroupId,
GroupListResult, GroupMetaResult, GroupName, GroupUpdatePrivateKeyResult,
},
user_api::{
DeviceId, EncryptedPrivateKey, UserCreateResult, UserDevice, UserDeviceListResult, UserId,
UserResult, UserUpdatePrivateKeyResult,
},
};
use crate::{
config::IronOxideConfig,
document::{advanced::DocumentAdvancedOps, DocumentEncryptOpts, DocumentOps},
group::{GroupCreateOpts, GroupOps},
user::{DeviceCreateOpts, UserCreateOpts, UserOps},
DeviceAddResult, DeviceContext,
InitAndRotationCheck::{self, NoRotationNeeded, RotationNeeded},
IronOxide, PrivateKeyRotationCheckResult, PublicKey, Result,
};
use futures::executor::block_on;
use std::collections::HashMap;
#[derive(Debug)]
pub struct BlockingIronOxide {
pub(crate) ironoxide: IronOxide,
pub(crate) runtime: tokio::runtime::Runtime,
}
impl BlockingIronOxide {
pub fn device(&self) -> &DeviceContext {
&self.ironoxide.device
}
pub fn rotate_all(
&self,
rotations: &PrivateKeyRotationCheckResult,
password: &str,
timeout: Option<std::time::Duration>,
) -> Result<(
Option<UserUpdatePrivateKeyResult>,
Option<Vec<GroupUpdatePrivateKeyResult>>,
)> {
self.runtime
.enter(|| block_on(self.ironoxide.rotate_all(rotations, password, timeout)))
}
pub fn document_list(&self) -> Result<DocumentListResult> {
self.runtime
.enter(|| block_on(self.ironoxide.document_list()))
}
pub fn document_get_metadata(&self, id: &DocumentId) -> Result<DocumentMetadataResult> {
self.runtime
.enter(|| block_on(self.ironoxide.document_get_metadata(id)))
}
pub fn document_get_id_from_bytes(&self, encrypted_document: &[u8]) -> Result<DocumentId> {
self.ironoxide
.document_get_id_from_bytes(encrypted_document)
}
pub fn document_encrypt(
&self,
document_data: &[u8],
encrypt_opts: &DocumentEncryptOpts,
) -> Result<DocumentEncryptResult> {
self.runtime
.enter(|| block_on(self.ironoxide.document_encrypt(document_data, encrypt_opts)))
}
pub fn document_update_bytes(
&self,
id: &DocumentId,
new_document_data: &[u8],
) -> Result<DocumentEncryptResult> {
self.runtime
.enter(|| block_on(self.ironoxide.document_update_bytes(id, new_document_data)))
}
pub fn document_decrypt(&self, encrypted_document: &[u8]) -> Result<DocumentDecryptResult> {
self.runtime
.enter(|| block_on(self.ironoxide.document_decrypt(encrypted_document)))
}
pub fn document_update_name(
&self,
id: &DocumentId,
name: Option<&DocumentName>,
) -> Result<DocumentMetadataResult> {
self.runtime
.enter(|| block_on(self.ironoxide.document_update_name(id, name)))
}
pub fn document_grant_access(
&self,
id: &DocumentId,
grant_list: &Vec<UserOrGroup>,
) -> Result<DocumentAccessResult> {
self.runtime
.enter(|| block_on(self.ironoxide.document_grant_access(id, grant_list)))
}
pub fn document_revoke_access(
&self,
id: &DocumentId,
revoke_list: &Vec<UserOrGroup>,
) -> Result<DocumentAccessResult> {
self.runtime
.enter(|| block_on(self.ironoxide.document_revoke_access(id, revoke_list)))
}
pub fn document_encrypt_unmanaged(
&self,
data: &[u8],
encrypt_opts: &DocumentEncryptOpts,
) -> Result<DocumentEncryptUnmanagedResult> {
self.runtime.enter(|| {
block_on(
self.ironoxide
.document_encrypt_unmanaged(data, encrypt_opts),
)
})
}
pub fn document_decrypt_unmanaged(
&self,
encrypted_data: &[u8],
encrypted_deks: &[u8],
) -> Result<DocumentDecryptUnmanagedResult> {
self.runtime.enter(|| {
block_on(
self.ironoxide
.document_decrypt_unmanaged(encrypted_data, encrypted_deks),
)
})
}
pub fn group_list(&self) -> Result<GroupListResult> {
self.runtime.enter(|| block_on(self.ironoxide.group_list()))
}
pub fn group_create(&self, opts: &GroupCreateOpts) -> Result<GroupCreateResult> {
self.runtime
.enter(|| block_on(self.ironoxide.group_create(opts)))
}
pub fn group_get_metadata(&self, id: &GroupId) -> Result<GroupGetResult> {
self.runtime
.enter(|| block_on(self.ironoxide.group_get_metadata(id)))
}
pub fn group_delete(&self, id: &GroupId) -> Result<GroupId> {
self.runtime
.enter(|| block_on(self.ironoxide.group_delete(id)))
}
pub fn group_update_name(
&self,
id: &GroupId,
name: Option<&GroupName>,
) -> Result<GroupMetaResult> {
self.runtime
.enter(|| block_on(self.ironoxide.group_update_name(id, name)))
}
pub fn group_add_members(
&self,
id: &GroupId,
grant_list: &[UserId],
) -> Result<GroupAccessEditResult> {
self.runtime
.enter(|| block_on(self.ironoxide.group_add_members(id, grant_list)))
}
pub fn group_remove_members(
&self,
id: &GroupId,
revoke_list: &[UserId],
) -> Result<GroupAccessEditResult> {
self.runtime
.enter(|| block_on(self.ironoxide.group_remove_members(id, revoke_list)))
}
pub fn group_add_admins(
&self,
id: &GroupId,
users: &[UserId],
) -> Result<GroupAccessEditResult> {
self.runtime
.enter(|| block_on(self.ironoxide.group_add_admins(id, users)))
}
pub fn group_remove_admins(
&self,
id: &GroupId,
revoke_list: &[UserId],
) -> Result<GroupAccessEditResult> {
self.runtime
.enter(|| block_on(self.ironoxide.group_remove_admins(id, revoke_list)))
}
pub fn group_rotate_private_key(&self, id: &GroupId) -> Result<GroupUpdatePrivateKeyResult> {
self.runtime
.enter(|| block_on(self.ironoxide.group_rotate_private_key(id)))
}
pub fn user_create(
jwt: &str,
password: &str,
user_create_opts: &UserCreateOpts,
timeout: Option<std::time::Duration>,
) -> Result<UserCreateResult> {
let rt = create_runtime();
rt.enter(|| {
block_on(IronOxide::user_create(
jwt,
password,
user_create_opts,
timeout,
))
})
}
pub fn user_list_devices(&self) -> Result<UserDeviceListResult> {
self.runtime
.enter(|| block_on(self.ironoxide.user_list_devices()))
}
pub fn generate_new_device(
jwt: &str,
password: &str,
device_create_options: &DeviceCreateOpts,
timeout: Option<std::time::Duration>,
) -> Result<DeviceAddResult> {
let rt = create_runtime();
rt.enter(|| {
block_on(IronOxide::generate_new_device(
jwt,
password,
device_create_options,
timeout,
))
})
}
pub fn user_delete_device(&self, device_id: Option<&DeviceId>) -> Result<DeviceId> {
self.runtime
.enter(|| block_on(self.ironoxide.user_delete_device(device_id)))
}
pub fn user_verify(
jwt: &str,
timeout: Option<std::time::Duration>,
) -> Result<Option<UserResult>> {
let rt = create_runtime();
rt.enter(|| block_on(IronOxide::user_verify(jwt, timeout)))
}
pub fn user_get_public_key(&self, users: &[UserId]) -> Result<HashMap<UserId, PublicKey>> {
self.runtime
.enter(|| block_on(self.ironoxide.user_get_public_key(users)))
}
pub fn user_rotate_private_key(&self, password: &str) -> Result<UserUpdatePrivateKeyResult> {
self.runtime
.enter(|| block_on(self.ironoxide.user_rotate_private_key(password)))
}
}
fn create_runtime() -> tokio::runtime::Runtime {
tokio::runtime::Builder::new()
.threaded_scheduler()
.enable_all()
.max_threads(250)
.build()
.expect("tokio runtime failed to initialize")
}
pub fn initialize(
device_context: &DeviceContext,
config: &IronOxideConfig,
) -> Result<BlockingIronOxide> {
let rt = create_runtime();
let maybe_io = rt.enter(|| block_on(crate::initialize(device_context, config)));
maybe_io.map(|io| BlockingIronOxide {
ironoxide: io,
runtime: rt,
})
}
pub fn initialize_check_rotation(
device_context: &DeviceContext,
config: &IronOxideConfig,
) -> Result<InitAndRotationCheck<BlockingIronOxide>> {
let rt = create_runtime();
let maybe_init =
rt.enter(|| block_on(crate::initialize_check_rotation(device_context, config)));
maybe_init.map(|init| match init {
NoRotationNeeded(io) => NoRotationNeeded(BlockingIronOxide {
ironoxide: io,
runtime: rt,
}),
RotationNeeded(io, rot) => RotationNeeded(
BlockingIronOxide {
ironoxide: io,
runtime: rt,
},
rot,
),
})
}