From f9de8a4687f3d761c78732cf342651c944eadfc2 Mon Sep 17 00:00:00 2001 From: Lennart <18233294+lennart-k@users.noreply.github.com> Date: Mon, 23 Jun 2025 16:35:36 +0200 Subject: [PATCH] feat: Add show_deleted to get_calendar --- ...1de5293be332d86cf643977d479999542553.json} | 6 ++--- crates/caldav/src/calendar/methods/get.rs | 8 ++++-- crates/caldav/src/calendar/methods/post.rs | 2 +- crates/caldav/src/calendar/service.rs | 5 +++- crates/caldav/src/calendar_object/methods.rs | 4 ++- crates/frontend/src/routes/calendar.rs | 2 +- crates/store/src/calendar_store.rs | 7 ++++- crates/store/src/combined_calendar_store.rs | 18 +++++++++---- crates/store/src/contact_birthday_store.rs | 10 +++++-- crates/store_sqlite/src/calendar_store.rs | 27 +++++++++++++------ 10 files changed, 64 insertions(+), 25 deletions(-) rename .sqlx/{query-9f930775043a6d4571a8ffd5a981cadf7c51f3f11a189f8461505abec31076e6.json => query-bb2fa030f2e7c7afdb38c5c54cb31de5293be332d86cf643977d479999542553.json} (90%) diff --git a/.sqlx/query-9f930775043a6d4571a8ffd5a981cadf7c51f3f11a189f8461505abec31076e6.json b/.sqlx/query-bb2fa030f2e7c7afdb38c5c54cb31de5293be332d86cf643977d479999542553.json similarity index 90% rename from .sqlx/query-9f930775043a6d4571a8ffd5a981cadf7c51f3f11a189f8461505abec31076e6.json rename to .sqlx/query-bb2fa030f2e7c7afdb38c5c54cb31de5293be332d86cf643977d479999542553.json index db153f5..4c94dd4 100644 --- a/.sqlx/query-9f930775043a6d4571a8ffd5a981cadf7c51f3f11a189f8461505abec31076e6.json +++ b/.sqlx/query-bb2fa030f2e7c7afdb38c5c54cb31de5293be332d86cf643977d479999542553.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT *\n FROM calendars\n WHERE (principal, id) = (?, ?)", + "query": "SELECT *\n FROM calendars\n WHERE (principal, id) = (?, ?)\n AND ((deleted_at IS NULL) OR ?) ", "describe": { "columns": [ { @@ -80,7 +80,7 @@ } ], "parameters": { - "Right": 2 + "Right": 3 }, "nullable": [ false, @@ -100,5 +100,5 @@ false ] }, - "hash": "9f930775043a6d4571a8ffd5a981cadf7c51f3f11a189f8461505abec31076e6" + "hash": "bb2fa030f2e7c7afdb38c5c54cb31de5293be332d86cf643977d479999542553" } diff --git a/crates/caldav/src/calendar/methods/get.rs b/crates/caldav/src/calendar/methods/get.rs index 73addab..eaafdda 100644 --- a/crates/caldav/src/calendar/methods/get.rs +++ b/crates/caldav/src/calendar/methods/get.rs @@ -24,12 +24,16 @@ pub async fn route_get( return Err(crate::Error::Unauthorized); } - let calendar = cal_store.get_calendar(&principal, &calendar_id).await?; + let calendar = cal_store + .get_calendar(&principal, &calendar_id, true) + .await?; if !user.is_principal(&calendar.principal) { return Err(crate::Error::Unauthorized); } - let calendar = cal_store.get_calendar(&principal, &calendar_id).await?; + let calendar = cal_store + .get_calendar(&principal, &calendar_id, true) + .await?; let mut timezones = HashMap::new(); let objects = cal_store.get_objects(&principal, &calendar_id).await?; diff --git a/crates/caldav/src/calendar/methods/post.rs b/crates/caldav/src/calendar/methods/post.rs index cc7536c..f246ea2 100644 --- a/crates/caldav/src/calendar/methods/post.rs +++ b/crates/caldav/src/calendar/methods/post.rs @@ -25,7 +25,7 @@ pub async fn route_post( let calendar = resource_service .cal_store - .get_calendar(&principal, &cal_id) + .get_calendar(&principal, &cal_id, false) .await?; let calendar_resource = CalendarResource { cal: calendar, diff --git a/crates/caldav/src/calendar/service.rs b/crates/caldav/src/calendar/service.rs index e4eb2d7..65e6194 100644 --- a/crates/caldav/src/calendar/service.rs +++ b/crates/caldav/src/calendar/service.rs @@ -57,7 +57,10 @@ impl ResourceService for CalendarResourc &self, (principal, cal_id): &Self::PathComponents, ) -> Result { - let calendar = self.cal_store.get_calendar(principal, cal_id).await?; + let calendar = self + .cal_store + .get_calendar(principal, cal_id, false) + .await?; Ok(CalendarResource { cal: calendar, read_only: self.cal_store.is_read_only(cal_id), diff --git a/crates/caldav/src/calendar_object/methods.rs b/crates/caldav/src/calendar_object/methods.rs index 3ee4fd1..13d6e3e 100644 --- a/crates/caldav/src/calendar_object/methods.rs +++ b/crates/caldav/src/calendar_object/methods.rs @@ -27,7 +27,9 @@ pub async fn get_event( return Err(crate::Error::Unauthorized); } - let calendar = cal_store.get_calendar(&principal, &calendar_id).await?; + let calendar = cal_store + .get_calendar(&principal, &calendar_id, false) + .await?; if !user.is_principal(&calendar.principal) { return Err(crate::Error::Unauthorized); } diff --git a/crates/frontend/src/routes/calendar.rs b/crates/frontend/src/routes/calendar.rs index 505c107..617dcb1 100644 --- a/crates/frontend/src/routes/calendar.rs +++ b/crates/frontend/src/routes/calendar.rs @@ -27,7 +27,7 @@ pub async fn route_calendar( return Ok(StatusCode::UNAUTHORIZED.into_response()); } Ok(CalendarPage { - calendar: store.get_calendar(&owner, &cal_id).await?, + calendar: store.get_calendar(&owner, &cal_id, true).await?, } .into_response()) } diff --git a/crates/store/src/calendar_store.rs b/crates/store/src/calendar_store.rs index 20e4c21..ffed079 100644 --- a/crates/store/src/calendar_store.rs +++ b/crates/store/src/calendar_store.rs @@ -11,7 +11,12 @@ pub struct CalendarQuery { #[async_trait] pub trait CalendarStore: Send + Sync + 'static { - async fn get_calendar(&self, principal: &str, id: &str) -> Result; + async fn get_calendar( + &self, + principal: &str, + id: &str, + show_deleted: bool, + ) -> Result; async fn get_calendars(&self, principal: &str) -> Result, Error>; async fn get_deleted_calendars(&self, principal: &str) -> Result, Error>; diff --git a/crates/store/src/combined_calendar_store.rs b/crates/store/src/combined_calendar_store.rs index e476fa7..b86c527 100644 --- a/crates/store/src/combined_calendar_store.rs +++ b/crates/store/src/combined_calendar_store.rs @@ -1,8 +1,7 @@ -use std::sync::Arc; - use async_trait::async_trait; use derive_more::Constructor; use rustical_ical::CalendarObject; +use std::sync::Arc; use crate::{ Calendar, CalendarStore, Error, calendar_store::CalendarQuery, @@ -27,11 +26,20 @@ impl Clone for CombinedCalendarStore CalendarStore for CombinedCalendarStore { #[inline] - async fn get_calendar(&self, principal: &str, id: &str) -> Result { + async fn get_calendar( + &self, + principal: &str, + id: &str, + show_deleted: bool, + ) -> Result { if id.starts_with(BIRTHDAYS_PREFIX) { - self.birthday_store.get_calendar(principal, id).await + self.birthday_store + .get_calendar(principal, id, show_deleted) + .await } else { - self.cal_store.get_calendar(principal, id).await + self.cal_store + .get_calendar(principal, id, show_deleted) + .await } } diff --git a/crates/store/src/contact_birthday_store.rs b/crates/store/src/contact_birthday_store.rs index 450d8e5..ef24e57 100644 --- a/crates/store/src/contact_birthday_store.rs +++ b/crates/store/src/contact_birthday_store.rs @@ -38,11 +38,17 @@ fn birthday_calendar(addressbook: Addressbook) -> Calendar { /// Objects are all prefixed with BIRTHDAYS_PREFIX #[async_trait] impl CalendarStore for ContactBirthdayStore { - async fn get_calendar(&self, principal: &str, id: &str) -> Result { + async fn get_calendar( + &self, + principal: &str, + id: &str, + show_deleted: bool, + ) -> Result { let id = id.strip_prefix(BIRTHDAYS_PREFIX).ok_or(Error::NotFound)?; - let addressbook = self.0.get_addressbook(principal, id, false).await?; + let addressbook = self.0.get_addressbook(principal, id, show_deleted).await?; Ok(birthday_calendar(addressbook)) } + async fn get_calendars(&self, principal: &str) -> Result, Error> { let addressbooks = self.0.get_addressbooks(principal).await?; Ok(addressbooks.into_iter().map(birthday_calendar).collect()) diff --git a/crates/store_sqlite/src/calendar_store.rs b/crates/store_sqlite/src/calendar_store.rs index 4de7353..218919f 100644 --- a/crates/store_sqlite/src/calendar_store.rs +++ b/crates/store_sqlite/src/calendar_store.rs @@ -86,14 +86,17 @@ impl SqliteCalendarStore { executor: E, principal: &str, id: &str, + show_deleted: bool, ) -> Result { let cal = sqlx::query_as!( CalendarRow, r#"SELECT * FROM calendars - WHERE (principal, id) = (?, ?)"#, + WHERE (principal, id) = (?, ?) + AND ((deleted_at IS NULL) OR ?) "#, principal, - id + id, + show_deleted ) .fetch_one(executor) .await @@ -470,8 +473,13 @@ impl SqliteCalendarStore { #[async_trait] impl CalendarStore for SqliteCalendarStore { #[instrument] - async fn get_calendar(&self, principal: &str, id: &str) -> Result { - Self::_get_calendar(&self.db, principal, id).await + async fn get_calendar( + &self, + principal: &str, + id: &str, + show_deleted: bool, + ) -> Result { + Self::_get_calendar(&self.db, principal, id, show_deleted).await } #[instrument] @@ -509,7 +517,7 @@ impl CalendarStore for SqliteCalendarStore { ) -> Result<(), Error> { let mut tx = self.db.begin().await.map_err(crate::Error::from)?; - let cal = match Self::_get_calendar(&mut *tx, principal, id).await { + let cal = match Self::_get_calendar(&mut *tx, principal, id, true).await { Ok(cal) => Some(cal), Err(Error::NotFound) => None, Err(err) => return Err(err), @@ -599,7 +607,10 @@ impl CalendarStore for SqliteCalendarStore { if let Err(err) = self.sender.try_send(CollectionOperation { data: CollectionOperationInfo::Content { sync_token }, - topic: self.get_calendar(&principal, &cal_id).await?.push_topic, + topic: self + .get_calendar(&principal, &cal_id, true) + .await? + .push_topic, }) { error!("Push notification about deleted calendar failed: {err}"); }; @@ -624,7 +635,7 @@ impl CalendarStore for SqliteCalendarStore { if let Err(err) = self.sender.try_send(CollectionOperation { data: CollectionOperationInfo::Content { sync_token }, - topic: self.get_calendar(principal, cal_id).await?.push_topic, + topic: self.get_calendar(principal, cal_id, true).await?.push_topic, }) { error!("Push notification about deleted calendar failed: {err}"); }; @@ -649,7 +660,7 @@ impl CalendarStore for SqliteCalendarStore { if let Err(err) = self.sender.try_send(CollectionOperation { data: CollectionOperationInfo::Content { sync_token }, - topic: self.get_calendar(principal, cal_id).await?.push_topic, + topic: self.get_calendar(principal, cal_id, true).await?.push_topic, }) { error!("Push notification about deleted calendar failed: {err}"); };