mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-14 14:02:29 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d639b18005 | ||
|
|
6046439fc7 | ||
|
|
f9de8a4687 |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "SQLite",
|
"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": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"Right": 2
|
"Right": 3
|
||||||
},
|
},
|
||||||
"nullable": [
|
"nullable": [
|
||||||
false,
|
false,
|
||||||
@@ -100,5 +100,5 @@
|
|||||||
false
|
false
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "9f930775043a6d4571a8ffd5a981cadf7c51f3f11a189f8461505abec31076e6"
|
"hash": "bb2fa030f2e7c7afdb38c5c54cb31de5293be332d86cf643977d479999542553"
|
||||||
}
|
}
|
||||||
22
Cargo.lock
generated
22
Cargo.lock
generated
@@ -2736,7 +2736,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustical"
|
name = "rustical"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"argon2",
|
"argon2",
|
||||||
@@ -2779,7 +2779,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustical_caldav"
|
name = "rustical_caldav"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
@@ -2814,7 +2814,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustical_carddav"
|
name = "rustical_carddav"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
@@ -2846,7 +2846,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustical_dav"
|
name = "rustical_dav"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
@@ -2871,7 +2871,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustical_dav_push"
|
name = "rustical_dav_push"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
@@ -2897,7 +2897,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustical_frontend"
|
name = "rustical_frontend"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"askama",
|
"askama",
|
||||||
"askama_web",
|
"askama_web",
|
||||||
@@ -2930,7 +2930,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustical_ical"
|
name = "rustical_ical"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -2948,7 +2948,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustical_oidc"
|
name = "rustical_oidc"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
@@ -2963,7 +2963,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustical_store"
|
name = "rustical_store"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -2997,7 +2997,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustical_store_sqlite"
|
name = "rustical_store_sqlite"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -3017,7 +3017,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustical_xml"
|
name = "rustical_xml"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quick-xml",
|
"quick-xml",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
members = ["crates/*"]
|
members = ["crates/*"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
description = "A CalDAV server"
|
description = "A CalDAV server"
|
||||||
repository = "https://github.com/lennart-k/rustical"
|
repository = "https://github.com/lennart-k/rustical"
|
||||||
|
|||||||
@@ -24,12 +24,16 @@ pub async fn route_get<C: CalendarStore, S: SubscriptionStore>(
|
|||||||
return Err(crate::Error::Unauthorized);
|
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) {
|
if !user.is_principal(&calendar.principal) {
|
||||||
return Err(crate::Error::Unauthorized);
|
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 mut timezones = HashMap::new();
|
||||||
let objects = cal_store.get_objects(&principal, &calendar_id).await?;
|
let objects = cal_store.get_objects(&principal, &calendar_id).await?;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ pub async fn route_post<C: CalendarStore, S: SubscriptionStore>(
|
|||||||
|
|
||||||
let calendar = resource_service
|
let calendar = resource_service
|
||||||
.cal_store
|
.cal_store
|
||||||
.get_calendar(&principal, &cal_id)
|
.get_calendar(&principal, &cal_id, false)
|
||||||
.await?;
|
.await?;
|
||||||
let calendar_resource = CalendarResource {
|
let calendar_resource = CalendarResource {
|
||||||
cal: calendar,
|
cal: calendar,
|
||||||
|
|||||||
@@ -56,8 +56,12 @@ impl<C: CalendarStore, S: SubscriptionStore> ResourceService for CalendarResourc
|
|||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
(principal, cal_id): &Self::PathComponents,
|
(principal, cal_id): &Self::PathComponents,
|
||||||
|
show_deleted: bool,
|
||||||
) -> Result<Self::Resource, Error> {
|
) -> Result<Self::Resource, Error> {
|
||||||
let calendar = self.cal_store.get_calendar(principal, cal_id).await?;
|
let calendar = self
|
||||||
|
.cal_store
|
||||||
|
.get_calendar(principal, cal_id, show_deleted)
|
||||||
|
.await?;
|
||||||
Ok(CalendarResource {
|
Ok(CalendarResource {
|
||||||
cal: calendar,
|
cal: calendar,
|
||||||
read_only: self.cal_store.is_read_only(cal_id),
|
read_only: self.cal_store.is_read_only(cal_id),
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ pub async fn get_event<C: CalendarStore>(
|
|||||||
return Err(crate::Error::Unauthorized);
|
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) {
|
if !user.is_principal(&calendar.principal) {
|
||||||
return Err(crate::Error::Unauthorized);
|
return Err(crate::Error::Unauthorized);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,10 +58,11 @@ impl<C: CalendarStore> ResourceService for CalendarObjectResourceService<C> {
|
|||||||
calendar_id,
|
calendar_id,
|
||||||
object_id,
|
object_id,
|
||||||
}: &Self::PathComponents,
|
}: &Self::PathComponents,
|
||||||
|
show_deleted: bool,
|
||||||
) -> Result<Self::Resource, Self::Error> {
|
) -> Result<Self::Resource, Self::Error> {
|
||||||
let object = self
|
let object = self
|
||||||
.cal_store
|
.cal_store
|
||||||
.get_object(principal, calendar_id, object_id, false)
|
.get_object(principal, calendar_id, object_id, show_deleted)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(CalendarObjectResource {
|
Ok(CalendarObjectResource {
|
||||||
object,
|
object,
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ impl<AP: AuthenticationProvider, S: SubscriptionStore, CS: CalendarStore> Resour
|
|||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
(principal,): &Self::PathComponents,
|
(principal,): &Self::PathComponents,
|
||||||
|
_show_deleted: bool,
|
||||||
) -> Result<Self::Resource, Self::Error> {
|
) -> Result<Self::Resource, Self::Error> {
|
||||||
let user = self
|
let user = self
|
||||||
.auth_provider
|
.auth_provider
|
||||||
|
|||||||
@@ -49,10 +49,11 @@ impl<AS: AddressbookStore> ResourceService for AddressObjectResourceService<AS>
|
|||||||
addressbook_id,
|
addressbook_id,
|
||||||
object_id,
|
object_id,
|
||||||
}: &Self::PathComponents,
|
}: &Self::PathComponents,
|
||||||
|
show_deleted: bool,
|
||||||
) -> Result<Self::Resource, Self::Error> {
|
) -> Result<Self::Resource, Self::Error> {
|
||||||
let object = self
|
let object = self
|
||||||
.addr_store
|
.addr_store
|
||||||
.get_object(principal, addressbook_id, object_id, false)
|
.get_object(principal, addressbook_id, object_id, show_deleted)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(AddressObjectResource {
|
Ok(AddressObjectResource {
|
||||||
object,
|
object,
|
||||||
|
|||||||
@@ -59,10 +59,11 @@ impl<AS: AddressbookStore, S: SubscriptionStore> ResourceService
|
|||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
(principal, addressbook_id): &Self::PathComponents,
|
(principal, addressbook_id): &Self::PathComponents,
|
||||||
|
show_deleted: bool,
|
||||||
) -> Result<Self::Resource, Error> {
|
) -> Result<Self::Resource, Error> {
|
||||||
let addressbook = self
|
let addressbook = self
|
||||||
.addr_store
|
.addr_store
|
||||||
.get_addressbook(principal, addressbook_id, false)
|
.get_addressbook(principal, addressbook_id, show_deleted)
|
||||||
.await
|
.await
|
||||||
.map_err(|_e| Error::NotFound)?;
|
.map_err(|_e| Error::NotFound)?;
|
||||||
Ok(addressbook.into())
|
Ok(addressbook.into())
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ impl<A: AddressbookStore, AP: AuthenticationProvider, S: SubscriptionStore> Reso
|
|||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
(principal,): &Self::PathComponents,
|
(principal,): &Self::PathComponents,
|
||||||
|
_show_deleted: bool,
|
||||||
) -> Result<Self::Resource, Self::Error> {
|
) -> Result<Self::Resource, Self::Error> {
|
||||||
let user = self
|
let user = self
|
||||||
.auth_provider
|
.auth_provider
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ pub async fn route_delete<R: ResourceService>(
|
|||||||
if_match: Option<IfMatch>,
|
if_match: Option<IfMatch>,
|
||||||
if_none_match: Option<IfNoneMatch>,
|
if_none_match: Option<IfNoneMatch>,
|
||||||
) -> Result<(), R::Error> {
|
) -> Result<(), R::Error> {
|
||||||
let resource = resource_service.get_resource(path_components).await?;
|
let resource = resource_service.get_resource(path_components, true).await?;
|
||||||
|
|
||||||
// Kind of a bodge since we don't get unbind from the parent
|
// Kind of a bodge since we don't get unbind from the parent
|
||||||
let privileges = resource.get_user_privileges(principal)?;
|
let privileges = resource.get_user_privileges(principal)?;
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ pub(crate) async fn route_propfind<R: ResourceService>(
|
|||||||
resource_service: &R,
|
resource_service: &R,
|
||||||
puri: &impl PrincipalUri,
|
puri: &impl PrincipalUri,
|
||||||
) -> Result<RSMultistatus<R>, R::Error> {
|
) -> Result<RSMultistatus<R>, R::Error> {
|
||||||
let resource = resource_service.get_resource(path_components).await?;
|
let resource = resource_service
|
||||||
|
.get_resource(path_components, false)
|
||||||
|
.await?;
|
||||||
let privileges = resource.get_user_privileges(principal)?;
|
let privileges = resource.get_user_privileges(principal)?;
|
||||||
if !privileges.has(&UserPrivilege::Read) {
|
if !privileges.has(&UserPrivilege::Read) {
|
||||||
return Err(Error::Unauthorized.into());
|
return Err(Error::Unauthorized.into());
|
||||||
|
|||||||
@@ -85,7 +85,9 @@ pub(crate) async fn route_proppatch<R: ResourceService>(
|
|||||||
operations,
|
operations,
|
||||||
) = XmlDocument::parse_str(body).map_err(Error::XmlError)?;
|
) = XmlDocument::parse_str(body).map_err(Error::XmlError)?;
|
||||||
|
|
||||||
let mut resource = resource_service.get_resource(path_components).await?;
|
let mut resource = resource_service
|
||||||
|
.get_resource(path_components, false)
|
||||||
|
.await?;
|
||||||
let privileges = resource.get_user_privileges(principal)?;
|
let privileges = resource.get_user_privileges(principal)?;
|
||||||
if !privileges.has(&UserPrivilege::Write) {
|
if !privileges.has(&UserPrivilege::Write) {
|
||||||
return Err(Error::Unauthorized.into());
|
return Err(Error::Unauthorized.into());
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ pub trait ResourceService: Clone + Sized + Send + Sync + AxumMethods + 'static {
|
|||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
_path: &Self::PathComponents,
|
path: &Self::PathComponents,
|
||||||
|
show_deleted: bool,
|
||||||
) -> Result<Self::Resource, Self::Error>;
|
) -> Result<Self::Resource, Self::Error>;
|
||||||
|
|
||||||
async fn save_resource(
|
async fn save_resource(
|
||||||
|
|||||||
@@ -86,7 +86,11 @@ where
|
|||||||
|
|
||||||
const DAV_HEADER: &str = "1, 3, access-control";
|
const DAV_HEADER: &str = "1, 3, access-control";
|
||||||
|
|
||||||
async fn get_resource(&self, _: &()) -> Result<Self::Resource, Self::Error> {
|
async fn get_resource(
|
||||||
|
&self,
|
||||||
|
_: &(),
|
||||||
|
_show_deleted: bool,
|
||||||
|
) -> Result<Self::Resource, Self::Error> {
|
||||||
Ok(RootResource::<PRS::Resource, P>::default())
|
Ok(RootResource::<PRS::Resource, P>::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ pub async fn route_calendar<C: CalendarStore>(
|
|||||||
return Ok(StatusCode::UNAUTHORIZED.into_response());
|
return Ok(StatusCode::UNAUTHORIZED.into_response());
|
||||||
}
|
}
|
||||||
Ok(CalendarPage {
|
Ok(CalendarPage {
|
||||||
calendar: store.get_calendar(&owner, &cal_id).await?,
|
calendar: store.get_calendar(&owner, &cal_id, true).await?,
|
||||||
}
|
}
|
||||||
.into_response())
|
.into_response())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,12 @@ pub struct CalendarQuery {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait CalendarStore: Send + Sync + 'static {
|
pub trait CalendarStore: Send + Sync + 'static {
|
||||||
async fn get_calendar(&self, principal: &str, id: &str) -> Result<Calendar, Error>;
|
async fn get_calendar(
|
||||||
|
&self,
|
||||||
|
principal: &str,
|
||||||
|
id: &str,
|
||||||
|
show_deleted: bool,
|
||||||
|
) -> Result<Calendar, Error>;
|
||||||
async fn get_calendars(&self, principal: &str) -> Result<Vec<Calendar>, Error>;
|
async fn get_calendars(&self, principal: &str) -> Result<Vec<Calendar>, Error>;
|
||||||
async fn get_deleted_calendars(&self, principal: &str) -> Result<Vec<Calendar>, Error>;
|
async fn get_deleted_calendars(&self, principal: &str) -> Result<Vec<Calendar>, Error>;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use derive_more::Constructor;
|
use derive_more::Constructor;
|
||||||
use rustical_ical::CalendarObject;
|
use rustical_ical::CalendarObject;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Calendar, CalendarStore, Error, calendar_store::CalendarQuery,
|
Calendar, CalendarStore, Error, calendar_store::CalendarQuery,
|
||||||
@@ -27,11 +26,20 @@ impl<CS: CalendarStore, BS: CalendarStore> Clone for CombinedCalendarStore<CS, B
|
|||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<CS: CalendarStore, BS: CalendarStore> CalendarStore for CombinedCalendarStore<CS, BS> {
|
impl<CS: CalendarStore, BS: CalendarStore> CalendarStore for CombinedCalendarStore<CS, BS> {
|
||||||
#[inline]
|
#[inline]
|
||||||
async fn get_calendar(&self, principal: &str, id: &str) -> Result<Calendar, Error> {
|
async fn get_calendar(
|
||||||
|
&self,
|
||||||
|
principal: &str,
|
||||||
|
id: &str,
|
||||||
|
show_deleted: bool,
|
||||||
|
) -> Result<Calendar, Error> {
|
||||||
if id.starts_with(BIRTHDAYS_PREFIX) {
|
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 {
|
} else {
|
||||||
self.cal_store.get_calendar(principal, id).await
|
self.cal_store
|
||||||
|
.get_calendar(principal, id, show_deleted)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,11 +38,17 @@ fn birthday_calendar(addressbook: Addressbook) -> Calendar {
|
|||||||
/// Objects are all prefixed with BIRTHDAYS_PREFIX
|
/// Objects are all prefixed with BIRTHDAYS_PREFIX
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<AS: AddressbookStore> CalendarStore for ContactBirthdayStore<AS> {
|
impl<AS: AddressbookStore> CalendarStore for ContactBirthdayStore<AS> {
|
||||||
async fn get_calendar(&self, principal: &str, id: &str) -> Result<Calendar, Error> {
|
async fn get_calendar(
|
||||||
|
&self,
|
||||||
|
principal: &str,
|
||||||
|
id: &str,
|
||||||
|
show_deleted: bool,
|
||||||
|
) -> Result<Calendar, Error> {
|
||||||
let id = id.strip_prefix(BIRTHDAYS_PREFIX).ok_or(Error::NotFound)?;
|
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))
|
Ok(birthday_calendar(addressbook))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_calendars(&self, principal: &str) -> Result<Vec<Calendar>, Error> {
|
async fn get_calendars(&self, principal: &str) -> Result<Vec<Calendar>, Error> {
|
||||||
let addressbooks = self.0.get_addressbooks(principal).await?;
|
let addressbooks = self.0.get_addressbooks(principal).await?;
|
||||||
Ok(addressbooks.into_iter().map(birthday_calendar).collect())
|
Ok(addressbooks.into_iter().map(birthday_calendar).collect())
|
||||||
|
|||||||
@@ -86,14 +86,17 @@ impl SqliteCalendarStore {
|
|||||||
executor: E,
|
executor: E,
|
||||||
principal: &str,
|
principal: &str,
|
||||||
id: &str,
|
id: &str,
|
||||||
|
show_deleted: bool,
|
||||||
) -> Result<Calendar, Error> {
|
) -> Result<Calendar, Error> {
|
||||||
let cal = sqlx::query_as!(
|
let cal = sqlx::query_as!(
|
||||||
CalendarRow,
|
CalendarRow,
|
||||||
r#"SELECT *
|
r#"SELECT *
|
||||||
FROM calendars
|
FROM calendars
|
||||||
WHERE (principal, id) = (?, ?)"#,
|
WHERE (principal, id) = (?, ?)
|
||||||
|
AND ((deleted_at IS NULL) OR ?) "#,
|
||||||
principal,
|
principal,
|
||||||
id
|
id,
|
||||||
|
show_deleted
|
||||||
)
|
)
|
||||||
.fetch_one(executor)
|
.fetch_one(executor)
|
||||||
.await
|
.await
|
||||||
@@ -470,8 +473,13 @@ impl SqliteCalendarStore {
|
|||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CalendarStore for SqliteCalendarStore {
|
impl CalendarStore for SqliteCalendarStore {
|
||||||
#[instrument]
|
#[instrument]
|
||||||
async fn get_calendar(&self, principal: &str, id: &str) -> Result<Calendar, Error> {
|
async fn get_calendar(
|
||||||
Self::_get_calendar(&self.db, principal, id).await
|
&self,
|
||||||
|
principal: &str,
|
||||||
|
id: &str,
|
||||||
|
show_deleted: bool,
|
||||||
|
) -> Result<Calendar, Error> {
|
||||||
|
Self::_get_calendar(&self.db, principal, id, show_deleted).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument]
|
#[instrument]
|
||||||
@@ -509,7 +517,7 @@ impl CalendarStore for SqliteCalendarStore {
|
|||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut tx = self.db.begin().await.map_err(crate::Error::from)?;
|
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),
|
Ok(cal) => Some(cal),
|
||||||
Err(Error::NotFound) => None,
|
Err(Error::NotFound) => None,
|
||||||
Err(err) => return Err(err),
|
Err(err) => return Err(err),
|
||||||
@@ -599,7 +607,10 @@ impl CalendarStore for SqliteCalendarStore {
|
|||||||
|
|
||||||
if let Err(err) = self.sender.try_send(CollectionOperation {
|
if let Err(err) = self.sender.try_send(CollectionOperation {
|
||||||
data: CollectionOperationInfo::Content { sync_token },
|
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}");
|
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 {
|
if let Err(err) = self.sender.try_send(CollectionOperation {
|
||||||
data: CollectionOperationInfo::Content { sync_token },
|
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}");
|
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 {
|
if let Err(err) = self.sender.try_send(CollectionOperation {
|
||||||
data: CollectionOperationInfo::Content { sync_token },
|
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}");
|
error!("Push notification about deleted calendar failed: {err}");
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user