rustical_caldav/principal/
mod.rs1use 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 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::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}