diff --git a/crates/caldav/src/calendar_object/methods.rs b/crates/caldav/src/calendar_object/methods.rs index cf931b0..5001ce5 100644 --- a/crates/caldav/src/calendar_object/methods.rs +++ b/crates/caldav/src/calendar_object/methods.rs @@ -11,14 +11,20 @@ use rustical_store::CalendarStore; use tracing::instrument; use tracing_actix_web::RootSpan; -#[instrument(parent = root_span.id(), skip(context, path, root_span))] +use super::resource::CalendarObjectPathComponents; + +#[instrument(parent = root_span.id(), skip(context, root_span))] pub async fn get_event( context: Data>, - path: Path<(String, String, String)>, + path: Path, user: User, root_span: RootSpan, ) -> Result { - let (principal, cid, mut uid) = path.into_inner(); + let CalendarObjectPathComponents { + principal, + cid, + uid, + } = path.into_inner(); if user.id != principal { return Ok(HttpResponse::Unauthorized().body("")); @@ -34,9 +40,6 @@ pub async fn get_event( return Ok(HttpResponse::Unauthorized().body("")); } - if uid.ends_with(".ics") { - uid.truncate(uid.len() - 4); - } let event = context .store .read() @@ -50,16 +53,21 @@ pub async fn get_event( .body(event.get_ics().to_owned())) } -#[instrument(parent = root_span.id(), skip(context, path, req, root_span))] +#[instrument(parent = root_span.id(), skip(context, req, root_span))] pub async fn put_event( context: Data>, - path: Path<(String, String, String)>, + path: Path, body: String, user: User, req: HttpRequest, root_span: RootSpan, ) -> Result { - let (principal, cid, mut uid) = path.into_inner(); + let CalendarObjectPathComponents { + principal, + cid, + uid, + } = path.into_inner(); + if user.id != principal { return Ok(HttpResponse::Unauthorized().body("")); } @@ -73,10 +81,6 @@ pub async fn put_event( if user.id != calendar.principal { return Ok(HttpResponse::Unauthorized().body("")); } - // Incredibly bodged method of normalising the uid but works for a prototype - if uid.ends_with(".ics") { - uid.truncate(uid.len() - 4); - } // TODO: implement If-Match diff --git a/crates/caldav/src/calendar_object/resource.rs b/crates/caldav/src/calendar_object/resource.rs index 687a0b2..18bf803 100644 --- a/crates/caldav/src/calendar_object/resource.rs +++ b/crates/caldav/src/calendar_object/resource.rs @@ -75,9 +75,34 @@ impl Resource for CalendarObjectResource { } } +#[derive(Debug, Clone)] +pub struct CalendarObjectPathComponents { + pub principal: String, + pub cid: String, + pub uid: String, +} + +impl<'de> Deserialize<'de> for CalendarObjectPathComponents { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + type Inner = (String, String, String); + let (principal, calendar, mut object) = Inner::deserialize(deserializer)?; + if object.ends_with(".ics") { + object.truncate(object.len() - 4); + } + Ok(Self { + principal, + cid: calendar, + uid: object, + }) + } +} + #[async_trait(?Send)] impl ResourceService for CalendarObjectResourceService { - type PathComponents = (String, String, String); // principal, calendar, event + type PathComponents = CalendarObjectPathComponents; type Resource = CalendarObjectResource; type MemberType = CalendarObjectResource; type Error = Error; @@ -86,11 +111,11 @@ impl ResourceService for CalendarObjectResourceServic req: &HttpRequest, path_components: Self::PathComponents, ) -> Result { - let (principal, cid, mut uid) = path_components; - - if uid.ends_with(".ics") { - uid.truncate(uid.len() - 4); - } + let CalendarObjectPathComponents { + principal, + cid, + uid, + } = path_components; let cal_store = req .app_data::>>()