Refactor how ResourceService works

This commit is contained in:
Lennart
2025-01-04 14:24:01 +01:00
parent 40c8624703
commit c19e4745f9
16 changed files with 203 additions and 250 deletions

View File

@@ -1,3 +1,2 @@
pub mod mkcalendar;
pub mod post;
pub mod report;

View File

@@ -1,15 +0,0 @@
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"
}

View File

@@ -1,9 +1,7 @@
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, Transports,
SupportedCalendarComponentSet, SupportedCalendarData, SupportedReportSet, Transports,
};
use crate::calendar_object::resource::CalendarObjectResource;
use crate::principal::PrincipalResource;
@@ -11,7 +9,6 @@ use crate::Error;
use actix_web::dev::ResourceMap;
use actix_web::http::Method;
use actix_web::web;
use actix_web::{web::Data, HttpRequest};
use async_trait::async_trait;
use derive_more::derive::{From, Into};
use rustical_dav::privileges::UserPrivilegeSet;
@@ -27,8 +24,12 @@ use strum::{EnumDiscriminants, EnumString, IntoStaticStr, VariantNames};
pub struct CalendarResourceService<C: CalendarStore + ?Sized> {
cal_store: Arc<C>,
principal: String,
calendar_id: String,
}
impl<C: CalendarStore + ?Sized> CalendarResourceService<C> {
pub fn new(cal_store: Arc<C>) -> Self {
Self { cal_store }
}
}
#[derive(XmlDeserialize, XmlSerialize, PartialEq, EnumDiscriminants, Clone)]
@@ -243,10 +244,13 @@ impl<C: CalendarStore + ?Sized> ResourceService for CalendarResourceService<C> {
type Resource = CalendarResource;
type Error = Error;
async fn get_resource(&self) -> Result<Self::Resource, Error> {
async fn get_resource(
&self,
(principal, cal_id): &Self::PathComponents,
) -> Result<Self::Resource, Error> {
let calendar = self
.cal_store
.get_calendar(&self.principal, &self.calendar_id)
.get_calendar(principal, cal_id)
.await
.map_err(|_e| Error::NotFound)?;
Ok(calendar.into())
@@ -254,60 +258,45 @@ impl<C: CalendarStore + ?Sized> ResourceService for CalendarResourceService<C> {
async fn get_members(
&self,
(principal, cal_id): &Self::PathComponents,
rmap: &ResourceMap,
) -> Result<Vec<(String, Self::MemberType)>, Self::Error> {
Ok(self
.cal_store
.get_objects(&self.principal, &self.calendar_id)
.get_objects(principal, cal_id)
.await?
.into_iter()
.map(|object| {
(
CalendarObjectResource::get_url(
rmap,
vec![&self.principal, &self.calendar_id, object.get_id()],
)
.unwrap(),
CalendarObjectResource::get_url(rmap, vec![principal, cal_id, object.get_id()])
.unwrap(),
CalendarObjectResource {
object,
principal: self.principal.to_owned(),
principal: principal.to_owned(),
},
)
})
.collect())
}
async fn new(
req: &HttpRequest,
path_components: Self::PathComponents,
) -> Result<Self, Self::Error> {
let cal_store = req
.app_data::<Data<C>>()
.expect("no calendar store in app_data!")
.clone()
.into_inner();
Ok(Self {
principal: path_components.0,
calendar_id: path_components.1,
cal_store,
})
}
async fn save_resource(&self, file: Self::Resource) -> Result<(), Self::Error> {
async fn save_resource(
&self,
(principal, cal_id): &Self::PathComponents,
file: Self::Resource,
) -> Result<(), Self::Error> {
self.cal_store
.update_calendar(
self.principal.to_owned(),
self.calendar_id.to_owned(),
file.into(),
)
.update_calendar(principal.to_owned(), cal_id.to_owned(), file.into())
.await?;
Ok(())
}
async fn delete_resource(&self, use_trashbin: bool) -> Result<(), Self::Error> {
async fn delete_resource(
&self,
(principal, cal_id): &Self::PathComponents,
use_trashbin: bool,
) -> Result<(), Self::Error> {
self.cal_store
.delete_calendar(&self.principal, &self.calendar_id, use_trashbin)
.delete_calendar(principal, cal_id, use_trashbin)
.await?;
Ok(())
}
@@ -319,6 +308,5 @@ 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>)
}
}

View File

@@ -1,6 +1,6 @@
use super::methods::{get_event, put_event};
use crate::{principal::PrincipalResource, Error};
use actix_web::{dev::ResourceMap, web::Data, HttpRequest};
use actix_web::dev::ResourceMap;
use async_trait::async_trait;
use derive_more::derive::{From, Into};
use rustical_dav::{
@@ -15,9 +15,12 @@ use strum::{EnumDiscriminants, EnumString, IntoStaticStr, VariantNames};
pub struct CalendarObjectResourceService<C: CalendarStore + ?Sized> {
cal_store: Arc<C>,
principal: String,
cal_id: String,
object_id: String,
}
impl<C: CalendarStore + ?Sized> CalendarObjectResourceService<C> {
pub fn new(cal_store: Arc<C>) -> Self {
Self { cal_store }
}
}
#[derive(XmlDeserialize, XmlSerialize, PartialEq, EnumDiscriminants, Clone)]
@@ -117,44 +120,35 @@ impl<C: CalendarStore + ?Sized> ResourceService for CalendarObjectResourceServic
type MemberType = CalendarObjectResource;
type Error = Error;
async fn new(
req: &HttpRequest,
path_components: Self::PathComponents,
) -> Result<Self, Self::Error> {
let CalendarObjectPathComponents {
async fn get_resource(
&self,
CalendarObjectPathComponents {
principal,
cal_id,
object_id,
} = path_components;
let cal_store = req
.app_data::<Data<C>>()
.expect("no calendar store in app_data!")
.clone()
.into_inner();
Ok(Self {
cal_store,
principal,
cal_id,
object_id,
})
}
async fn get_resource(&self) -> Result<Self::Resource, Self::Error> {
}: &Self::PathComponents,
) -> Result<Self::Resource, Self::Error> {
let object = self
.cal_store
.get_object(&self.principal, &self.cal_id, &self.object_id)
.get_object(principal, cal_id, object_id)
.await?;
Ok(CalendarObjectResource {
object,
principal: self.principal.to_owned(),
principal: principal.to_owned(),
})
}
async fn delete_resource(&self, use_trashbin: bool) -> Result<(), Self::Error> {
async fn delete_resource(
&self,
CalendarObjectPathComponents {
principal,
cal_id,
object_id,
}: &Self::PathComponents,
use_trashbin: bool,
) -> Result<(), Self::Error> {
self.cal_store
.delete_object(&self.principal, &self.cal_id, &self.object_id, use_trashbin)
.delete_object(principal, cal_id, object_id, use_trashbin)
.await?;
Ok(())
}

View File

@@ -52,17 +52,21 @@ pub fn configure_dav<AP: AuthenticationProvider, C: CalendarStore + ?Sized>(
}),
)
.app_data(Data::from(store.clone()))
.service(RootResourceService::<PrincipalResource>::actix_resource())
.service(RootResourceService::<PrincipalResource>::default().actix_resource())
.service(
web::scope("/user").service(
web::scope("/{principal}")
.service(PrincipalResourceService::<C>::actix_resource())
.service(PrincipalResourceService::<C>::new(store.clone()).actix_resource())
.service(
web::scope("/{calendar}")
.service(CalendarResourceService::<C>::actix_resource())
.service(
CalendarResourceService::<C>::new(store.clone())
.actix_resource(),
)
.service(
web::scope("/{object}").service(
CalendarObjectResourceService::<C>::actix_resource(),
CalendarObjectResourceService::<C>::new(store.clone())
.actix_resource(),
),
),
),

View File

@@ -1,8 +1,6 @@
use crate::calendar::resource::CalendarResource;
use crate::Error;
use actix_web::dev::ResourceMap;
use actix_web::web::Data;
use actix_web::HttpRequest;
use async_trait::async_trait;
use rustical_dav::privileges::UserPrivilegeSet;
use rustical_dav::resource::{Resource, ResourceService};
@@ -14,10 +12,15 @@ use std::sync::Arc;
use strum::{EnumDiscriminants, EnumString, IntoStaticStr, VariantNames};
pub struct PrincipalResourceService<C: CalendarStore + ?Sized> {
principal: String,
cal_store: Arc<C>,
}
impl<C: CalendarStore + ?Sized> PrincipalResourceService<C> {
pub fn new(cal_store: Arc<C>) -> Self {
Self { cal_store }
}
}
#[derive(Clone)]
pub struct PrincipalResource {
principal: String,
@@ -96,38 +99,26 @@ impl<C: CalendarStore + ?Sized> ResourceService for PrincipalResourceService<C>
type Resource = PrincipalResource;
type Error = Error;
async fn new(
req: &HttpRequest,
(principal,): Self::PathComponents,
) -> Result<Self, Self::Error> {
let cal_store = req
.app_data::<Data<C>>()
.expect("no calendar store in app_data!")
.clone()
.into_inner();
Ok(Self {
cal_store,
principal,
})
}
async fn get_resource(&self) -> Result<Self::Resource, Self::Error> {
async fn get_resource(
&self,
(principal,): &Self::PathComponents,
) -> Result<Self::Resource, Self::Error> {
Ok(PrincipalResource {
principal: self.principal.to_owned(),
principal: principal.to_owned(),
})
}
async fn get_members(
&self,
(principal,): &Self::PathComponents,
rmap: &ResourceMap,
) -> Result<Vec<(String, Self::MemberType)>, Self::Error> {
let calendars = self.cal_store.get_calendars(&self.principal).await?;
let calendars = self.cal_store.get_calendars(principal).await?;
Ok(calendars
.into_iter()
.map(|cal| {
(
CalendarResource::get_url(rmap, vec![&self.principal, &cal.id]).unwrap(),
CalendarResource::get_url(rmap, vec![principal, &cal.id]).unwrap(),
cal.into(),
)
})