caldav: add support for calendar subscriptions

This commit is contained in:
Lennart
2024-11-11 17:31:32 +01:00
parent dc4e0c7f28
commit 1d671ad266
16 changed files with 64 additions and 23 deletions

View File

@@ -79,6 +79,7 @@ pub async fn route_mkcalendar<C: CalendarStore + ?Sized>(
description: request.calendar_description,
deleted_at: None,
synctoken: 0,
subscription_url: None,
};
match store.get_calendar(&principal, &cal_id).await {

View File

@@ -15,6 +15,7 @@ use async_trait::async_trait;
use derive_more::derive::{From, Into};
use rustical_dav::privileges::UserPrivilegeSet;
use rustical_dav::resource::{Resource, ResourceService};
use rustical_dav::xml::HrefElement;
use rustical_store::auth::User;
use rustical_store::{Calendar, CalendarStore};
use serde::{Deserialize, Serialize};
@@ -43,6 +44,7 @@ pub enum CalendarPropName {
SupportedReportSet,
SyncToken,
Getctag,
Source,
}
#[derive(Default, Deserialize, Serialize, PartialEq)]
@@ -82,6 +84,8 @@ pub enum CalendarProp {
// CalendarServer
#[serde(rename = "CS:getctag", alias = "getctag")]
Getctag(String),
#[serde(rename = "CS:source", alias = "source")]
Source(Option<HrefElement>),
#[serde(other)]
#[default]
@@ -97,8 +101,12 @@ impl Resource for CalendarResource {
type Error = Error;
type PrincipalResource = PrincipalResource;
fn get_resourcetype() -> &'static [&'static str] {
&["collection", "C:calendar"]
fn get_resourcetype(&self) -> &'static [&'static str] {
if self.0.subscription_url.is_none() {
&["collection", "C:calendar"]
} else {
&["collection", "CS:subscribed"]
}
}
fn get_prop(
@@ -144,6 +152,9 @@ impl Resource for CalendarResource {
}
CalendarPropName::SyncToken => CalendarProp::SyncToken(self.0.format_synctoken()),
CalendarPropName::Getctag => CalendarProp::Getctag(self.0.format_synctoken()),
CalendarPropName::Source => {
CalendarProp::Source(self.0.subscription_url.to_owned().map(HrefElement::from))
}
})
}
@@ -178,6 +189,8 @@ impl Resource for CalendarResource {
CalendarProp::SupportedReportSet(_) => Err(rustical_dav::Error::PropReadOnly),
CalendarProp::SyncToken(_) => Err(rustical_dav::Error::PropReadOnly),
CalendarProp::Getctag(_) => Err(rustical_dav::Error::PropReadOnly),
// Converting between a calendar subscription calendar and a normal one would be weird
CalendarProp::Source(_) => Err(rustical_dav::Error::PropReadOnly),
CalendarProp::Invalid => Err(rustical_dav::Error::PropReadOnly),
}
}
@@ -213,6 +226,8 @@ impl Resource for CalendarResource {
CalendarPropName::SupportedReportSet => Err(rustical_dav::Error::PropReadOnly),
CalendarPropName::SyncToken => Err(rustical_dav::Error::PropReadOnly),
CalendarPropName::Getctag => Err(rustical_dav::Error::PropReadOnly),
// Converting a calendar subscription calendar into a normal one would be weird
CalendarPropName::Source => Err(rustical_dav::Error::PropReadOnly),
}
}
@@ -226,6 +241,7 @@ impl Resource for CalendarResource {
}
fn get_user_privileges(&self, user: &User) -> Result<UserPrivilegeSet, Self::Error> {
// TODO: read-only for subscription
Ok(UserPrivilegeSet::owner_only(self.0.principal == user.id))
}
}

View File

@@ -55,7 +55,7 @@ impl Resource for CalendarObjectResource {
type Error = Error;
type PrincipalResource = PrincipalResource;
fn get_resourcetype() -> &'static [&'static str] {
fn get_resourcetype(&self) -> &'static [&'static str] {
&[]
}

View File

@@ -62,7 +62,7 @@ impl Resource for PrincipalResource {
type Error = Error;
type PrincipalResource = PrincipalResource;
fn get_resourcetype() -> &'static [&'static str] {
fn get_resourcetype(&self) -> &'static [&'static str] {
&["collection", "principal"]
}