changes around extensions

This commit is contained in:
Lennart
2024-11-04 19:19:54 +01:00
parent c41e3e3abb
commit 0d2e07fb65
10 changed files with 53 additions and 79 deletions

View File

@@ -13,8 +13,7 @@ use actix_web::web;
use actix_web::{web::Data, HttpRequest};
use async_trait::async_trait;
use derive_more::derive::{From, Into, TryInto};
use rustical_dav::extension::BoxedExtension;
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
use rustical_dav::extensions::CommonPropertiesProp;
use rustical_dav::privileges::UserPrivilegeSet;
use rustical_dav::resource::{InvalidProperty, Resource, ResourceService};
use rustical_store::auth::User;
@@ -86,7 +85,7 @@ pub enum CalendarProp {
#[serde(skip_deserializing, untagged)]
#[from]
#[try_into]
ExtCommonProperties(CommonPropertiesProp<CalendarResource>),
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
#[serde(untagged)]
Invalid,
@@ -106,12 +105,7 @@ impl Resource for CalendarResource {
type Prop = CalendarProp;
type Error = Error;
type ResourceType = Resourcetype;
fn list_extensions() -> Vec<BoxedExtension<Self>> {
vec![BoxedExtension::from_ext(CommonPropertiesExtension::<
PrincipalResource,
>::default())]
}
type PrincipalResource = PrincipalResource;
fn get_prop(
&self,

View File

@@ -4,8 +4,7 @@ use actix_web::{dev::ResourceMap, web::Data, HttpRequest};
use async_trait::async_trait;
use derive_more::derive::{From, Into, TryInto};
use rustical_dav::{
extension::BoxedExtension,
extensions::{CommonPropertiesExtension, CommonPropertiesProp},
extensions::CommonPropertiesProp,
privileges::UserPrivilegeSet,
resource::{InvalidProperty, Resource, ResourceService},
};
@@ -44,7 +43,7 @@ pub enum CalendarObjectProp {
#[serde(skip_deserializing, untagged)]
#[from]
#[try_into]
ExtCommonProperties(CommonPropertiesProp<CalendarObjectResource>),
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
#[serde(untagged)]
Invalid,
@@ -73,14 +72,9 @@ impl Resource for CalendarObjectResource {
type PropName = CalendarObjectPropName;
type Prop = CalendarObjectProp;
type Error = Error;
type PrincipalResource = PrincipalResource;
type ResourceType = Resourcetype;
fn list_extensions() -> Vec<BoxedExtension<Self>> {
vec![BoxedExtension::from_ext(CommonPropertiesExtension::<
PrincipalResource,
>::default())]
}
fn get_prop(
&self,
_rmap: &ResourceMap,

View File

@@ -5,8 +5,7 @@ use actix_web::web::Data;
use actix_web::HttpRequest;
use async_trait::async_trait;
use derive_more::derive::{From, TryInto};
use rustical_dav::extension::BoxedExtension;
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
use rustical_dav::extensions::CommonPropertiesProp;
use rustical_dav::privileges::UserPrivilegeSet;
use rustical_dav::resource::{InvalidProperty, Resource, ResourceService};
use rustical_dav::xml::HrefElement;
@@ -49,7 +48,7 @@ pub enum PrincipalProp {
#[serde(skip_deserializing, untagged)]
#[from]
#[try_into]
ExtCommonProperties(CommonPropertiesProp<PrincipalResource>),
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
#[serde(untagged)]
Invalid,
@@ -81,12 +80,7 @@ impl Resource for PrincipalResource {
type Prop = PrincipalProp;
type Error = Error;
type ResourceType = Resourcetype;
fn list_extensions() -> Vec<BoxedExtension<Self>> {
vec![BoxedExtension::from_ext(CommonPropertiesExtension::<
PrincipalResource,
>::default())]
}
type PrincipalResource = PrincipalResource;
fn get_prop(
&self,

View File

@@ -3,8 +3,7 @@ use actix_web::{dev::ResourceMap, web::Data, HttpRequest};
use async_trait::async_trait;
use derive_more::derive::{From, Into, TryInto};
use rustical_dav::{
extension::BoxedExtension,
extensions::{CommonPropertiesExtension, CommonPropertiesProp},
extensions::CommonPropertiesProp,
privileges::UserPrivilegeSet,
resource::{InvalidProperty, Resource, ResourceService},
};
@@ -45,7 +44,7 @@ pub enum AddressObjectProp {
#[serde(skip_deserializing, untagged)]
#[from]
#[try_into]
ExtCommonProperties(CommonPropertiesProp<AddressObjectResource>),
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
#[serde(untagged)]
Invalid,
@@ -75,12 +74,7 @@ impl Resource for AddressObjectResource {
type Prop = AddressObjectProp;
type Error = Error;
type ResourceType = Resourcetype;
fn list_extensions() -> Vec<BoxedExtension<Self>> {
vec![BoxedExtension::from_ext(CommonPropertiesExtension::<
PrincipalResource,
>::default())]
}
type PrincipalResource = PrincipalResource;
fn get_prop(
&self,

View File

@@ -10,8 +10,7 @@ use actix_web::web;
use actix_web::{web::Data, HttpRequest};
use async_trait::async_trait;
use derive_more::derive::{From, Into, TryInto};
use rustical_dav::extension::BoxedExtension;
use rustical_dav::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
use rustical_dav::extensions::CommonPropertiesProp;
use rustical_dav::privileges::UserPrivilegeSet;
use rustical_dav::resource::{InvalidProperty, Resource, ResourceService};
use rustical_store::auth::User;
@@ -71,7 +70,7 @@ pub enum AddressbookProp {
#[serde(skip_deserializing, untagged)]
#[from]
#[try_into]
ExtCommonProperties(CommonPropertiesProp<AddressbookResource>),
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
#[serde(untagged)]
Invalid,
@@ -91,12 +90,7 @@ impl Resource for AddressbookResource {
type Prop = AddressbookProp;
type Error = Error;
type ResourceType = Resourcetype;
fn list_extensions() -> Vec<BoxedExtension<Self>> {
vec![BoxedExtension::from_ext(CommonPropertiesExtension::<
PrincipalResource,
>::default())]
}
type PrincipalResource = PrincipalResource;
fn get_prop(
&self,

View File

@@ -49,7 +49,7 @@ pub enum PrincipalProp {
#[serde(skip_deserializing, untagged)]
#[from]
#[try_into]
ExtCommonProperties(CommonPropertiesProp<PrincipalResource>),
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
#[serde(untagged)]
Invalid,
@@ -81,12 +81,7 @@ impl Resource for PrincipalResource {
type Prop = PrincipalProp;
type Error = Error;
type ResourceType = Resourcetype;
fn list_extensions() -> Vec<BoxedExtension<Self>> {
vec![BoxedExtension::from_ext(CommonPropertiesExtension::<
PrincipalResource,
>::default())]
}
type PrincipalResource = PrincipalResource;
fn get_prop(
&self,

View File

@@ -49,10 +49,8 @@ pub trait BoxableExtension<R: Resource> {
fn list_props(&self) -> &'static [&'static str];
}
impl<
R: Resource,
RE: ResourceExtension<R, Prop: Into<R::Prop> + TryFrom<R::Prop>, Error: Into<R::Error>>,
> BoxableExtension<R> for RE
impl<R: Resource, RE: ResourceExtension<R, Prop: Into<R::Prop>, Error: Into<R::Error>>>
BoxableExtension<R> for RE
{
fn get_prop(
&self,
@@ -114,9 +112,7 @@ impl<
pub struct BoxedExtension<R>(Box<dyn BoxableExtension<R>>);
impl<R: Resource> BoxedExtension<R> {
pub fn from_ext<RE: ResourceExtension<R, Prop: Into<R::Prop> + TryFrom<R::Prop>> + 'static>(
ext: RE,
) -> Self {
pub fn from_ext<RE: ResourceExtension<R, Prop: Into<R::Prop>> + 'static>(ext: RE) -> Self {
let boxed_ext: Box<dyn BoxableExtension<R>> = Box::new(ext);
BoxedExtension(boxed_ext)
}

View File

@@ -1,7 +1,7 @@
use crate::{
extension::ResourceExtension,
privileges::UserPrivilegeSet,
resource::{InvalidProperty, Resource},
resource::{InvalidProperty, Resource, ResourceType},
xml::HrefElement,
};
use actix_web::dev::ResourceMap;
@@ -11,9 +11,9 @@ use std::marker::PhantomData;
use strum::{EnumString, VariantNames};
#[derive(Clone)]
pub struct CommonPropertiesExtension<PR: Resource>(PhantomData<PR>);
pub struct CommonPropertiesExtension<R: Resource>(PhantomData<R>);
impl<PR: Resource> Default for CommonPropertiesExtension<PR> {
impl<R: Resource> Default for CommonPropertiesExtension<R> {
fn default() -> Self {
Self(PhantomData)
}
@@ -21,9 +21,10 @@ impl<PR: Resource> Default for CommonPropertiesExtension<PR> {
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum CommonPropertiesProp<R: Resource> {
pub enum CommonPropertiesProp<RT: ResourceType> {
// WebDAV (RFC 2518)
Resourcetype(R::ResourceType),
#[serde(skip_deserializing)]
Resourcetype(RT),
// WebDAV Current Principal Extension (RFC 5397)
CurrentUserPrincipal(HrefElement),
@@ -36,7 +37,7 @@ pub enum CommonPropertiesProp<R: Resource> {
Invalid,
}
impl<R: Resource> InvalidProperty for CommonPropertiesProp<R> {
impl<RT: ResourceType> InvalidProperty for CommonPropertiesProp<RT> {
fn invalid_property(&self) -> bool {
matches!(self, Self::Invalid)
}
@@ -51,11 +52,11 @@ pub enum CommonPropertiesPropName {
Owner,
}
impl<R: Resource, PR: Resource> ResourceExtension<R> for CommonPropertiesExtension<PR>
impl<R: Resource> ResourceExtension<R> for CommonPropertiesExtension<R>
where
R::Prop: From<CommonPropertiesProp<R>>,
R::Prop: From<CommonPropertiesProp<R::ResourceType>>,
{
type Prop = CommonPropertiesProp<R>;
type Prop = CommonPropertiesProp<R::ResourceType>;
type PropName = CommonPropertiesPropName;
type Error = R::Error;
@@ -72,17 +73,21 @@ where
}
CommonPropertiesPropName::CurrentUserPrincipal => {
CommonPropertiesProp::CurrentUserPrincipal(
PR::get_url(rmap, &[&user.id]).unwrap().into(),
R::PrincipalResource::get_url(rmap, &[&user.id])
.unwrap()
.into(),
)
}
CommonPropertiesPropName::CurrentUserPrivilegeSet => {
CommonPropertiesProp::CurrentUserPrivilegeSet(resource.get_user_privileges(user)?)
}
CommonPropertiesPropName::Owner => CommonPropertiesProp::Owner(
resource
.get_owner()
.map(|owner| PR::get_url(rmap, &[owner]).unwrap().into()),
),
CommonPropertiesPropName::Owner => {
CommonPropertiesProp::Owner(resource.get_owner().map(|owner| {
R::PrincipalResource::get_url(rmap, &[owner])
.unwrap()
.into()
}))
}
})
}
}

View File

@@ -1,4 +1,5 @@
use crate::extension::BoxedExtension;
use crate::extension::{BoxableExtension, BoxedExtension};
use crate::extensions::{CommonPropertiesExtension, CommonPropertiesProp};
use crate::methods::{route_delete, route_propfind, route_proppatch};
use crate::privileges::UserPrivilegeSet;
use crate::xml::multistatus::{PropTagWrapper, PropstatElement, PropstatWrapper};
@@ -26,14 +27,20 @@ impl<T: ResourceReadProp + for<'de> Deserialize<'de>> ResourceProp for T {}
pub trait ResourcePropName: FromStr + VariantNames {}
impl<T: FromStr + VariantNames> ResourcePropName for T {}
pub trait ResourceType: Serialize + for<'de> Deserialize<'de> {}
impl<T: Serialize + for<'de> Deserialize<'de>> ResourceType for T {}
pub trait Resource: Clone + 'static {
type PropName: ResourcePropName;
type Prop: ResourceProp;
type Prop: ResourceProp + From<CommonPropertiesProp<Self::ResourceType>>;
type Error: ResponseError + From<crate::Error>;
type PrincipalResource: Resource;
type ResourceType: Default + Serialize + for<'de> Deserialize<'de>;
fn list_extensions() -> Vec<BoxedExtension<Self>> {
vec![]
vec![BoxedExtension::from_ext(
CommonPropertiesExtension::<Self>::default(),
)]
}
fn list_props() -> Vec<&'static str> {

View File

@@ -30,13 +30,14 @@ impl<PR: Resource> Default for RootResource<PR> {
impl<PR: Resource> Resource for RootResource<PR> {
type PropName = CommonPropertiesPropName;
type Prop = CommonPropertiesProp<RootResource<PR>>;
type Prop = CommonPropertiesProp<Self::ResourceType>;
type Error = PR::Error;
type ResourceType = Resourcetype;
type PrincipalResource = PR;
fn list_extensions() -> Vec<BoxedExtension<Self>> {
vec![BoxedExtension::from_ext(
CommonPropertiesExtension::<PR>::default(),
CommonPropertiesExtension::<Self>::default(),
)]
}