rustical_caldav/
lib.rs

1#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
2#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc)]
3use axum::{Extension, Router};
4use derive_more::Constructor;
5use principal::PrincipalResourceService;
6use rustical_dav::resource::{PrincipalUri, ResourceService};
7use rustical_dav::resources::RootResourceService;
8use rustical_store::auth::middleware::AuthenticationLayer;
9use rustical_store::auth::{AuthenticationProvider, Principal};
10use rustical_store::{CalendarStore, SubscriptionStore};
11use serde::{Deserialize, Serialize};
12use std::sync::Arc;
13
14pub mod calendar;
15pub mod calendar_object;
16pub mod error;
17pub mod principal;
18pub use error::Error;
19
20#[derive(Debug, Clone, Constructor)]
21pub struct CalDavPrincipalUri(&'static str);
22
23impl PrincipalUri for CalDavPrincipalUri {
24    fn principal_collection(&self) -> String {
25        format!("{}/principal/", self.0)
26    }
27    fn principal_uri(&self, principal: &str) -> String {
28        format!("{}{}/", self.principal_collection(), principal)
29    }
30}
31
32pub fn caldav_router<AP: AuthenticationProvider, C: CalendarStore, S: SubscriptionStore>(
33    prefix: &'static str,
34    auth_provider: Arc<AP>,
35    store: Arc<C>,
36    subscription_store: Arc<S>,
37    simplified_home_set: bool,
38    config: Arc<CalDavConfig>,
39) -> Router {
40    Router::new().nest(
41        prefix,
42        RootResourceService::<_, Principal, CalDavPrincipalUri>::new(PrincipalResourceService {
43            auth_provider: auth_provider.clone(),
44            sub_store: subscription_store,
45            cal_store: store,
46            simplified_home_set,
47            config,
48        })
49        .axum_router()
50        .layer(AuthenticationLayer::new(auth_provider))
51        .layer(Extension(CalDavPrincipalUri(prefix))),
52    )
53}
54
55const fn default_true() -> bool {
56    true
57}
58
59#[derive(Debug, Clone, Deserialize, Serialize)]
60#[serde(deny_unknown_fields, default)]
61pub struct CalDavConfig {
62    #[serde(default = "default_true")]
63    rfc7809: bool,
64}
65
66impl Default for CalDavConfig {
67    fn default() -> Self {
68        Self { rfc7809: true }
69    }
70}