Skip to content

Commit bfdda64

Browse files
authored
Expose group metadata (#524)
1 parent 6e67f37 commit bfdda64

File tree

5 files changed

+112
-2
lines changed

5 files changed

+112
-2
lines changed

bindings_ffi/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ pub enum GenericError {
2626
GroupError(#[from] xmtp_mls::groups::GroupError),
2727
#[error("Signature: {0}")]
2828
Signature(#[from] xmtp_cryptography::signature::SignatureError),
29+
#[error("Group metadata: {0}")]
30+
GroupMetadata(#[from] xmtp_mls::groups::group_metadata::GroupMetadataError),
2931
#[error("Generic {err}")]
3032
Generic { err: String },
3133
}

bindings_ffi/src/mls.rs

+48
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ use tokio::sync::{oneshot, oneshot::Sender};
1212
use xmtp_api_grpc::grpc_api_helper::Client as TonicApiClient;
1313
use xmtp_mls::builder::IdentityStrategy;
1414
use xmtp_mls::builder::LegacyIdentity;
15+
use xmtp_mls::groups::group_metadata::ConversationType;
16+
use xmtp_mls::groups::group_metadata::GroupMetadata;
17+
use xmtp_mls::groups::PreconfiguredPolicies;
1518
use xmtp_mls::{
1619
builder::ClientBuilder,
1720
client::Client as MlsClient,
@@ -173,6 +176,15 @@ pub enum GroupPermissions {
173176
GroupCreatorIsAdmin,
174177
}
175178

179+
impl From<PreconfiguredPolicies> for GroupPermissions {
180+
fn from(policy: PreconfiguredPolicies) -> Self {
181+
match policy {
182+
PreconfiguredPolicies::EveryoneIsAdmin => GroupPermissions::EveryoneIsAdmin,
183+
PreconfiguredPolicies::GroupCreatorIsAdmin => GroupPermissions::GroupCreatorIsAdmin,
184+
}
185+
}
186+
}
187+
176188
#[uniffi::export(async_runtime = "tokio")]
177189
impl FfiConversations {
178190
pub async fn create_group(
@@ -443,6 +455,19 @@ impl FfiGroup {
443455

444456
Ok(group.is_active()?)
445457
}
458+
459+
pub fn group_metadata(&self) -> Result<Arc<FfiGroupMetadata>, GenericError> {
460+
let group = MlsGroup::new(
461+
self.inner_client.as_ref(),
462+
self.group_id.clone(),
463+
self.created_at_ns,
464+
);
465+
466+
let metadata = group.metadata()?;
467+
Ok(Arc::new(FfiGroupMetadata {
468+
inner: Arc::new(metadata),
469+
}))
470+
}
446471
}
447472

448473
#[uniffi::export]
@@ -507,6 +532,29 @@ pub trait FfiConversationCallback: Send + Sync {
507532
fn on_conversation(&self, conversation: Arc<FfiGroup>);
508533
}
509534

535+
#[derive(uniffi::Object)]
536+
pub struct FfiGroupMetadata {
537+
inner: Arc<GroupMetadata>,
538+
}
539+
540+
#[uniffi::export]
541+
impl FfiGroupMetadata {
542+
pub fn creator_account_address(&self) -> String {
543+
self.inner.creator_account_address.clone()
544+
}
545+
546+
pub fn conversation_type(&self) -> String {
547+
match self.inner.conversation_type {
548+
ConversationType::Group => "group".to_string(),
549+
ConversationType::Dm => "dm".to_string(),
550+
}
551+
}
552+
553+
pub fn policy_type(&self) -> Result<GroupPermissions, GenericError> {
554+
Ok(self.inner.preconfigured_policy()?.into())
555+
}
556+
}
557+
510558
#[cfg(test)]
511559
mod tests {
512560
use crate::{

xmtp_mls/src/groups/group_metadata.rs

+41-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ use xmtp_proto::xmtp::mls::message_contents::{
66
ConversationType as ConversationTypeProto, GroupMetadataV1 as GroupMetadataProto,
77
};
88

9-
use super::group_permissions::{PolicyError, PolicySet};
9+
use super::{
10+
group_permissions::{PolicyError, PolicySet},
11+
PreconfiguredPolicies,
12+
};
1013

1114
#[derive(Debug, Error)]
1215
pub enum GroupMetadataError {
@@ -44,6 +47,10 @@ impl GroupMetadata {
4447
}
4548
}
4649

50+
pub fn preconfigured_policy(&self) -> Result<PreconfiguredPolicies, GroupMetadataError> {
51+
Ok(PreconfiguredPolicies::from_policy_set(&self.policies)?)
52+
}
53+
4754
pub(crate) fn from_proto(proto: GroupMetadataProto) -> Result<Self, GroupMetadataError> {
4855
if proto.policies.is_none() {
4956
return Err(GroupMetadataError::MissingPolicies);
@@ -132,3 +139,36 @@ pub fn extract_group_metadata(group: &OpenMlsGroup) -> Result<GroupMetadata, Gro
132139

133140
extension.metadata().try_into()
134141
}
142+
143+
#[cfg(test)]
144+
mod tests {
145+
use crate::groups::group_permissions::{
146+
policy_everyone_is_admin, policy_group_creator_is_admin,
147+
};
148+
149+
use super::*;
150+
#[test]
151+
fn test_preconfigured_policy() {
152+
let account_address = "account_address";
153+
let group_metadata = GroupMetadata::new(
154+
ConversationType::Group,
155+
account_address.to_string(),
156+
policy_everyone_is_admin(),
157+
);
158+
assert_eq!(
159+
group_metadata.preconfigured_policy().unwrap(),
160+
PreconfiguredPolicies::EveryoneIsAdmin
161+
);
162+
163+
let group_metadata_creator_admin = GroupMetadata::new(
164+
ConversationType::Group,
165+
account_address.to_string(),
166+
policy_group_creator_is_admin(),
167+
);
168+
169+
assert_eq!(
170+
group_metadata_creator_admin.preconfigured_policy().unwrap(),
171+
PreconfiguredPolicies::GroupCreatorIsAdmin
172+
);
173+
}
174+
}

xmtp_mls/src/groups/group_permissions.rs

+11
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ pub(crate) fn policy_group_creator_is_admin() -> PolicySet {
345345
)
346346
}
347347

348+
#[derive(Debug, Clone, PartialEq)]
348349
pub enum PreconfiguredPolicies {
349350
EveryoneIsAdmin,
350351
GroupCreatorIsAdmin,
@@ -357,6 +358,16 @@ impl PreconfiguredPolicies {
357358
PreconfiguredPolicies::GroupCreatorIsAdmin => policy_group_creator_is_admin(),
358359
}
359360
}
361+
362+
pub fn from_policy_set(policy_set: &PolicySet) -> Result<Self, PolicyError> {
363+
if policy_set.eq(&policy_everyone_is_admin()) {
364+
Ok(PreconfiguredPolicies::EveryoneIsAdmin)
365+
} else if policy_set.eq(&policy_group_creator_is_admin()) {
366+
Ok(PreconfiguredPolicies::GroupCreatorIsAdmin)
367+
} else {
368+
Err(PolicyError::InvalidPolicy)
369+
}
370+
}
360371
}
361372

362373
impl Default for PreconfiguredPolicies {

xmtp_mls/src/groups/mod.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
mod group_metadata;
1+
pub mod group_metadata;
22
mod group_permissions;
33
mod intents;
44
mod members;
55
mod subscriptions;
66
mod sync;
77
pub mod validated_commit;
88

9+
use self::group_metadata::extract_group_metadata;
910
pub use self::group_permissions::PreconfiguredPolicies;
1011
pub use self::intents::{AddressesOrInstallationIds, IntentError};
1112
use self::{
@@ -338,6 +339,14 @@ where
338339

339340
Ok(mls_group.is_active())
340341
}
342+
343+
pub fn metadata(&self) -> Result<GroupMetadata, GroupError> {
344+
let conn = &self.client.store.conn()?;
345+
let provider = XmtpOpenMlsProvider::new(conn);
346+
let mls_group = self.load_mls_group(&provider)?;
347+
348+
Ok(extract_group_metadata(&mls_group)?)
349+
}
341350
}
342351

343352
fn extract_message_v1(message: GroupMessage) -> Result<GroupMessageV1, MessageProcessingError> {

0 commit comments

Comments
 (0)