@@ -1086,15 +1086,21 @@ where
1086
1086
index : u32 ,
1087
1087
authenticated_data : Vec < u8 > ,
1088
1088
) -> Result < MlsMessage , MlsError > {
1089
+ let proposal = self . server_remove_proposal ( index) ?;
1090
+ self . proposal_message ( proposal, authenticated_data) . await
1091
+ }
1092
+
1093
+ #[ cfg( feature = "server_remove_proposal" ) ]
1094
+ #[ cfg_attr( feature = "ffi" , safer_ffi_gen:: safer_ffi_gen_ignore) ]
1095
+ fn server_remove_proposal ( & self , index : u32 ) -> Result < Proposal , MlsError > {
1089
1096
let leaf_index = LeafIndex ( index) ;
1090
1097
1091
1098
// Verify that this leaf is actually in the tree
1092
1099
self . current_epoch_tree ( ) . get_leaf_node ( leaf_index) ?;
1093
1100
1094
- let proposal = Proposal :: ServerRemove ( ServerRemoveProposal {
1101
+ Ok ( Proposal :: ServerRemove ( ServerRemoveProposal {
1095
1102
to_remove : leaf_index,
1096
- } ) ;
1097
- self . proposal_message ( proposal, authenticated_data) . await
1103
+ } ) )
1098
1104
}
1099
1105
1100
1106
/// Create a proposal message that adds an external pre shared key to the group.
@@ -4621,6 +4627,37 @@ mod tests {
4621
4627
} ;
4622
4628
}
4623
4629
4630
+ #[ cfg( feature = "server_remove_proposal" ) ]
4631
+ #[ maybe_async:: test( not( mls_build_async) , async ( mls_build_async, crate :: futures_test) ) ]
4632
+ async fn server_remove_removes_client_by_value ( ) {
4633
+ let ( mut alice, mut bob) = custom_proposal_setup ( ProposalType :: SERVER_REMOVE ) . await ;
4634
+
4635
+ let commit_builder = alice. commit_builder ( ) ;
4636
+ let commit_builder = commit_builder. server_remove_member ( 1 ) . await . unwrap ( ) ;
4637
+ let commit = commit_builder. build ( ) . await . unwrap ( ) . commit_message ;
4638
+
4639
+ let ReceivedMessage :: Commit ( CommitMessageDescription {
4640
+ effect : CommitEffect :: NewEpoch ( new_epoch) ,
4641
+ ..
4642
+ } ) = alice
4643
+ . process_incoming_message ( commit. clone ( ) )
4644
+ . await
4645
+ . unwrap ( )
4646
+ else {
4647
+ panic ! ( "unexpected commit effect" ) ;
4648
+ } ;
4649
+
4650
+ assert_eq ! ( new_epoch. applied_proposals. len( ) , 1 ) ;
4651
+
4652
+ let ReceivedMessage :: Commit ( CommitMessageDescription {
4653
+ effect : CommitEffect :: Removed { .. } ,
4654
+ ..
4655
+ } ) = bob. process_incoming_message ( commit) . await . unwrap ( )
4656
+ else {
4657
+ panic ! ( "unexpected commit effect" ) ;
4658
+ } ;
4659
+ }
4660
+
4624
4661
#[ cfg( feature = "server_remove_proposal" ) ]
4625
4662
#[ maybe_async:: test( not( mls_build_async) , async ( mls_build_async, crate :: futures_test) ) ]
4626
4663
async fn commit_with_both_remove_and_server_remove_for_same_client_leaves_server_remove_unused ( )
0 commit comments