From 38f5338ceb425a834a8e7c93fb415d9efca968fa Mon Sep 17 00:00:00 2001 From: Lennart <18233294+lennart-k@users.noreply.github.com> Date: Sat, 25 May 2024 22:19:38 +0200 Subject: [PATCH] Make prefix a parameter to decrease chaos --- crates/caldav/src/resources/calendar.rs | 11 +++-------- crates/caldav/src/resources/event.rs | 3 +-- crates/caldav/src/resources/principal.rs | 16 +++++----------- crates/caldav/src/resources/root.rs | 9 ++------- crates/caldav/src/routes/calendar.rs | 8 ++++++-- crates/dav/src/dav_resource.rs | 8 ++++---- crates/dav/src/propfind.rs | 6 +++--- 7 files changed, 24 insertions(+), 37 deletions(-) diff --git a/crates/caldav/src/resources/calendar.rs b/crates/caldav/src/resources/calendar.rs index 19e684a..d035a72 100644 --- a/crates/caldav/src/resources/calendar.rs +++ b/crates/caldav/src/resources/calendar.rs @@ -14,7 +14,6 @@ use tokio::sync::RwLock; pub struct CalendarResource { pub cal_store: Arc>, pub path: String, - pub prefix: String, pub principal: String, pub calendar_id: String, } @@ -160,7 +159,6 @@ pub enum CalendarPropResponse { pub struct CalendarFile { pub calendar: Calendar, pub principal: String, - pub prefix: String, pub path: String, } @@ -168,17 +166,17 @@ impl Resource for CalendarFile { type PropType = CalendarProp; type PropResponse = CalendarPropResponse; - fn get_prop(&self, prop: Self::PropType) -> Result { + fn get_prop(&self, prefix: &str, prop: Self::PropType) -> Result { match prop { CalendarProp::Resourcetype => { Ok(CalendarPropResponse::Resourcetype(Resourcetype::default())) } CalendarProp::CurrentUserPrincipal => Ok(CalendarPropResponse::CurrentUserPrincipal( - HrefElement::new(format!("{}/{}/", self.prefix, self.principal)), + HrefElement::new(format!("{}/{}/", prefix, self.principal)), )), CalendarProp::Owner => Ok(CalendarPropResponse::Owner(HrefElement::new(format!( "{}/{}/", - self.prefix, self.principal + prefix, self.principal )))), CalendarProp::Displayname => Ok(CalendarPropResponse::Displayname(TextNode( self.calendar.name.clone(), @@ -232,7 +230,6 @@ impl ResourceService for CalendarResource { .map_err(|_e| Error::NotFound)?; Ok(CalendarFile { calendar, - prefix: self.prefix.to_owned(), principal: self.principal.to_owned(), path: self.path.to_owned(), }) @@ -247,7 +244,6 @@ impl ResourceService for CalendarResource { req: HttpRequest, auth_info: AuthInfo, path_components: Self::PathComponents, - prefix: String, ) -> Result { let cal_store = req .app_data::>>() @@ -256,7 +252,6 @@ impl ResourceService for CalendarResource { .into_inner(); Ok(Self { - prefix, path: req.path().to_owned(), principal: auth_info.user_id, calendar_id: path_components.1, diff --git a/crates/caldav/src/resources/event.rs b/crates/caldav/src/resources/event.rs index e08e61b..4e2bb48 100644 --- a/crates/caldav/src/resources/event.rs +++ b/crates/caldav/src/resources/event.rs @@ -47,7 +47,7 @@ impl Resource for EventFile { "asd" } - fn get_prop(&self, prop: Self::PropType) -> Result { + fn get_prop(&self, _prefix: &str, prop: Self::PropType) -> Result { match prop { EventProp::Getetag => Ok(PrincipalPropResponse::Getetag(TextNode(Some( self.event.get_etag(), @@ -76,7 +76,6 @@ impl ResourceService for EventResource { req: HttpRequest, _auth_info: AuthInfo, path_components: Self::PathComponents, - _prefix: String, ) -> Result { let (_principal, cid, uid) = path_components; diff --git a/crates/caldav/src/resources/principal.rs b/crates/caldav/src/resources/principal.rs index 2495ec7..1f6935e 100644 --- a/crates/caldav/src/resources/principal.rs +++ b/crates/caldav/src/resources/principal.rs @@ -15,14 +15,12 @@ use tokio::sync::RwLock; use super::calendar::CalendarFile; pub struct PrincipalResource { - prefix: String, principal: String, path: String, cal_store: Arc>, } pub struct PrincipalFile { - prefix: String, principal: String, path: String, } @@ -63,23 +61,23 @@ impl Resource for PrincipalFile { type PropType = PrincipalProp; type PropResponse = PrincipalPropResponse; - fn get_prop(&self, prop: Self::PropType) -> Result { + fn get_prop(&self, prefix: &str, prop: Self::PropType) -> Result { match prop { PrincipalProp::Resourcetype => { Ok(PrincipalPropResponse::Resourcetype(Resourcetype::default())) } PrincipalProp::CurrentUserPrincipal => Ok(PrincipalPropResponse::CurrentUserPrincipal( - HrefElement::new(format!("{}/{}/", self.prefix, self.principal)), + HrefElement::new(format!("{}/{}/", prefix, self.principal)), )), PrincipalProp::PrincipalUrl => Ok(PrincipalPropResponse::PrincipalUrl( - HrefElement::new(format!("{}/{}/", self.prefix, self.principal)), + HrefElement::new(format!("{}/{}/", prefix, self.principal)), )), PrincipalProp::CalendarHomeSet => Ok(PrincipalPropResponse::CalendarHomeSet( - HrefElement::new(format!("{}/{}/", self.prefix, self.principal)), + HrefElement::new(format!("{}/{}/", prefix, self.principal)), )), PrincipalProp::CalendarUserAddressSet => { Ok(PrincipalPropResponse::CalendarUserAddressSet( - HrefElement::new(format!("{}/{}/", self.prefix, self.principal)), + HrefElement::new(format!("{}/{}/", prefix, self.principal)), )) } } @@ -100,7 +98,6 @@ impl ResourceService for PrincipalResource { req: HttpRequest, auth_info: AuthInfo, _path_components: Self::PathComponents, - prefix: String, ) -> Result { let cal_store = req .app_data::>>() @@ -112,14 +109,12 @@ impl ResourceService for PrincipalResource { cal_store, path: req.path().to_owned(), principal: auth_info.user_id, - prefix, }) } async fn get_file(&self) -> Result { Ok(PrincipalFile { principal: self.principal.to_owned(), - prefix: self.prefix.to_owned(), path: self.path.to_owned(), }) } @@ -136,7 +131,6 @@ impl ResourceService for PrincipalResource { .map(|cal| CalendarFile { calendar: cal, principal: self.principal.to_owned(), - prefix: self.prefix.to_owned(), path: self.path.to_owned(), }) .collect()) diff --git a/crates/caldav/src/resources/root.rs b/crates/caldav/src/resources/root.rs index fa38f6d..dfebb27 100644 --- a/crates/caldav/src/resources/root.rs +++ b/crates/caldav/src/resources/root.rs @@ -9,7 +9,6 @@ use serde::Serialize; use strum::{EnumString, IntoStaticStr, VariantNames}; pub struct RootResource { - prefix: String, principal: String, path: String, } @@ -35,7 +34,6 @@ pub enum RootPropResponse { } pub struct RootFile { - pub prefix: String, pub principal: String, pub path: String, } @@ -44,11 +42,11 @@ impl Resource for RootFile { type PropType = RootProp; type PropResponse = RootPropResponse; - fn get_prop(&self, prop: Self::PropType) -> Result { + fn get_prop(&self, prefix: &str, prop: Self::PropType) -> Result { match prop { RootProp::Resourcetype => Ok(RootPropResponse::Resourcetype(Resourcetype::default())), RootProp::CurrentUserPrincipal => Ok(RootPropResponse::CurrentUserPrincipal( - HrefElement::new(format!("{}/{}/", self.prefix, self.principal)), + HrefElement::new(format!("{}/{}/", prefix, self.principal)), )), } } @@ -72,10 +70,8 @@ impl ResourceService for RootResource { req: HttpRequest, auth_info: AuthInfo, _path_components: Self::PathComponents, - prefix: String, ) -> Result { Ok(Self { - prefix, principal: auth_info.user_id, path: req.path().to_string(), }) @@ -85,7 +81,6 @@ impl ResourceService for RootResource { Ok(RootFile { path: self.path.to_owned(), principal: self.principal.to_owned(), - prefix: self.prefix.to_owned(), }) } } diff --git a/crates/caldav/src/routes/calendar.rs b/crates/caldav/src/routes/calendar.rs index 303d911..ce84534 100644 --- a/crates/caldav/src/routes/calendar.rs +++ b/crates/caldav/src/routes/calendar.rs @@ -9,6 +9,7 @@ use roxmltree::{Node, NodeType}; use rustical_auth::{AuthInfoExtractor, CheckAuthentication}; use rustical_dav::dav_resource::HandlePropfind; use rustical_dav::namespace::Namespace; +use rustical_dav::propfind::ServicePrefix; use rustical_dav::xml_snippets::generate_multistatus; use rustical_store::calendar::{Calendar, CalendarStore}; use rustical_store::event::Event; @@ -39,6 +40,7 @@ async fn handle_report_calendar_query( _request: HttpRequest, events: Vec, _cal_store: Arc>, + prefix: &str, ) -> Result { let prop_node = query_node .children() @@ -62,7 +64,7 @@ async fn handle_report_calendar_query( .collect(); let mut event_responses = Vec::new(); for event_file in event_files { - event_responses.push(event_file.propfind(props.clone()).await?); + event_responses.push(event_file.propfind(prefix, props.clone()).await?); } // let event_results: Result, _> = event_files // .iter() @@ -90,9 +92,11 @@ pub async fn route_report_calendar, request: HttpRequest, _auth: AuthInfoExtractor, + prefix: Data, ) -> Result { // TODO: Check authorization let (_principal, cid) = path.into_inner(); + let prefix = &prefix.0; let doc = roxmltree::Document::parse(&body).map_err(|_e| Error::BadRequest)?; let query_node = doc.root_element(); @@ -104,7 +108,7 @@ pub async fn route_report_calendar {} _ => return Err(Error::BadRequest), }; - handle_report_calendar_query(query_node, request, events, context.store.clone()).await + handle_report_calendar_query(query_node, request, events, context.store.clone(), prefix).await } pub async fn handle_mkcol_calendar_set( diff --git a/crates/dav/src/dav_resource.rs b/crates/dav/src/dav_resource.rs index 2c89167..903f343 100644 --- a/crates/dav/src/dav_resource.rs +++ b/crates/dav/src/dav_resource.rs @@ -17,7 +17,7 @@ pub trait Resource { Self::PropType::VARIANTS } - fn get_prop(&self, prop: Self::PropType) -> Result; + fn get_prop(&self, prefix: &str, prop: Self::PropType) -> Result; fn get_path(&self) -> &str; } @@ -36,7 +36,6 @@ pub trait ResourceService: Sized { req: HttpRequest, auth_info: AuthInfo, path_components: Self::PathComponents, - prefix: String, ) -> Result; async fn get_file(&self) -> Result; @@ -73,13 +72,14 @@ enum PropstatType { #[async_trait(?Send)] pub trait HandlePropfind { - async fn propfind(&self, props: Vec<&str>) -> Result; + async fn propfind(&self, prefix: &str, props: Vec<&str>) -> Result; } #[async_trait(?Send)] impl HandlePropfind for R { async fn propfind( &self, + prefix: &str, props: Vec<&str>, ) -> Result>, TagList>> { let mut props = props.into_iter().unique().collect_vec(); @@ -95,7 +95,7 @@ impl HandlePropfind for R { let mut prop_responses = Vec::new(); for prop in props { if let Ok(valid_prop) = R::PropType::from_str(prop) { - match self.get_prop(valid_prop.clone()) { + match self.get_prop(prefix, valid_prop.clone()) { Ok(response) => { prop_responses.push(response); } diff --git a/crates/dav/src/propfind.rs b/crates/dav/src/propfind.rs index 909f5a8..3ec6f26 100644 --- a/crates/dav/src/propfind.rs +++ b/crates/dav/src/propfind.rs @@ -87,15 +87,15 @@ pub async fn handle_propfind< let prefix = prefix.0.to_owned(); let path_components = path.into_inner(); - let resource_service = R::new(req, auth_info.clone(), path_components.clone(), prefix).await?; + let resource_service = R::new(req, auth_info.clone(), path_components.clone()).await?; let resource = resource_service.get_file().await?; - let response = resource.propfind(props.clone()).await?; + let response = resource.propfind(&prefix, props.clone()).await?; let mut member_responses = Vec::new(); if depth != Depth::Zero { for member in resource_service.get_members(auth_info).await? { - member_responses.push(member.propfind(props.clone()).await?); + member_responses.push(member.propfind(&prefix, props.clone()).await?); } }