mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 21:42:34 +00:00
changes around extensions
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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(),
|
||||
)]
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user