rustical_caldav/principal/
service.rs1use crate::calendar::CalendarResourceService;
2use crate::calendar::resource::CalendarResource;
3use crate::principal::PrincipalResource;
4use crate::{CalDavConfig, CalDavPrincipalUri, Error};
5use async_trait::async_trait;
6use axum::Router;
7use rustical_dav::resource::{AxumMethods, ResourceService};
8use rustical_store::auth::{AuthenticationProvider, Principal};
9use rustical_store::{CalendarStore, SubscriptionStore};
10use std::sync::Arc;
11
12#[derive(Debug)]
13pub struct PrincipalResourceService<
14 AP: AuthenticationProvider,
15 S: SubscriptionStore,
16 CS: CalendarStore,
17> {
18 pub(crate) auth_provider: Arc<AP>,
19 pub(crate) sub_store: Arc<S>,
20 pub(crate) cal_store: Arc<CS>,
21 pub(crate) simplified_home_set: bool,
23 pub(crate) config: Arc<CalDavConfig>,
24}
25
26impl<AP: AuthenticationProvider, S: SubscriptionStore, CS: CalendarStore> Clone
27 for PrincipalResourceService<AP, S, CS>
28{
29 fn clone(&self) -> Self {
30 Self {
31 auth_provider: self.auth_provider.clone(),
32 sub_store: self.sub_store.clone(),
33 cal_store: self.cal_store.clone(),
34 simplified_home_set: self.simplified_home_set,
35 config: self.config.clone(),
36 }
37 }
38}
39
40#[async_trait]
41impl<AP: AuthenticationProvider, S: SubscriptionStore, CS: CalendarStore> ResourceService
42 for PrincipalResourceService<AP, S, CS>
43{
44 type PathComponents = (String,);
45 type MemberType = CalendarResource;
46 type Resource = PrincipalResource;
47 type Error = Error;
48 type Principal = Principal;
49 type PrincipalUri = CalDavPrincipalUri;
50
51 const DAV_HEADER: &str = "1, 3, access-control, calendar-access";
52
53 async fn get_resource(
54 &self,
55 (principal,): &Self::PathComponents,
56 _show_deleted: bool,
57 ) -> Result<Self::Resource, Self::Error> {
58 let user = self
59 .auth_provider
60 .get_principal(principal)
61 .await?
62 .ok_or(crate::Error::NotFound)?;
63 Ok(PrincipalResource {
64 members: self.auth_provider.list_members(&user.id).await?,
65 principal: user,
66 simplified_home_set: self.simplified_home_set,
67 })
68 }
69
70 async fn get_members(
71 &self,
72 (principal,): &Self::PathComponents,
73 ) -> Result<Vec<Self::MemberType>, Self::Error> {
74 let calendars = self.cal_store.get_calendars(principal).await?;
75
76 Ok(calendars
77 .into_iter()
78 .map(|cal| CalendarResource {
79 read_only: self.cal_store.is_read_only(&cal.id),
80 cal,
81 })
82 .collect())
83 }
84
85 fn axum_router<State: Send + Sync + Clone + 'static>(self) -> axum::Router<State> {
86 Router::new()
87 .nest(
88 "/{calendar_id}",
89 CalendarResourceService::new(
90 self.cal_store.clone(),
91 self.sub_store.clone(),
92 self.config.clone(),
93 )
94 .axum_router(),
95 )
96 .route_service("/", self.axum_service())
97 }
98}
99
100impl<AP: AuthenticationProvider, S: SubscriptionStore, CS: CalendarStore> AxumMethods
101 for PrincipalResourceService<AP, S, CS>
102{
103}