mod common;
use crate::common::init_sdk_get_user;
use common::{create_second_user, init_sdk};
use galvanic_assert::matchers::{collection::*, *};
use ironoxide::{document::*, group::GroupCreateOpts, prelude::*};
use itertools::EitherOrBoth;
use std::convert::{TryFrom, TryInto};
#[cfg(test)]
#[macro_use]
extern crate galvanic_assert;
#[macro_use]
extern crate serde_json;
#[test]
fn doc_create_without_id() {
let mut sdk = init_sdk();
let doc = [0u8; 64];
let doc_result = sdk.document_encrypt(&doc, &Default::default());
assert!(doc_result.is_ok());
let doc_result = doc_result.unwrap();
assert_eq!(doc_result.grants().len(), 1); assert_eq!(doc_result.access_errs().len(), 0);
}
#[test]
fn doc_create_with_policy_grants() -> Result<(), IronOxideErr> {
let (curr_user, mut sdk) = init_sdk_get_user();
let data_rec_group_id: GroupId = format!("data_recovery_{}", curr_user.id())
.try_into()
.unwrap();
let group_result = sdk.group_create(&GroupCreateOpts::new(
data_rec_group_id.clone().into(),
None,
true,
));
assert!(group_result.is_ok());
let doc = [0u8; 64];
let doc_result = sdk
.document_encrypt(
&doc,
&DocumentEncryptOpts::with_policy_grants(
None,
Some("doc name".try_into()?),
PolicyGrant::new(
Some("PII".try_into()?),
Some("INTERNAL".try_into()?),
None,
None,
),
),
)
.unwrap();
assert_eq!(doc_result.grants().len(), 2);
assert_that!(
&doc_result
.grants()
.iter()
.map(Clone::clone)
.collect::<Vec<UserOrGroup>>(),
contains_in_any_order(vec![
UserOrGroup::User {
id: sdk.device().account_id().clone()
},
UserOrGroup::Group {
id: data_rec_group_id.clone()
}
])
);
assert_eq!(doc_result.access_errs().len(), 2);
assert_that!(
&doc_result
.access_errs()
.iter()
.map(|err| err.user_or_group.clone())
.collect::<Vec<_>>(),
contains_in_any_order(vec![
UserOrGroup::Group {
id: "badgroupid_frompolicy".try_into().unwrap()
},
UserOrGroup::User {
id: "baduserid_frompolicy".try_into().unwrap()
}
])
);
let user2_result = create_second_user();
let user2 = user2_result.account_id();
let group2_id: GroupId = format!("group_other_{}", user2.id()).try_into().unwrap();
let group2_result =
sdk.group_create(&GroupCreateOpts::new(group2_id.clone().into(), None, false));
assert!(group2_result.is_ok());
let doc_result2 = sdk
.document_encrypt(
&doc,
&DocumentEncryptOpts::with_policy_grants(
None,
Some("doc name2".try_into()?),
PolicyGrant::new(
Some("HEALTH".try_into()?),
Some("RESTRICTED".try_into()?),
Some("PATIENT".try_into()?),
Some(user2.clone()),
),
),
)
.unwrap();
assert_eq!(doc_result2.grants().len(), 3);
assert_that!(
&doc_result2
.grants()
.iter()
.map(Clone::clone)
.collect::<Vec<UserOrGroup>>(),
contains_in_any_order(vec![
UserOrGroup::User { id: user2.clone() },
UserOrGroup::Group { id: group2_id },
UserOrGroup::Group {
id: data_rec_group_id.clone()
}
])
);
assert_eq!(doc_result2.access_errs().len(), 1);
assert_that!(
&doc_result2
.access_errs()
.iter()
.map(|err| err.user_or_group.clone())
.collect::<Vec<_>>(),
contains_in_any_order(vec![UserOrGroup::Group {
id: "group_id_doctors".try_into().unwrap()
},])
);
let doc_result3 = sdk
.document_encrypt(
&doc,
&DocumentEncryptOpts::with_policy_grants(
None,
Some("doc name2".try_into()?),
PolicyGrant::default(),
),
)
.unwrap();
assert_eq!(doc_result3.grants().len(), 1);
Ok(())
}
#[test]
fn doc_create_with_explicit_grants() {
let mut sdk = init_sdk();
let doc = [0u8; 64];
let bad_user: UserId = "bad_user".try_into().unwrap();
let bad_group: GroupId = "bad_group".try_into().unwrap();
let doc_result = sdk
.document_encrypt(
&doc,
&DocumentEncryptOpts::with_explicit_grants(
None,
Some("first name".try_into().unwrap()),
true,
vec![
UserOrGroup::User {
id: bad_user.clone(),
},
UserOrGroup::Group {
id: bad_group.clone(),
},
],
),
)
.unwrap();
assert_eq!(doc_result.grants().len(), 1);
assert_eq!(
doc_result.grants()[0],
UserOrGroup::User {
id: sdk.device().account_id().clone()
}
);
assert_eq!(doc_result.access_errs().len(), 2);
assert_that!(
&doc_result
.access_errs()
.iter()
.map(|err| err.user_or_group.clone())
.collect::<Vec<_>>(),
contains_in_any_order(vec![
UserOrGroup::User { id: bad_user },
UserOrGroup::Group { id: bad_group }
])
)
}
#[test]
fn doc_create_with_explicit_and_policy_grants() -> Result<(), IronOxideErr> {
use std::borrow::Borrow;
let (curr_user, mut sdk) = init_sdk_get_user();
let data_rec_group_id: GroupId = format!("data_recovery_{}", curr_user.id())
.try_into()
.unwrap();
let group_result = sdk.group_create(&GroupCreateOpts::new(
data_rec_group_id.clone().into(),
None,
true,
));
assert!(group_result.is_ok());
let group2_result = sdk.group_create(&Default::default());
assert!(group2_result.is_ok());
let group2 = group2_result?;
let ex_group_id = group2.id();
let doc = [0u8; 64];
let bad_group: GroupId = "bad_group".try_into().unwrap();
let doc_result = sdk
.document_encrypt(
&doc,
&DocumentEncryptOpts::new(
None,
None,
EitherOrBoth::Both(
ExplicitGrant::new(true, &vec![ex_group_id.into(), bad_group.borrow().into()]),
PolicyGrant::new(
Some("PII".try_into()?),
Some("INTERNAL".try_into()?),
None,
None,
),
),
),
)
.unwrap();
assert_eq!(doc_result.grants().len(), 3);
assert_that!(
&doc_result
.grants()
.iter()
.map(Clone::clone)
.collect::<Vec<UserOrGroup>>(),
contains_in_any_order(vec![
UserOrGroup::User {
id: sdk.device().account_id().clone()
},
UserOrGroup::Group {
id: data_rec_group_id.clone()
},
UserOrGroup::Group {
id: ex_group_id.clone()
}
])
);
assert_eq!(doc_result.access_errs().len(), 3);
assert_that!(
&doc_result
.access_errs()
.iter()
.map(|err| err.user_or_group.clone())
.collect::<Vec<_>>(),
contains_in_any_order(vec![
UserOrGroup::Group {
id: "badgroupid_frompolicy".try_into().unwrap()
},
UserOrGroup::User {
id: "baduserid_frompolicy".try_into().unwrap()
},
UserOrGroup::Group { id: bad_group } ])
);
Ok(())
}
#[test]
fn doc_create_duplicate_grants() {
let (user, mut sdk) = init_sdk_get_user();
let doc = [0u8; 64];
let doc_result = sdk
.document_encrypt(
&doc,
&DocumentEncryptOpts::with_explicit_grants(
None,
Some("first name".try_into().unwrap()),
true,
vec![UserOrGroup::User { id: user }],
),
)
.unwrap();
assert_that!(&doc_result.grants().len(), eq(1))
}
#[test]
fn doc_create_without_self_grant() {
let mut sdk = init_sdk();
let doc = [0u8; 64];
let second_user = create_second_user();
let doc_result = sdk
.document_encrypt(
&doc,
&DocumentEncryptOpts::with_explicit_grants(
None,
Some("first name".try_into().unwrap()),
false,
vec![UserOrGroup::User {
id: second_user.account_id().clone(),
}],
),
)
.unwrap();
assert_eq!(doc_result.grants().len(), 1);
assert_ne!(
doc_result.grants()[0],
UserOrGroup::User {
id: sdk.device().account_id().clone()
}
);
assert_eq!(
doc_result.grants()[0],
UserOrGroup::User {
id: second_user.account_id().clone()
}
);
assert_eq!(doc_result.access_errs().len(), 0);
}
#[test]
fn doc_create_must_grant() {
let mut sdk = init_sdk();
let doc = [0u8; 64];
let doc_result = sdk.document_encrypt(
&doc,
&DocumentEncryptOpts::with_explicit_grants(
None,
Some("first name".try_into().unwrap()),
false,
vec![],
),
);
assert_eq!(
match doc_result.err().unwrap() {
IronOxideErr::ValidationError(field_name, _) => field_name,
_ => "failed test".to_string(),
},
"grants".to_string()
)
}
#[test]
fn doc_create_and_adjust_name() {
let mut sdk = init_sdk();
let doc = [0u8; 64];
let doc_result = sdk
.document_encrypt(
&doc,
&DocumentEncryptOpts::with_explicit_grants(
None,
Some("first name".try_into().unwrap()),
true,
vec![UserOrGroup::User {
id: UserId::try_from("bad-user").expect("should be good id"),
}],
),
)
.unwrap();
assert_eq!(doc_result.name().unwrap().name(), &"first name".to_string());
let first_update = sdk
.document_update_name(&doc_result.id(), Some(&"second name".try_into().unwrap()))
.unwrap();
assert_eq!(
first_update.name().unwrap().name(),
&"second name".to_string()
);
let last_update = sdk.document_update_name(&doc_result.id(), None).unwrap();
assert!(last_update.name().is_none());
}
#[test]
fn doc_decrypt_roundtrip() {
let mut sdk = init_sdk();
let doc = [43u8; 64];
let encrypted_doc = sdk.document_encrypt(&doc, &Default::default()).unwrap();
sdk.document_get_metadata(&encrypted_doc.id()).unwrap();
let decrypted = sdk
.document_decrypt(&encrypted_doc.encrypted_data())
.unwrap();
assert_eq!(doc.to_vec(), decrypted.decrypted_data());
}
#[test]
fn doc_encrypt_update_and_decrypt() {
let mut sdk = init_sdk();
let doc1 = [20u8; 72];
let encrypted_doc = sdk.document_encrypt(&doc1, &Default::default()).unwrap();
let doc_id = &encrypted_doc.id();
let doc2 = [10u8; 11];
let updated_encrypted_doc = sdk.document_update_bytes(doc_id, &doc2).unwrap();
let decrypted = sdk
.document_decrypt(&updated_encrypted_doc.encrypted_data())
.unwrap();
assert_eq!(doc2.to_vec(), decrypted.decrypted_data());
}
#[test]
fn doc_grant_access() {
let mut sdk = init_sdk();
let doc = [0u8; 64];
let doc_result = sdk.document_encrypt(&doc, &Default::default());
assert!(doc_result.is_ok());
let doc_id = doc_result.unwrap().id().clone();
let user = create_second_user();
let group_result = sdk.group_create(&Default::default());
assert!(group_result.is_ok());
let group_id = group_result.unwrap().id().clone();
let group2_result = sdk.group_create(&GroupCreateOpts::new(None, None, false));
assert!(group2_result.is_ok());
let group2_id = group2_result.unwrap().id().clone();
let grant_result = sdk.document_grant_access(
&doc_id,
&vec![
UserOrGroup::User {
id: user.account_id().clone(),
},
UserOrGroup::Group { id: group_id },
UserOrGroup::Group { id: group2_id },
UserOrGroup::User {
id: "bad-user-id".try_into().unwrap(),
},
UserOrGroup::Group {
id: "bad-group-id".try_into().unwrap(),
},
],
);
dbg!(&grant_result);
assert!(grant_result.is_ok());
let grants = grant_result.unwrap();
assert_eq!(3, grants.succeeded().len());
assert_eq!(2, grants.failed().len());
}
#[test]
fn doc_revoke_access() {
let mut sdk = init_sdk();
let doc = [0u8; 64];
let doc_result = sdk.document_encrypt(&doc, &Default::default());
assert!(doc_result.is_ok());
let doc_id = doc_result.unwrap().id().clone();
let user = create_second_user();
let group_result = sdk.group_create(&Default::default());
assert!(group_result.is_ok());
let group_id = group_result.unwrap().id().clone();
let grant_result = sdk.document_grant_access(
&doc_id,
&vec![
UserOrGroup::User {
id: user.account_id().clone(),
},
UserOrGroup::Group {
id: group_id.clone(),
},
],
);
assert!(grant_result.is_ok());
let grants = grant_result.unwrap();
assert_eq!(grants.succeeded().len(), 2);
let revoke_result = sdk.document_revoke_access(
&doc_id,
&vec![
UserOrGroup::User {
id: user.account_id().clone(),
},
UserOrGroup::Group {
id: group_id.clone(),
},
UserOrGroup::User {
id: "bad-user-id".try_into().unwrap(),
},
UserOrGroup::Group {
id: "bad-group-id".try_into().unwrap(),
},
],
);
assert!(revoke_result.is_ok());
let revokes = revoke_result.unwrap();
assert_eq!(revokes.succeeded().len(), 2);
assert_eq!(revokes.failed().len(), 2)
}