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