From f1997f2c184062befe53251eda183a9a6a078a2f Mon Sep 17 00:00:00 2001 From: Lennart <18233294+lennart-k@users.noreply.github.com> Date: Sun, 3 Nov 2024 22:51:19 +0100 Subject: [PATCH] outsource resourcetype to extension --- crates/caldav/src/calendar/resource.rs | 12 +++---- crates/caldav/src/calendar_object/resource.rs | 16 ++++++--- crates/caldav/src/principal/mod.rs | 7 ++-- crates/caldav/src/root/mod.rs | 7 ++-- crates/carddav/src/address_object/resource.rs | 14 ++++++-- crates/carddav/src/addressbook/resource.rs | 14 +++----- crates/carddav/src/principal/mod.rs | 12 +++---- crates/carddav/src/root/mod.rs | 22 +++++-------- crates/dav/src/extensions/mod.rs | 33 +++++++++++-------- crates/dav/src/resource.rs | 6 ++-- 10 files changed, 73 insertions(+), 70 deletions(-) diff --git a/crates/caldav/src/calendar/resource.rs b/crates/caldav/src/calendar/resource.rs index 5dc6737..177a07a 100644 --- a/crates/caldav/src/calendar/resource.rs +++ b/crates/caldav/src/calendar/resource.rs @@ -34,10 +34,9 @@ pub struct CalendarResourceService { pub calendar_id: String, } -#[derive(EnumString, Debug, VariantNames, Clone, From, TryInto)] +#[derive(EnumString, VariantNames, Clone, From, TryInto)] #[strum(serialize_all = "kebab-case")] pub enum CalendarPropName { - Resourcetype, Owner, Displayname, CalendarColor, @@ -57,11 +56,10 @@ pub enum CalendarPropName { ExtCommonProperties(CommonPropertiesPropName), } -#[derive(Debug, Deserialize, Serialize, From, TryInto)] +#[derive(Deserialize, Serialize, From, TryInto)] #[serde(rename_all = "kebab-case")] pub enum CalendarProp { // WebDAV (RFC 2518) - Resourcetype(Resourcetype), Displayname(Option), Getcontenttype(String), @@ -99,7 +97,7 @@ pub enum CalendarProp { #[serde(skip_deserializing, untagged)] #[from] #[try_into] - ExtCommonProperties(CommonPropertiesProp), + ExtCommonProperties(CommonPropertiesProp), #[serde(untagged)] Invalid, @@ -118,6 +116,7 @@ impl Resource for CalendarResource { type PropName = CalendarPropName; type Prop = CalendarProp; type Error = Error; + type ResourceType = Resourcetype; fn list_extensions() -> Vec> { vec![BoxedExtension::from_ext(CommonPropertiesExtension::< @@ -132,7 +131,6 @@ impl Resource for CalendarResource { prop: &Self::PropName, ) -> Result { Ok(match prop { - CalendarPropName::Resourcetype => CalendarProp::Resourcetype(Resourcetype::default()), CalendarPropName::Owner => CalendarProp::Owner(HrefElement::new( PrincipalResource::get_url(rmap, vec![&self.0.principal]).unwrap(), )), @@ -181,7 +179,6 @@ impl Resource for CalendarResource { fn set_prop(&mut self, prop: Self::Prop) -> Result<(), rustical_dav::Error> { match prop { - CalendarProp::Resourcetype(_) => Err(rustical_dav::Error::PropReadOnly), CalendarProp::Owner(_) => Err(rustical_dav::Error::PropReadOnly), CalendarProp::Displayname(displayname) => { self.0.displayname = displayname; @@ -220,7 +217,6 @@ impl Resource for CalendarResource { fn remove_prop(&mut self, prop: &Self::PropName) -> Result<(), rustical_dav::Error> { match prop { - CalendarPropName::Resourcetype => Err(rustical_dav::Error::PropReadOnly), CalendarPropName::Owner => Err(rustical_dav::Error::PropReadOnly), CalendarPropName::Displayname => { self.0.displayname = None; diff --git a/crates/caldav/src/calendar_object/resource.rs b/crates/caldav/src/calendar_object/resource.rs index 670c845..da20616 100644 --- a/crates/caldav/src/calendar_object/resource.rs +++ b/crates/caldav/src/calendar_object/resource.rs @@ -23,7 +23,7 @@ pub struct CalendarObjectResourceService { pub object_id: String, } -#[derive(EnumString, Debug, VariantNames, Clone, From, TryInto)] +#[derive(EnumString, VariantNames, Clone, From, TryInto)] #[strum(serialize_all = "kebab-case")] pub enum CalendarObjectPropName { Getetag, @@ -36,7 +36,7 @@ pub enum CalendarObjectPropName { ExtCommonProperties(CommonPropertiesPropName), } -#[derive(Deserialize, Serialize, Debug, From, TryInto)] +#[derive(Deserialize, Serialize, From, TryInto)] #[serde(rename_all = "kebab-case")] pub enum CalendarObjectProp { // WebDAV (RFC 2518) @@ -53,7 +53,7 @@ pub enum CalendarObjectProp { #[serde(skip_deserializing, untagged)] #[from] #[try_into] - ExtCommonProperties(CommonPropertiesProp), + ExtCommonProperties(CommonPropertiesProp), #[serde(untagged)] Invalid, @@ -71,10 +71,18 @@ pub struct CalendarObjectResource { pub principal: String, } +// TODO: set correct resourcetype +#[derive(Debug, Clone, Deserialize, Serialize, Default)] +#[serde(rename_all = "kebab-case")] +pub struct Resourcetype { + collection: (), +} + impl Resource for CalendarObjectResource { type PropName = CalendarObjectPropName; type Prop = CalendarObjectProp; type Error = Error; + type ResourceType = Resourcetype; fn list_extensions() -> Vec> { vec![BoxedExtension::from_ext(CommonPropertiesExtension::< @@ -85,7 +93,7 @@ impl Resource for CalendarObjectResource { fn get_prop( &self, rmap: &ResourceMap, - user: &User, + _user: &User, prop: &Self::PropName, ) -> Result { Ok(match prop { diff --git a/crates/caldav/src/principal/mod.rs b/crates/caldav/src/principal/mod.rs index 6be30ab..e3074b3 100644 --- a/crates/caldav/src/principal/mod.rs +++ b/crates/caldav/src/principal/mod.rs @@ -35,7 +35,7 @@ pub struct Resourcetype { collection: (), } -#[derive(Deserialize, Serialize, Debug, From, TryInto)] +#[derive(Deserialize, Serialize, From, TryInto)] #[serde(rename_all = "kebab-case")] pub enum PrincipalProp { // WebDAV (RFC 2518) @@ -57,7 +57,7 @@ pub enum PrincipalProp { #[serde(skip_deserializing, untagged)] #[from] #[try_into] - ExtCommonProperties(CommonPropertiesProp), + ExtCommonProperties(CommonPropertiesProp), #[serde(untagged)] Invalid, @@ -69,7 +69,7 @@ impl InvalidProperty for PrincipalProp { } } -#[derive(EnumString, Debug, VariantNames, Clone, From, TryInto)] +#[derive(EnumString, VariantNames, Clone, From, TryInto)] #[strum(serialize_all = "kebab-case")] pub enum PrincipalPropName { Resourcetype, @@ -94,6 +94,7 @@ impl Resource for PrincipalResource { type PropName = PrincipalPropName; type Prop = PrincipalProp; type Error = Error; + type ResourceType = Resourcetype; fn list_extensions() -> Vec> { vec![BoxedExtension::from_ext(CommonPropertiesExtension::< diff --git a/crates/caldav/src/root/mod.rs b/crates/caldav/src/root/mod.rs index 7fcb9c2..6182fe6 100644 --- a/crates/caldav/src/root/mod.rs +++ b/crates/caldav/src/root/mod.rs @@ -14,7 +14,7 @@ use rustical_store::auth::User; use serde::{Deserialize, Serialize}; use strum::{EnumString, VariantNames}; -#[derive(EnumString, Debug, VariantNames, Clone, From, TryInto)] +#[derive(EnumString, VariantNames, Clone, From, TryInto)] #[strum(serialize_all = "kebab-case")] pub enum RootPropName { Resourcetype, @@ -30,7 +30,7 @@ pub struct Resourcetype { collection: (), } -#[derive(Deserialize, Serialize, Debug, From, TryInto)] +#[derive(Deserialize, Serialize, From, TryInto)] #[serde(rename_all = "kebab-case")] pub enum RootProp { // WebDAV (RFC 2518) @@ -39,7 +39,7 @@ pub enum RootProp { #[serde(skip_deserializing, untagged)] #[from] #[try_into] - ExtCommonProperties(CommonPropertiesProp), + ExtCommonProperties(CommonPropertiesProp), #[serde(untagged)] Invalid, @@ -58,6 +58,7 @@ impl Resource for RootResource { type PropName = RootPropName; type Prop = RootProp; type Error = Error; + type ResourceType = Resourcetype; fn list_extensions() -> Vec> { vec![BoxedExtension::from_ext(CommonPropertiesExtension::< diff --git a/crates/carddav/src/address_object/resource.rs b/crates/carddav/src/address_object/resource.rs index cc7b017..83bedac 100644 --- a/crates/carddav/src/address_object/resource.rs +++ b/crates/carddav/src/address_object/resource.rs @@ -24,7 +24,7 @@ pub struct AddressObjectResourceService { pub object_id: String, } -#[derive(EnumString, Debug, VariantNames, Clone, From, TryInto)] +#[derive(EnumString, VariantNames, Clone, From, TryInto)] #[strum(serialize_all = "kebab-case")] pub enum AddressObjectPropName { Getetag, @@ -37,7 +37,7 @@ pub enum AddressObjectPropName { ExtCommonProperties(CommonPropertiesPropName), } -#[derive(Deserialize, Serialize, Debug, From, TryInto)] +#[derive(Deserialize, Serialize, From, TryInto)] #[serde(rename_all = "kebab-case")] pub enum AddressObjectProp { // WebDAV (RFC 2518) @@ -58,7 +58,7 @@ pub enum AddressObjectProp { #[serde(skip_deserializing, untagged)] #[from] #[try_into] - ExtCommonProperties(CommonPropertiesProp), + ExtCommonProperties(CommonPropertiesProp), #[serde(untagged)] Invalid, @@ -76,10 +76,18 @@ pub struct AddressObjectResource { pub principal: String, } +// TODO: set correct resourcetype +#[derive(Debug, Clone, Deserialize, Serialize, Default)] +#[serde(rename_all = "kebab-case")] +pub struct Resourcetype { + collection: (), +} + impl Resource for AddressObjectResource { type PropName = AddressObjectPropName; type Prop = AddressObjectProp; type Error = Error; + type ResourceType = Resourcetype; fn list_extensions() -> Vec> { vec![BoxedExtension::from_ext(CommonPropertiesExtension::< diff --git a/crates/carddav/src/addressbook/resource.rs b/crates/carddav/src/addressbook/resource.rs index f5f5931..6be9df5 100644 --- a/crates/carddav/src/addressbook/resource.rs +++ b/crates/carddav/src/addressbook/resource.rs @@ -31,10 +31,9 @@ pub struct AddressbookResourceService { pub addressbook_id: String, } -#[derive(EnumString, Debug, VariantNames, Clone, From, TryInto)] +#[derive(EnumString, VariantNames, Clone, From, TryInto)] #[strum(serialize_all = "kebab-case")] pub enum AddressbookPropName { - Resourcetype, Displayname, Getcontenttype, Owner, @@ -49,11 +48,10 @@ pub enum AddressbookPropName { ExtCommonProperties(CommonPropertiesPropName), } -#[derive(Debug, Deserialize, Serialize, From, TryInto)] +#[derive(Deserialize, Serialize, From, TryInto)] #[serde(rename_all = "kebab-case")] pub enum AddressbookProp { // WebDAV (RFC 2518) - Resourcetype(Resourcetype), Displayname(Option), Getcontenttype(String), @@ -83,7 +81,7 @@ pub enum AddressbookProp { #[serde(skip_deserializing, untagged)] #[from] #[try_into] - ExtCommonProperties(CommonPropertiesProp), + ExtCommonProperties(CommonPropertiesProp), #[serde(untagged)] Invalid, @@ -102,6 +100,7 @@ impl Resource for AddressbookResource { type PropName = AddressbookPropName; type Prop = AddressbookProp; type Error = Error; + type ResourceType = Resourcetype; fn list_extensions() -> Vec> { vec![BoxedExtension::from_ext(CommonPropertiesExtension::< @@ -116,9 +115,6 @@ impl Resource for AddressbookResource { prop: &Self::PropName, ) -> Result { Ok(match prop { - AddressbookPropName::Resourcetype => { - AddressbookProp::Resourcetype(Resourcetype::default()) - } AddressbookPropName::Owner => AddressbookProp::Owner( PrincipalResource::get_principal_url(rmap, &self.0.principal).into(), ), @@ -146,7 +142,6 @@ impl Resource for AddressbookResource { fn set_prop(&mut self, prop: Self::Prop) -> Result<(), rustical_dav::Error> { match prop { - AddressbookProp::Resourcetype(_) => Err(rustical_dav::Error::PropReadOnly), AddressbookProp::Owner(_) => Err(rustical_dav::Error::PropReadOnly), AddressbookProp::Displayname(displayname) => { self.0.displayname = displayname; @@ -169,7 +164,6 @@ impl Resource for AddressbookResource { fn remove_prop(&mut self, prop: &Self::PropName) -> Result<(), rustical_dav::Error> { match prop { - AddressbookPropName::Resourcetype => Err(rustical_dav::Error::PropReadOnly), AddressbookPropName::Owner => Err(rustical_dav::Error::PropReadOnly), AddressbookPropName::Displayname => { self.0.displayname = None; diff --git a/crates/carddav/src/principal/mod.rs b/crates/carddav/src/principal/mod.rs index d4a91eb..06c5e2d 100644 --- a/crates/carddav/src/principal/mod.rs +++ b/crates/carddav/src/principal/mod.rs @@ -35,12 +35,9 @@ pub struct Resourcetype { collection: (), } -#[derive(Deserialize, Serialize, Debug, From, TryInto)] +#[derive(Deserialize, Serialize, From, TryInto)] #[serde(rename_all = "kebab-case")] pub enum PrincipalProp { - // WebDAV (RFC 2518) - Resourcetype(Resourcetype), - // WebDAV Access Control (RFC 3744) #[serde(rename = "principal-URL")] PrincipalUrl(HrefElement), @@ -54,7 +51,7 @@ pub enum PrincipalProp { #[serde(skip_deserializing, untagged)] #[from] #[try_into] - ExtRFC5397RFC3477(CommonPropertiesProp), + ExtRFC5397RFC3477(CommonPropertiesProp), #[serde(untagged)] Invalid, @@ -66,10 +63,9 @@ impl InvalidProperty for PrincipalProp { } } -#[derive(EnumString, Debug, VariantNames, Clone, From, TryInto)] +#[derive(EnumString, VariantNames, Clone, From, TryInto)] #[strum(serialize_all = "kebab-case")] pub enum PrincipalPropName { - Resourcetype, #[strum(serialize = "principal-URL")] PrincipalUrl, AddressbookHomeSet, @@ -90,6 +86,7 @@ impl Resource for PrincipalResource { type PropName = PrincipalPropName; type Prop = PrincipalProp; type Error = Error; + type ResourceType = Resourcetype; fn list_extensions() -> Vec> { vec![BoxedExtension::from_ext(CommonPropertiesExtension::< @@ -106,7 +103,6 @@ impl Resource for PrincipalResource { let principal_href = HrefElement::new(Self::get_principal_url(rmap, &self.principal)); Ok(match prop { - PrincipalPropName::Resourcetype => PrincipalProp::Resourcetype(Resourcetype::default()), PrincipalPropName::PrincipalUrl => PrincipalProp::PrincipalUrl(principal_href), PrincipalPropName::AddressbookHomeSet => { PrincipalProp::AddressbookHomeSet(principal_href) diff --git a/crates/carddav/src/root/mod.rs b/crates/carddav/src/root/mod.rs index bf8a394..00d79b2 100644 --- a/crates/carddav/src/root/mod.rs +++ b/crates/carddav/src/root/mod.rs @@ -14,10 +14,9 @@ use rustical_store::auth::User; use serde::{Deserialize, Serialize}; use strum::{EnumString, VariantNames}; -#[derive(EnumString, Debug, VariantNames, Clone, From, TryInto)] +#[derive(EnumString, VariantNames, Clone, From, TryInto)] #[strum(serialize_all = "kebab-case")] pub enum RootPropName { - Resourcetype, #[from] #[try_into] #[strum(disabled)] @@ -30,16 +29,13 @@ pub struct Resourcetype { collection: (), } -#[derive(Deserialize, Serialize, Debug, From, TryInto)] +#[derive(Deserialize, Serialize, From, TryInto)] #[serde(rename_all = "kebab-case")] pub enum RootProp { - // WebDAV (RFC 2518) - Resourcetype(Resourcetype), - #[serde(skip_deserializing, untagged)] #[from] #[try_into] - ExtCommonProperties(CommonPropertiesProp), + ExtCommonProperties(CommonPropertiesProp), #[serde(untagged)] Invalid, @@ -58,6 +54,7 @@ impl Resource for RootResource { type PropName = RootPropName; type Prop = RootProp; type Error = Error; + type ResourceType = Resourcetype; fn list_extensions() -> Vec> { vec![BoxedExtension::from_ext(CommonPropertiesExtension::< @@ -67,14 +64,11 @@ impl Resource for RootResource { fn get_prop( &self, - rmap: &ResourceMap, - user: &User, - prop: &Self::PropName, + _rmap: &ResourceMap, + _user: &User, + _prop: &Self::PropName, ) -> Result { - Ok(match prop { - RootPropName::Resourcetype => RootProp::Resourcetype(Resourcetype::default()), - _ => panic!("we shouldn't end up here"), - }) + panic!("we shouldn't end up here") } #[inline] diff --git a/crates/dav/src/extensions/mod.rs b/crates/dav/src/extensions/mod.rs index da2d5ee..c5b7245 100644 --- a/crates/dav/src/extensions/mod.rs +++ b/crates/dav/src/extensions/mod.rs @@ -1,18 +1,16 @@ -use std::marker::PhantomData; - -use actix_web::dev::ResourceMap; -use rustical_store::auth::User; -use serde::{Deserialize, Serialize}; -use strum::{EnumString, VariantNames}; - use crate::{ extension::ResourceExtension, privileges::UserPrivilegeSet, resource::{InvalidProperty, Resource}, xml::HrefElement, }; +use actix_web::dev::ResourceMap; +use rustical_store::auth::User; +use serde::{Deserialize, Serialize}; +use std::marker::PhantomData; +use strum::{EnumString, VariantNames}; -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct CommonPropertiesExtension(PhantomData); impl Default for CommonPropertiesExtension { @@ -21,9 +19,12 @@ impl Default for CommonPropertiesExtension { } } -#[derive(Deserialize, Serialize, Debug)] +#[derive(Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] -pub enum CommonPropertiesProp { +pub enum CommonPropertiesProp { + // WebDAV (RFC 2518) + Resourcetype(R::ResourceType), + // WebDAV Current Principal Extension (RFC 5397) CurrentUserPrincipal(HrefElement), @@ -34,15 +35,16 @@ pub enum CommonPropertiesProp { Invalid, } -impl InvalidProperty for CommonPropertiesProp { +impl InvalidProperty for CommonPropertiesProp { fn invalid_property(&self) -> bool { matches!(self, Self::Invalid) } } -#[derive(EnumString, Debug, VariantNames, Clone)] +#[derive(EnumString, VariantNames, Clone)] #[strum(serialize_all = "kebab-case")] pub enum CommonPropertiesPropName { + Resourcetype, CurrentUserPrincipal, CurrentUserPrivilegeSet, } @@ -50,9 +52,9 @@ pub enum CommonPropertiesPropName { impl ResourceExtension for CommonPropertiesExtension where R::PropName: TryInto, - R::Prop: From, + R::Prop: From>, { - type Prop = CommonPropertiesProp; + type Prop = CommonPropertiesProp; type PropName = CommonPropertiesPropName; type Error = R::Error; @@ -64,6 +66,9 @@ where prop: Self::PropName, ) -> Result { Ok(match prop { + CommonPropertiesPropName::Resourcetype => { + CommonPropertiesProp::Resourcetype(R::ResourceType::default()) + } CommonPropertiesPropName::CurrentUserPrincipal => { CommonPropertiesProp::CurrentUserPrincipal( PR::get_url(rmap, &[&user.id]).unwrap().into(), diff --git a/crates/dav/src/resource.rs b/crates/dav/src/resource.rs index b24c64b..b71e574 100644 --- a/crates/dav/src/resource.rs +++ b/crates/dav/src/resource.rs @@ -11,15 +11,14 @@ use actix_web::test::TestRequest; use actix_web::web; use actix_web::{http::StatusCode, HttpRequest, ResponseError}; use async_trait::async_trait; -use core::fmt; use itertools::Itertools; use rustical_store::auth::User; use serde::{Deserialize, Serialize}; use std::str::FromStr; use strum::VariantNames; -pub trait ResourceReadProp: Serialize + fmt::Debug + InvalidProperty {} -impl ResourceReadProp for T {} +pub trait ResourceReadProp: Serialize + InvalidProperty {} +impl ResourceReadProp for T {} pub trait ResourceProp: ResourceReadProp + for<'de> Deserialize<'de> {} impl Deserialize<'de>> ResourceProp for T {} @@ -31,6 +30,7 @@ pub trait Resource: Clone { type PropName: ResourcePropName; type Prop: ResourceProp; type Error: ResponseError + From; + type ResourceType: Default + Serialize + for<'de> Deserialize<'de>; fn list_extensions() -> Vec> { vec![]