lift restriction on object_id and UID having to match

addresses #135
This commit is contained in:
Lennart
2025-11-01 21:48:37 +01:00
parent db144ebcae
commit 76b4194b94
21 changed files with 234 additions and 103 deletions

View File

@@ -17,19 +17,20 @@ use tracing::{error, instrument};
struct CalendarObjectRow {
id: String,
ics: String,
uid: String,
}
impl TryFrom<CalendarObjectRow> for CalendarObject {
type Error = rustical_store::Error;
fn try_from(value: CalendarObjectRow) -> Result<Self, Self::Error> {
let object = Self::from_ics(value.ics)?;
if object.get_uid() != value.id {
let object = Self::from_ics(value.ics, Some(value.id))?;
if object.get_uid() != value.uid {
return Err(rustical_store::Error::IcalError(
rustical_ical::Error::InvalidData(format!(
"object_id={} and UID={} don't match",
object.get_uid(),
value.id
"uid={} and UID={} don't match",
value.uid,
object.get_uid()
)),
));
}
@@ -281,7 +282,7 @@ impl SqliteCalendarStore {
) -> Result<Vec<CalendarObject>, Error> {
sqlx::query_as!(
CalendarObjectRow,
"SELECT id, ics FROM calendarobjects WHERE principal = ? AND cal_id = ? AND deleted_at IS NULL",
"SELECT id, uid, ics FROM calendarobjects WHERE principal = ? AND cal_id = ? AND deleted_at IS NULL",
principal,
cal_id
)
@@ -306,7 +307,7 @@ impl SqliteCalendarStore {
sqlx::query_as!(
CalendarObjectRow,
r"SELECT id, ics FROM calendarobjects
r"SELECT id, uid, ics FROM calendarobjects
WHERE principal = ? AND cal_id = ? AND deleted_at IS NULL
AND (last_occurence IS NULL OR ? IS NULL OR last_occurence >= date(?))
AND (first_occurence IS NULL OR ? IS NULL OR first_occurence <= date(?))
@@ -335,7 +336,7 @@ impl SqliteCalendarStore {
) -> Result<CalendarObject, Error> {
sqlx::query_as!(
CalendarObjectRow,
"SELECT id, ics FROM calendarobjects WHERE (principal, cal_id, id) = (?, ?, ?) AND ((deleted_at IS NULL) OR ?)",
"SELECT id, uid, ics FROM calendarobjects WHERE (principal, cal_id, id) = (?, ?, ?) AND ((deleted_at IS NULL) OR ?)",
principal,
cal_id,
object_id,
@@ -355,7 +356,7 @@ impl SqliteCalendarStore {
object: CalendarObject,
overwrite: bool,
) -> Result<(), Error> {
let (object_id, ics) = (object.get_uid(), object.get_ics());
let (object_id, uid, ics) = (object.get_id(), object.get_uid(), object.get_ics());
let first_occurence = object
.get_first_occurence()
@@ -374,10 +375,11 @@ impl SqliteCalendarStore {
(if overwrite {
sqlx::query!(
"REPLACE INTO calendarobjects (principal, cal_id, id, ics, first_occurence, last_occurence, etag, object_type) VALUES (?, ?, ?, ?, date(?), date(?), ?, ?)",
"REPLACE INTO calendarobjects (principal, cal_id, id, uid, ics, first_occurence, last_occurence, etag, object_type) VALUES (?, ?, ?, ?, ?, date(?), date(?), ?, ?)",
principal,
cal_id,
object_id,
uid,
ics,
first_occurence,
last_occurence,
@@ -387,10 +389,11 @@ impl SqliteCalendarStore {
} else {
// If the object already exists a database error is thrown and handled in error.rs
sqlx::query!(
"INSERT INTO calendarobjects (principal, cal_id, id, ics, first_occurence, last_occurence, etag, object_type) VALUES (?, ?, ?, ?, date(?), date(?), ?, ?)",
"INSERT INTO calendarobjects (principal, cal_id, id, uid, ics, first_occurence, last_occurence, etag, object_type) VALUES (?, ?, ?, ?, ?, date(?), date(?), ?, ?)",
principal,
cal_id,
object_id,
uid,
ics,
first_occurence,
last_occurence,
@@ -410,7 +413,7 @@ impl SqliteCalendarStore {
executor: E,
principal: &str,
cal_id: &str,
id: &str,
object_id: &str,
use_trashbin: bool,
) -> Result<(), Error> {
if use_trashbin {
@@ -418,7 +421,7 @@ impl SqliteCalendarStore {
"UPDATE calendarobjects SET deleted_at = datetime(), updated_at = datetime() WHERE (principal, cal_id, id) = (?, ?, ?)",
principal,
cal_id,
id
object_id
)
.execute(executor)
.await.map_err(crate::Error::from)?;
@@ -426,7 +429,7 @@ impl SqliteCalendarStore {
sqlx::query!(
"DELETE FROM calendarobjects WHERE cal_id = ? AND id = ?",
cal_id,
id
object_id
)
.execute(executor)
.await
@@ -678,7 +681,7 @@ impl CalendarStore for SqliteCalendarStore {
.await
.map_err(crate::Error::from)?;
let object_id = object.get_uid().to_owned();
let object_id = object.get_id().to_owned();
let calendar = Self::_get_calendar(&mut *tx, &principal, &cal_id, true).await?;
if calendar.subscription_url.is_some() {