From fc88888391853365165063a0e8a69b2a98406fe9 Mon Sep 17 00:00:00 2001 From: Nicholas Molnar <65710+neekolas@users.noreply.github.com> Date: Mon, 20 May 2024 13:23:10 -0700 Subject: [PATCH 1/4] Add new update_group_membership --- openmls/src/group/mls_group/membership.rs | 66 +++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/openmls/src/group/mls_group/membership.rs b/openmls/src/group/mls_group/membership.rs index b22c723ed..5f93552c9 100644 --- a/openmls/src/group/mls_group/membership.rs +++ b/openmls/src/group/mls_group/membership.rs @@ -15,6 +15,72 @@ use crate::{ }; impl MlsGroup { + /// Updates the group membership using only inline proposals. + /// Adds and removes members and updates the group context. + pub fn update_group_membership( + &mut self, + provider: &impl OpenMlsProvider, + signer: &impl Signer, + key_packages_to_add: &[KeyPackage], + leaf_nodes_to_remove: &[LeafNodeIndex], + new_extensions: Extensions, + ) -> Result< + (MlsMessageOut, Option, Option), + AddMembersError, + > { + self.is_operational()?; + + // Create inline add proposals from any provided key packages + let add_proposals = key_packages_to_add + .iter() + .map(|key_package| { + Proposal::Add(AddProposal { + key_package: key_package.clone(), + }) + }) + .collect::>(); + + let extensions_proposals = vec![Proposal::GroupContextExtensions( + GroupContextExtensionProposal { + extensions: new_extensions, + }, + )]; + + let mut remove_proposals = Vec::new(); + for member in leaf_nodes_to_remove.iter() { + remove_proposals.push(Proposal::Remove(RemoveProposal { removed: *member })) + } + + let proposals = [add_proposals, extensions_proposals, remove_proposals].concat(); + + let params = CreateCommitParams::builder() + .framing_parameters(self.framing_parameters()) + .proposal_store(&self.proposal_store) + .inline_proposals(proposals) + .build(); + let create_commit_result = self.group.create_commit(params, provider, signer)?; + + // Convert PublicMessage messages to MLSMessage and encrypt them if required by + // the configuration + let mls_messages = self.content_to_mls_message(create_commit_result.commit, provider)?; + + // Set the current group state to [`MlsGroupState::PendingCommit`], + // storing the current [`StagedCommit`] from the commit results + self.group_state = MlsGroupState::PendingCommit(Box::new(PendingCommitState::Member( + create_commit_result.staged_commit, + ))); + + // Since the state of the group might be changed, arm the state flag + self.flag_state_change(); + + Ok(( + mls_messages, + create_commit_result + .welcome_option + .map(|w| MlsMessageOut::from_welcome(w, self.group.version())), + create_commit_result.group_info, + )) + } /// Adds members to the group. /// /// New members are added by providing a `KeyPackage` for each member. From 9f3cad8c6c434f4860bd4f120451558e8d6293ce Mon Sep 17 00:00:00 2001 From: Nicholas Molnar <65710+neekolas@users.noreply.github.com> Date: Tue, 21 May 2024 13:39:02 -0700 Subject: [PATCH 2/4] Add UpdateGroupMembership --- openmls/src/group/mls_group/errors.rs | 19 +++++++++++++++++++ openmls/src/group/mls_group/membership.rs | 12 +++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/openmls/src/group/mls_group/errors.rs b/openmls/src/group/mls_group/errors.rs index abf94bdbe..c40017911 100644 --- a/openmls/src/group/mls_group/errors.rs +++ b/openmls/src/group/mls_group/errors.rs @@ -212,6 +212,25 @@ pub enum RemoveMembersError { StorageError(StorageError), } +#[derive(Error, Debug, PartialEq, Clone)] +pub enum UpdateGroupMembershipError { + /// See [`LibraryError`] for more details. + #[error(transparent)] + LibraryError(#[from] LibraryError), + /// See [`CreateCommitError`] for more details. + #[error(transparent)] + CreateCommitError(#[from] CreateCommitError), + /// See [`MlsGroupStateError`] for more details. + #[error(transparent)] + GroupStateError(#[from] MlsGroupStateError), + /// The member that should be removed can not be found. + #[error("The member that should be removed can not be found.")] + UnknownMember, + /// Error writing to storage + #[error("Error writing to storage: {0}")] + StorageError(StorageError), +} + /// Leave group error #[derive(Error, Debug, PartialEq, Clone)] pub enum LeaveGroupError { diff --git a/openmls/src/group/mls_group/membership.rs b/openmls/src/group/mls_group/membership.rs index 5f93552c9..473699a7d 100644 --- a/openmls/src/group/mls_group/membership.rs +++ b/openmls/src/group/mls_group/membership.rs @@ -17,16 +17,16 @@ use crate::{ impl MlsGroup { /// Updates the group membership using only inline proposals. /// Adds and removes members and updates the group context. - pub fn update_group_membership( + pub fn update_group_membership( &mut self, - provider: &impl OpenMlsProvider, + provider: &Provider, signer: &impl Signer, key_packages_to_add: &[KeyPackage], leaf_nodes_to_remove: &[LeafNodeIndex], new_extensions: Extensions, ) -> Result< (MlsMessageOut, Option, Option), - AddMembersError, + UpdateGroupMembershipError, > { self.is_operational()?; @@ -70,8 +70,10 @@ impl MlsGroup { create_commit_result.staged_commit, ))); - // Since the state of the group might be changed, arm the state flag - self.flag_state_change(); + provider + .storage() + .write_group_state(self.group_id(), &self.group_state) + .map_err(UpdateGroupMembershipError::StorageError)?; Ok(( mls_messages, From 74256d6eb85dd793779a52896afba1a0467c664e Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Fri, 24 May 2024 11:15:23 -0700 Subject: [PATCH 3/4] Update errors.rs --- openmls/src/group/mls_group/errors.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/openmls/src/group/mls_group/errors.rs b/openmls/src/group/mls_group/errors.rs index c40017911..888f57b2a 100644 --- a/openmls/src/group/mls_group/errors.rs +++ b/openmls/src/group/mls_group/errors.rs @@ -212,6 +212,7 @@ pub enum RemoveMembersError { StorageError(StorageError), } +/// Update group membership error #[derive(Error, Debug, PartialEq, Clone)] pub enum UpdateGroupMembershipError { /// See [`LibraryError`] for more details. From 8dd6a5614b6ae14d104dba4656d089dee2e94c39 Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Fri, 24 May 2024 11:19:10 -0700 Subject: [PATCH 4/4] fix the clippy issue --- openmls/src/group/mls_group/membership.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/openmls/src/group/mls_group/membership.rs b/openmls/src/group/mls_group/membership.rs index 473699a7d..c1bf84b18 100644 --- a/openmls/src/group/mls_group/membership.rs +++ b/openmls/src/group/mls_group/membership.rs @@ -14,6 +14,11 @@ use crate::{ storage::OpenMlsProvider, treesync::LeafNode, }; +type UpdateResult = Result< + (MlsMessageOut, Option, Option), + UpdateGroupMembershipError<::StorageError>, +>; + impl MlsGroup { /// Updates the group membership using only inline proposals. /// Adds and removes members and updates the group context. @@ -24,10 +29,7 @@ impl MlsGroup { key_packages_to_add: &[KeyPackage], leaf_nodes_to_remove: &[LeafNodeIndex], new_extensions: Extensions, - ) -> Result< - (MlsMessageOut, Option, Option), - UpdateGroupMembershipError, - > { + ) -> UpdateResult { self.is_operational()?; // Create inline add proposals from any provided key packages