diff --git a/crates/caldav/src/principal/mod.rs b/crates/caldav/src/principal/mod.rs index e4f248d..11a5e9c 100644 --- a/crates/caldav/src/principal/mod.rs +++ b/crates/caldav/src/principal/mod.rs @@ -63,6 +63,15 @@ impl Resource for PrincipalResource { PrincipalPropName::CalendarUserAddressSet => { PrincipalProp::CalendarUserAddressSet(principal_url.into()) } + PrincipalPropName::GroupMembership => { + PrincipalProp::GroupMembership(GroupMembership( + user.memberships_without_self() + .iter() + .map(|principal| puri.principal_uri(principal).into()) + .collect(), + )) + } + PrincipalPropName::AlternateUriSet => PrincipalProp::AlternateUriSet, }) } PrincipalPropWrapperName::Common(prop) => PrincipalPropWrapper::Common( diff --git a/crates/caldav/src/principal/prop.rs b/crates/caldav/src/principal/prop.rs index 2cb4fb5..fa3043a 100644 --- a/crates/caldav/src/principal/prop.rs +++ b/crates/caldav/src/principal/prop.rs @@ -14,6 +14,10 @@ pub enum PrincipalProp { // WebDAV Access Control (RFC 3744) #[xml(ns = "rustical_dav::namespace::NS_DAV", rename = b"principal-URL")] PrincipalUrl(HrefElement), + #[xml(ns = "rustical_dav::namespace::NS_DAV")] + GroupMembership(GroupMembership), + #[xml(ns = "rustical_dav::namespace::NS_DAV", rename = b"alternate-URI-set")] + AlternateUriSet, // CalDAV (RFC 4791) #[xml(ns = "rustical_dav::namespace::NS_CALDAV")] @@ -29,3 +33,6 @@ pub enum PrincipalPropWrapper { #[derive(XmlDeserialize, XmlSerialize, PartialEq, Clone)] pub struct CalendarHomeSet(#[xml(ty = "untagged", flatten)] pub(super) Vec); + +#[derive(XmlDeserialize, XmlSerialize, PartialEq, Clone)] +pub struct GroupMembership(#[xml(ty = "untagged", flatten)] pub(super) Vec); diff --git a/crates/carddav/src/principal/mod.rs b/crates/carddav/src/principal/mod.rs index 5bb0bc9..a7186ff 100644 --- a/crates/carddav/src/principal/mod.rs +++ b/crates/carddav/src/principal/mod.rs @@ -59,6 +59,15 @@ impl Resource for PrincipalResource { PrincipalProp::AddressbookHomeSet(home_set) } PrincipalPropName::PrincipalAddress => PrincipalProp::PrincipalAddress(None), + PrincipalPropName::GroupMembership => { + PrincipalProp::GroupMembership(GroupMembership( + user.memberships_without_self() + .iter() + .map(|principal| puri.principal_uri(principal).into()) + .collect(), + )) + } + PrincipalPropName::AlternateUriSet => PrincipalProp::AlternateUriSet, }) } diff --git a/crates/carddav/src/principal/prop.rs b/crates/carddav/src/principal/prop.rs index e749e1f..3a6d968 100644 --- a/crates/carddav/src/principal/prop.rs +++ b/crates/carddav/src/principal/prop.rs @@ -11,6 +11,10 @@ pub enum PrincipalProp { #[xml(rename = b"principal-URL")] #[xml(ns = "rustical_dav::namespace::NS_DAV")] PrincipalUrl(HrefElement), + #[xml(ns = "rustical_dav::namespace::NS_DAV")] + GroupMembership(GroupMembership), + #[xml(ns = "rustical_dav::namespace::NS_DAV", rename = b"alternate-URI-set")] + AlternateUriSet, // CardDAV (RFC 6352) #[xml(ns = "rustical_dav::namespace::NS_CARDDAV")] @@ -25,3 +29,6 @@ pub enum PrincipalPropWrapper { Principal(PrincipalProp), Common(CommonPropertiesProp), } + +#[derive(XmlDeserialize, XmlSerialize, PartialEq, Clone)] +pub struct GroupMembership(#[xml(ty = "untagged", flatten)] pub(super) Vec); diff --git a/crates/store/src/auth/user.rs b/crates/store/src/auth/user.rs index e7710a8..284cc23 100644 --- a/crates/store/src/auth/user.rs +++ b/crates/store/src/auth/user.rs @@ -108,6 +108,10 @@ impl User { memberships.push(self.id.as_str()); memberships } + + pub fn memberships_without_self(&self) -> Vec<&str> { + self.memberships.iter().map(String::as_str).collect() + } } impl rustical_dav::Principal for User {