#![cfg(feature = "extensions-draft-08")]
use openmls::{component::ComponentId, prelude::*, test_utils::single_group_test_framework::*};
#[openmls_test::openmls_test]
fn app_ephemeral_proposals() {
const COMPONENT_ID: ComponentId = 1;
const DATA: &[u8] = b"data";
let group_id = GroupId::from_slice(b"Test Group");
let alice_provider = &Provider::default();
let bob_provider = &Provider::default();
let capabilities =
Capabilities::new(None, None, None, Some(&[ProposalType::AppEphemeral]), None);
let mls_group_create_config = MlsGroupCreateConfig::builder()
.ciphersuite(ciphersuite)
.use_ratchet_tree_extension(true)
.capabilities(capabilities.clone())
.build();
let (alice_credential, alice_signer) = generate_credential(
b"Alice".to_vec(),
ciphersuite.signature_algorithm(),
alice_provider,
);
let (bob_credential, bob_signer) = generate_credential(
b"Bob".to_vec(),
ciphersuite.signature_algorithm(),
bob_provider,
);
let bob_key_package = KeyPackage::builder()
.leaf_node_capabilities(capabilities)
.build(ciphersuite, bob_provider, &bob_signer, bob_credential)
.unwrap();
let mut alice_group = MlsGroup::new_with_group_id(
alice_provider,
&alice_signer,
&mls_group_create_config,
group_id,
alice_credential.clone(),
)
.expect("An unexpected error occurred.");
let welcome = match alice_group.add_members(
alice_provider,
&alice_signer,
&[bob_key_package.key_package().clone()],
) {
Ok((_, welcome, _)) => welcome,
Err(e) => panic!("Could not add member to group: {e:?}"),
};
alice_group.merge_pending_commit(alice_provider).unwrap();
let welcome: MlsMessageIn = welcome.into();
let welcome = welcome
.into_welcome()
.expect("expected the message to be a welcome message");
let mut bob_group = StagedWelcome::new_from_welcome(
bob_provider,
mls_group_create_config.join_config(),
welcome,
Some(alice_group.export_ratchet_tree().into()),
)
.expect("Error creating StagedWelcome from Welcome")
.into_group(bob_provider)
.expect("Error creating group from StagedWelcome");
let message_bundle = alice_group
.commit_builder()
.add_proposals(vec![Proposal::AppEphemeral(Box::new(
AppEphemeralProposal::new(COMPONENT_ID, DATA.into()),
))])
.load_psks(alice_provider.storage())
.expect("error loading psks")
.build(
alice_provider.rand(),
alice_provider.crypto(),
&alice_signer,
|_| true,
)
.expect("error validating data and building commit")
.stage_commit(alice_provider)
.expect("error staging commit");
let alice_pending_commit = alice_group.pending_commit().expect("no pending commit");
assert_eq!(
alice_pending_commit
.staged_proposal_queue
.app_ephemeral_proposals_for_component_id(COMPONENT_ID)
.count(),
1
);
let (mls_message_out, _, _) = message_bundle.into_contents();
let protocol_message = MlsMessageIn::from(mls_message_out)
.try_into_protocol_message()
.unwrap();
let processed_message = bob_group
.process_message(bob_provider, protocol_message)
.expect("could not process message");
let bob_staged_commit = match processed_message.into_content() {
ProcessedMessageContent::StagedCommitMessage(commit) => commit,
_ => panic!("incorrect message type"),
};
assert_eq!(
bob_staged_commit
.staged_proposal_queue
.app_ephemeral_proposals_for_component_id(COMPONENT_ID)
.count(),
1
);
let component_ids = bob_staged_commit
.staged_proposal_queue
.unique_component_ids_for_app_ephemeral();
assert_eq!(component_ids, vec![COMPONENT_ID]);
for queued_proposal in bob_staged_commit
.staged_proposal_queue
.app_ephemeral_proposals_for_component_id(COMPONENT_ID)
{
let proposal = queued_proposal.app_ephemeral_proposal();
assert_eq!(proposal.data(), DATA);
}
}