rustical_caldav/principal/
mod.rs

1use crate::Error;
2use rustical_dav::extensions::CommonPropertiesExtension;
3use rustical_dav::privileges::UserPrivilegeSet;
4use rustical_dav::resource::{PrincipalUri, Resource, ResourceName};
5use rustical_dav::xml::{
6    GroupMemberSet, GroupMembership, Resourcetype, ResourcetypeInner, SupportedReportSet,
7};
8use rustical_store::auth::Principal;
9use std::borrow::Cow;
10
11mod service;
12pub use service::*;
13mod prop;
14pub use prop::*;
15#[cfg(test)]
16pub mod tests;
17
18#[derive(Debug, Clone)]
19pub struct PrincipalResource {
20    principal: Principal,
21    members: Vec<String>,
22    // If true only return the principal as the calendar home set, otherwise also groups
23    simplified_home_set: bool,
24}
25
26impl ResourceName for PrincipalResource {
27    fn get_name(&self) -> Cow<'_, str> {
28        Cow::from(&self.principal.id)
29    }
30}
31
32impl Resource for PrincipalResource {
33    type Prop = PrincipalPropWrapper;
34    type Error = Error;
35    type Principal = Principal;
36
37    fn is_collection(&self) -> bool {
38        true
39    }
40
41    fn get_resourcetype(&self) -> Resourcetype {
42        Resourcetype(&[
43            ResourcetypeInner(Some(rustical_dav::namespace::NS_DAV), "collection"),
44            ResourcetypeInner(Some(rustical_dav::namespace::NS_DAV), "principal"),
45        ])
46    }
47
48    fn get_prop(
49        &self,
50        puri: &impl PrincipalUri,
51        user: &Principal,
52        prop: &PrincipalPropWrapperName,
53    ) -> Result<Self::Prop, Self::Error> {
54        let principal_url = puri.principal_uri(&self.principal.id);
55
56        Ok(match prop {
57            PrincipalPropWrapperName::Principal(prop) => {
58                PrincipalPropWrapper::Principal(match prop {
59                    PrincipalPropName::CalendarUserType => {
60                        PrincipalProp::CalendarUserType(self.principal.principal_type.clone())
61                    }
62                    PrincipalPropName::PrincipalUrl => {
63                        PrincipalProp::PrincipalUrl(principal_url.into())
64                    }
65                    PrincipalPropName::CalendarHomeSet => PrincipalProp::CalendarHomeSet(
66                        CalendarHomeSet(if self.simplified_home_set {
67                            vec![principal_url.into()]
68                        } else {
69                            self.principal
70                                .memberships()
71                                .iter()
72                                .map(|principal| puri.principal_uri(principal).into())
73                                .collect()
74                        }),
75                    ),
76                    PrincipalPropName::CalendarUserAddressSet => {
77                        PrincipalProp::CalendarUserAddressSet(principal_url.into())
78                    }
79                    PrincipalPropName::GroupMemberSet => {
80                        PrincipalProp::GroupMemberSet(GroupMemberSet(
81                            self.members
82                                .iter()
83                                .map(|principal| puri.principal_uri(principal).into())
84                                .collect(),
85                        ))
86                    }
87                    PrincipalPropName::GroupMembership => {
88                        PrincipalProp::GroupMembership(GroupMembership(
89                            self.principal
90                                .memberships_without_self()
91                                .iter()
92                                .map(|principal| puri.principal_uri(principal).into())
93                                .collect(),
94                        ))
95                    }
96                    PrincipalPropName::AlternateUriSet => PrincipalProp::AlternateUriSet,
97                    // PrincipalPropName::PrincipalCollectionSet => {
98                    //     PrincipalProp::PrincipalCollectionSet(puri.principal_collection().into())
99                    // }
100                    PrincipalPropName::SupportedReportSet => {
101                        PrincipalProp::SupportedReportSet(SupportedReportSet::all())
102                    }
103                })
104            }
105            PrincipalPropWrapperName::Common(prop) => PrincipalPropWrapper::Common(
106                <Self as CommonPropertiesExtension>::get_prop(self, puri, user, prop)?,
107            ),
108        })
109    }
110
111    fn get_displayname(&self) -> Option<&str> {
112        Some(
113            self.principal
114                .displayname
115                .as_ref()
116                .unwrap_or(&self.principal.id),
117        )
118    }
119
120    fn get_owner(&self) -> Option<&str> {
121        Some(&self.principal.id)
122    }
123
124    fn get_user_privileges(&self, user: &Principal) -> Result<UserPrivilegeSet, Self::Error> {
125        Ok(UserPrivilegeSet::owner_only(
126            user.is_principal(&self.principal.id),
127        ))
128    }
129}