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