MKCALENDAR: Handling of invalid timezones

This commit is contained in:
Lennart
2026-01-19 16:36:25 +01:00
parent be34cc3091
commit 1b6214d426
2 changed files with 28 additions and 9 deletions

View File

@@ -1,10 +1,14 @@
use std::str::FromStr;
use crate::Error;
use crate::calendar::CalendarResourceService;
use crate::calendar::prop::SupportedCalendarComponentSet;
use crate::error::Precondition;
use axum::extract::{Path, State};
use axum::response::{IntoResponse, Response};
use http::{Method, StatusCode};
use ical::IcalParser;
use ical::types::get_proprietary_tzid;
use rustical_dav::xml::HrefElement;
use rustical_ical::CalendarObjectType;
use rustical_store::auth::Principal;
@@ -84,21 +88,33 @@ pub async fn route_mkcalendar<C: CalendarStore, S: SubscriptionStore>(
}
let timezone_id = if let Some(tzid) = request.calendar_timezone_id {
if chrono_tz::Tz::from_str(&tzid).is_err() {
return Err(Error::PreconditionFailed(Precondition::CalendarTimezone(
"Invalid timezone ID in calendar-timezone-id",
)));
}
Some(tzid)
} else if let Some(tz) = request.calendar_timezone {
// TODO: Proper error (calendar-timezone precondition)
let calendar = IcalParser::from_slice(tz.as_bytes())
.next()
.ok_or_else(|| rustical_dav::Error::BadRequest("No timezone data provided".to_owned()))?
.map_err(|_| rustical_dav::Error::BadRequest("Error parsing timezone".to_owned()))?;
.ok_or(Error::PreconditionFailed(Precondition::CalendarTimezone(
"No timezone data provided",
)))?
.map_err(|_| {
Error::PreconditionFailed(Precondition::CalendarTimezone("Error parsing timezone"))
})?;
let timezone = calendar.vtimezones.values().next().ok_or_else(|| {
rustical_dav::Error::BadRequest("No timezone data provided".to_owned())
})?;
let timezone = calendar
.vtimezones
.values()
.next()
.ok_or(Error::PreconditionFailed(Precondition::CalendarTimezone(
"No timezone data provided",
)))?;
let timezone: Option<chrono_tz::Tz> = timezone.into();
let timezone = timezone.ok_or_else(|| {
rustical_dav::Error::BadRequest("Cannot translate VTIMEZONE into IANA TZID".to_owned())
})?;
let timezone = timezone.ok_or(Error::PreconditionFailed(
Precondition::CalendarTimezone("No timezone data provided"),
))?;
Some(timezone.name().to_owned())
} else {