mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 21:42:34 +00:00
some preparations for WebDav Push
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2469,6 +2469,7 @@ dependencies = [
|
||||
"rustical_dav",
|
||||
"rustical_store",
|
||||
"serde",
|
||||
"sha2",
|
||||
"strum",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
|
||||
@@ -25,3 +25,4 @@ url = { workspace = true }
|
||||
rustical_dav = { workspace = true }
|
||||
rustical_store = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
sha2 = { workspace = true }
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod mkcalendar;
|
||||
pub mod post;
|
||||
pub mod report;
|
||||
|
||||
15
crates/caldav/src/calendar/methods/post.rs
Normal file
15
crates/caldav/src/calendar/methods/post.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
use actix_web::{web::Data, web::Path, Responder};
|
||||
use rustical_store::{auth::User, CalendarStore};
|
||||
use tracing::instrument;
|
||||
use tracing_actix_web::RootSpan;
|
||||
|
||||
#[instrument(parent = root_span.id(), skip(store, root_span))]
|
||||
pub async fn route_post<C: CalendarStore + ?Sized>(
|
||||
path: Path<(String, String)>,
|
||||
body: String,
|
||||
user: User,
|
||||
store: Data<C>,
|
||||
root_span: RootSpan,
|
||||
) -> impl Responder {
|
||||
"asd"
|
||||
}
|
||||
@@ -86,3 +86,37 @@ impl Default for SupportedReportSet {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, PartialEq)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum Transport {
|
||||
#[serde(rename = "P:web-push")]
|
||||
WebPush,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, PartialEq)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct TransportWrapper {
|
||||
#[serde(rename = "$value")]
|
||||
transport: Transport,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, PartialEq)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Transports {
|
||||
// NOTE: Here we implement an older version of the spec since the new property name is not reflected
|
||||
// in DAVx5 yet
|
||||
// https://github.com/bitfireAT/webdav-push/commit/461259a2f2174454b2b00033419b11fac52b79e3
|
||||
#[serde(rename = "P:transport")]
|
||||
transports: Vec<TransportWrapper>,
|
||||
}
|
||||
|
||||
impl Default for Transports {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
transports: vec![TransportWrapper {
|
||||
transport: Transport::WebPush,
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use super::methods::mkcalendar::route_mkcalendar;
|
||||
use super::methods::post::route_post;
|
||||
use super::methods::report::route_report_calendar;
|
||||
use super::prop::{
|
||||
SupportedCalendarComponent, SupportedCalendarComponentSet, SupportedCalendarData,
|
||||
SupportedReportSet,
|
||||
SupportedReportSet, Transports,
|
||||
};
|
||||
use crate::calendar_object::resource::CalendarObjectResource;
|
||||
use crate::principal::PrincipalResource;
|
||||
@@ -12,6 +13,8 @@ use actix_web::http::Method;
|
||||
use actix_web::web;
|
||||
use actix_web::{web::Data, HttpRequest};
|
||||
use async_trait::async_trait;
|
||||
use base64::prelude::{BASE64_STANDARD, BASE64_URL_SAFE};
|
||||
use base64::Engine;
|
||||
use derive_more::derive::{From, Into};
|
||||
use rustical_dav::privileges::UserPrivilegeSet;
|
||||
use rustical_dav::resource::{Resource, ResourceService};
|
||||
@@ -19,6 +22,7 @@ use rustical_dav::xml::HrefElement;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::{Calendar, CalendarStore};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use strum::{EnumString, VariantNames};
|
||||
@@ -33,13 +37,15 @@ pub struct CalendarResourceService<C: CalendarStore + ?Sized> {
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum CalendarPropName {
|
||||
Displayname,
|
||||
Getcontenttype,
|
||||
Transports,
|
||||
Topic,
|
||||
CalendarColor,
|
||||
CalendarDescription,
|
||||
CalendarTimezone,
|
||||
CalendarOrder,
|
||||
SupportedCalendarComponentSet,
|
||||
SupportedCalendarData,
|
||||
Getcontenttype,
|
||||
MaxResourceSize,
|
||||
SupportedReportSet,
|
||||
SyncToken,
|
||||
@@ -54,6 +60,15 @@ pub enum CalendarProp {
|
||||
Displayname(Option<String>),
|
||||
Getcontenttype(String),
|
||||
|
||||
// WebDav Push
|
||||
// NOTE: Here we implement an older version of the spec since the new property name is not reflected
|
||||
// in DAVx5 yet
|
||||
// https://github.com/bitfireAT/webdav-push/commit/461259a2f2174454b2b00033419b11fac52b79e3
|
||||
#[serde(skip_deserializing)]
|
||||
#[serde(rename = "P:push-transports", alias = "push-transports")]
|
||||
Transports(Transports),
|
||||
Topic(String),
|
||||
|
||||
// CalDAV (RFC 4791)
|
||||
#[serde(rename = "IC:calendar-color", alias = "calendar-color")]
|
||||
CalendarColor(Option<String>),
|
||||
@@ -111,7 +126,7 @@ impl Resource for CalendarResource {
|
||||
|
||||
fn get_prop(
|
||||
&self,
|
||||
_rmap: &ResourceMap,
|
||||
rmap: &ResourceMap,
|
||||
_user: &User,
|
||||
prop: &Self::PropName,
|
||||
) -> Result<Self::Prop, Self::Error> {
|
||||
@@ -146,6 +161,14 @@ impl Resource for CalendarResource {
|
||||
CalendarPropName::Getcontenttype => {
|
||||
CalendarProp::Getcontenttype("text/calendar;charset=utf-8".to_owned())
|
||||
}
|
||||
CalendarPropName::Transports => CalendarProp::Transports(Default::default()),
|
||||
CalendarPropName::Topic => {
|
||||
let url = CalendarResource::get_url(rmap, [&self.0.principal, &self.0.id]).unwrap();
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(url);
|
||||
let topic = format!("{:x}", hasher.finalize());
|
||||
CalendarProp::Topic(topic)
|
||||
}
|
||||
CalendarPropName::MaxResourceSize => CalendarProp::MaxResourceSize(10000000),
|
||||
CalendarPropName::SupportedReportSet => {
|
||||
CalendarProp::SupportedReportSet(SupportedReportSet::default())
|
||||
@@ -185,6 +208,8 @@ impl Resource for CalendarResource {
|
||||
}
|
||||
CalendarProp::SupportedCalendarData(_) => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarProp::Getcontenttype(_) => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarProp::Transports(_) => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarProp::Topic(_) => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarProp::MaxResourceSize(_) => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarProp::SupportedReportSet(_) => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarProp::SyncToken(_) => Err(rustical_dav::Error::PropReadOnly),
|
||||
@@ -222,6 +247,8 @@ impl Resource for CalendarResource {
|
||||
}
|
||||
CalendarPropName::SupportedCalendarData => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarPropName::Getcontenttype => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarPropName::Transports => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarPropName::Topic => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarPropName::MaxResourceSize => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarPropName::SupportedReportSet => Err(rustical_dav::Error::PropReadOnly),
|
||||
CalendarPropName::SyncToken => Err(rustical_dav::Error::PropReadOnly),
|
||||
@@ -329,5 +356,6 @@ impl<C: CalendarStore + ?Sized> ResourceService for CalendarResourceService<C> {
|
||||
|
||||
res.route(report_method.to(route_report_calendar::<C>))
|
||||
.route(mkcalendar_method.to(route_mkcalendar::<C>))
|
||||
.post(route_post::<C>)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use quick_xml::events::attributes::Attribute;
|
||||
// Can also generate appropriate attributes for quick_xml
|
||||
pub enum Namespace {
|
||||
Dav,
|
||||
DavPush,
|
||||
CalDAV,
|
||||
CardDAV,
|
||||
ICal,
|
||||
@@ -16,6 +17,7 @@ impl Namespace {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Dav => "DAV:",
|
||||
Self::DavPush => "DAV:Push",
|
||||
Self::CalDAV => "urn:ietf:params:xml:ns:caldav",
|
||||
Self::CardDAV => "urn:ietf:params:xml:ns:carddav",
|
||||
Self::ICal => "http://apple.com/ns/ical/",
|
||||
@@ -28,6 +30,7 @@ impl Namespace {
|
||||
pub fn xml_attr(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Dav => "xmlns",
|
||||
Self::DavPush => "xmlns:P",
|
||||
Self::CalDAV => "xmlns:C",
|
||||
Self::CardDAV => "xmlns:CARD",
|
||||
Self::ICal => "xmlns:IC",
|
||||
|
||||
@@ -79,6 +79,8 @@ pub struct MultistatusElement<PropType: Serialize, MemberPropType: Serialize> {
|
||||
pub member_responses: Vec<ResponseElement<MemberPropType>>,
|
||||
#[serde(rename = "@xmlns")]
|
||||
pub ns_dav: &'static str,
|
||||
#[serde(rename = "@xmlns:P")]
|
||||
pub ns_davpush: &'static str,
|
||||
#[serde(rename = "@xmlns:C")]
|
||||
pub ns_caldav: &'static str,
|
||||
#[serde(rename = "@xmlns:IC")]
|
||||
@@ -97,6 +99,7 @@ impl<T1: Serialize, T2: Serialize> Default for MultistatusElement<T1, T2> {
|
||||
responses: vec![],
|
||||
member_responses: vec![],
|
||||
ns_dav: Namespace::Dav.as_str(),
|
||||
ns_davpush: Namespace::DavPush.as_str(),
|
||||
ns_caldav: Namespace::CalDAV.as_str(),
|
||||
ns_ical: Namespace::ICal.as_str(),
|
||||
ns_calendarserver: Namespace::CServer.as_str(),
|
||||
|
||||
Reference in New Issue
Block a user