Skip to main content

rustical_caldav/principal/
mod.rs

1use crate::Error;
2use rustical_dav::extensions::CommonPropertiesExtension;
3use rustical_dav::namespace::NS_DAV;
4use rustical_dav::privileges::UserPrivilegeSet;
5use rustical_dav::resource::{PrincipalUri, Resource, ResourceName};
6use rustical_dav::resourcetype;
7use rustical_dav::xml::{GroupMemberSet, GroupMembership, Resourcetype, SupportedReportSet};
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!((NS_DAV, "collection"), (NS_DAV, "principal"),)
43    }
44
45    fn get_prop(
46        &self,
47        puri: &impl PrincipalUri,
48        user: &Principal,
49        prop: &PrincipalPropWrapperName,
50    ) -> Result<Self::Prop, Self::Error> {
51        let principal_url = puri.principal_uri(&self.principal.id);
52
53        Ok(match prop {
54            PrincipalPropWrapperName::Principal(prop) => {
55                PrincipalPropWrapper::Principal(match prop {
56                    PrincipalPropName::CalendarUserType => {
57                        PrincipalProp::CalendarUserType(self.principal.principal_type.clone())
58                    }
59                    PrincipalPropName::PrincipalUrl => {
60                        PrincipalProp::PrincipalUrl(principal_url.into())
61                    }
62                    PrincipalPropName::CalendarHomeSet => PrincipalProp::CalendarHomeSet(
63                        CalendarHomeSet(if self.simplified_home_set {
64                            vec![principal_url.into()]
65                        } else {
66                            self.principal
67                                .memberships()
68                                .iter()
69                                .map(|principal| puri.principal_uri(principal).into())
70                                .collect()
71                        }),
72                    ),
73                    PrincipalPropName::CalendarUserAddressSet => {
74                        PrincipalProp::CalendarUserAddressSet(principal_url.into())
75                    }
76                    PrincipalPropName::GroupMemberSet => {
77                        PrincipalProp::GroupMemberSet(GroupMemberSet(
78                            self.members
79                                .iter()
80                                .map(|principal| puri.principal_uri(principal).into())
81                                .collect(),
82                        ))
83                    }
84                    PrincipalPropName::GroupMembership => {
85                        PrincipalProp::GroupMembership(GroupMembership(
86                            self.principal
87                                .memberships_without_self()
88                                .iter()
89                                .map(|principal| puri.principal_uri(principal).into())
90                                .collect(),
91                        ))
92                    }
93                    PrincipalPropName::AlternateUriSet => PrincipalProp::AlternateUriSet,
94                    // PrincipalPropName::PrincipalCollectionSet => {
95                    //     PrincipalProp::PrincipalCollectionSet(puri.principal_collection().into())
96                    // }
97                    PrincipalPropName::SupportedReportSet => {
98                        PrincipalProp::SupportedReportSet(SupportedReportSet::all())
99                    }
100                })
101            }
102            PrincipalPropWrapperName::Common(prop) => PrincipalPropWrapper::Common(
103                <Self as CommonPropertiesExtension>::get_prop(self, puri, user, prop)?,
104            ),
105        })
106    }
107
108    fn get_displayname(&self) -> Option<&str> {
109        Some(
110            self.principal
111                .displayname
112                .as_ref()
113                .unwrap_or(&self.principal.id),
114        )
115    }
116
117    fn get_owner(&self) -> Option<&str> {
118        Some(&self.principal.id)
119    }
120
121    fn get_user_privileges(&self, user: &Principal) -> Result<UserPrivilegeSet, Self::Error> {
122        Ok(UserPrivilegeSet::owner_only(
123            user.is_principal(&self.principal.id),
124        ))
125    }
126}