Skip to content

Commit

Permalink
Merge branch 'pilip/user-group-removal' into 'master'
Browse files Browse the repository at this point in the history
feat: Allow to remove members from group

See merge request TankerHQ/sdk-rust!51
  • Loading branch information
blastrock committed Jul 27, 2021
2 parents 402f93d + dee707e commit cd60f8e
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 7 deletions.
20 changes: 15 additions & 5 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ impl Core {
unsafe { ctanker::create_group(self.ctanker, &members).await }
}

/// Add members to an existing group.
/// Add or remove members from an existing group.
///
/// The Tanker status must be `Ready`.
///
Expand All @@ -277,21 +277,31 @@ impl Core {
/// # Arguments
/// * `group_id` - Group ID to modify
/// * `users_to_add` - Public identities of users to add to the group
pub async fn update_group_members<S, Iter>(
/// * `users_to_remove` - Public identities of users to remove from the group
pub async fn update_group_members<S, AddIter, RemoveIter>(
&self,
group_id: &str,
users_to_add: Iter,
users_to_add: AddIter,
users_to_remove: RemoveIter,
) -> Result<(), Error>
where
S: AsRef<str>,
Iter: IntoIterator<Item = S>,
AddIter: IntoIterator<Item = S>,
RemoveIter: IntoIterator<Item = S>,
{
let group_id = CString::new(group_id).unwrap();
let users_to_add: Vec<_> = users_to_add
.into_iter()
.map(|r| CString::new(r.as_ref()).unwrap())
.collect();
unsafe { ctanker::update_group_members(self.ctanker, &group_id, &users_to_add).await }
let users_to_remove: Vec<_> = users_to_remove
.into_iter()
.map(|r| CString::new(r.as_ref()).unwrap())
.collect();
unsafe {
ctanker::update_group_members(self.ctanker, &group_id, &users_to_add, &users_to_remove)
.await
}
}

/// Revokes one of the user's devices.
Expand Down
7 changes: 7 additions & 0 deletions src/ctanker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,15 +454,22 @@ pub async unsafe fn update_group_members(
ctanker: CTankerPtr,
group_id: &CStr,
users_to_add: &[CString],
users_to_remove: &[CString],
) -> Result<(), Error> {
let users_to_add = users_to_add.iter().map(|u| u.as_ptr()).collect::<Vec<_>>();
let users_to_remove = users_to_remove
.iter()
.map(|u| u.as_ptr())
.collect::<Vec<_>>();

let fut = unsafe {
CFuture::<c_void>::new(tanker_update_group_members(
ctanker,
group_id.as_ptr(),
users_to_add.as_ptr(),
users_to_add.len() as u64,
users_to_remove.as_ptr(),
users_to_remove.len() as u64,
))
};
fut.await.map(|_| ())
Expand Down
60 changes: 58 additions & 2 deletions tests/group_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,74 @@ async fn add_member_to_group() -> Result<(), Error> {

let group_id = alice.create_group(&[&alice_pub_id]).await?;

let msg = "Für wenst'd've hätten wir Hunger?".as_bytes();
let msg = b"<insert famous citation here>";
let encrypted = alice.encrypt(msg, &Default::default()).await?;
let resource_id = alice.get_resource_id(&encrypted)?;

let options = SharingOptions::new().share_with_groups(&[&group_id]);
alice.share(&[resource_id], &options).await?;

alice.update_group_members(&group_id, &[bob_pub_id]).await?;
alice
.update_group_members(&group_id, &[bob_pub_id], &[])
.await?;

assert_eq!(bob.decrypt(&encrypted).await?, msg);

alice.stop().await?;
bob.stop().await?;
Ok(())
}

#[tokio::test(flavor = "multi_thread")]
async fn remove_member_from_group() -> Result<(), Error> {
let app = TestApp::get().await;
let alice_id = app.create_identity(None);
let alice_pub_id = app.get_public_identity(&alice_id);
let alice = app.start_anonymous(&alice_id).await?;
let bob_id = app.create_identity(None);
let bob_pub_id = app.get_public_identity(&bob_id);
let bob = app.start_anonymous(&bob_id).await?;

let group_id = alice.create_group(&[&alice_pub_id, &bob_pub_id]).await?;

let msg = b"<insert famous citation here>";
let options = EncryptionOptions::new().share_with_groups(&[&group_id]);
let encrypted = alice.encrypt(msg, &options).await?;

assert_eq!(bob.decrypt(&encrypted).await?, msg);

alice
.update_group_members(&group_id, &[], &[bob_pub_id])
.await?;

let encrypted = alice.encrypt(msg, &options).await?;

let err = bob.decrypt(&encrypted).await.unwrap_err();
assert_eq!(err.code(), ErrorCode::InvalidArgument);

alice.stop().await?;
bob.stop().await?;
Ok(())
}

#[tokio::test(flavor = "multi_thread")]
async fn reject_empty_group_update() -> Result<(), Error> {
let app = TestApp::get().await;
let alice_id = app.create_identity(None);
let alice_pub_id = app.get_public_identity(&alice_id);
let alice = app.start_anonymous(&alice_id).await?;

let group_id = alice.create_group(&[&alice_pub_id]).await?;

let empty_vec = Vec::<String>::new();

let err = alice
.update_group_members(&group_id, &empty_vec, &empty_vec)
.await
.unwrap_err();
assert_eq!(err.code(), ErrorCode::InvalidArgument);

alice.stop().await?;

Ok(())
}

0 comments on commit cd60f8e

Please sign in to comment.