WebDAV and other minor fixes

This commit is contained in:
Maurus Decimus
2026-04-18 10:42:21 +02:00
parent e6fbd189d6
commit dd95efe3ce
8 changed files with 53 additions and 6 deletions

View File

@@ -86,7 +86,10 @@ This version includes **multiple breaking changes**. If you are upgrading from v
- Increment argument max length to `8000` bytes
- ACL: Add `RIGHTS` capability (#2762)
- ACL: Fix `ACL SET` permission override.
- WebDAV: Return `304` `NOT_MODIFIED` on `If-None-Match`
- WebDAV:
- Return `304` `NOT_MODIFIED` on `If-None-Match`
- Use RFC 2616 instead of RFC 1123 for date formatting
- Fix ACL container/item mismatch in reports.
- Configuration: Prefix parsing issues (#2495)
- OIDC: JWKS Exposes Symmetric Signing Key
- SQLite: Fix thread pool exhaustion.

View File

@@ -375,6 +375,20 @@ impl Server {
})
.caused_by(trc::location!())?
{
let last_trained_at = match &model {
SpamClassifier::FhClassifier {
last_trained_at, ..
} => Some(*last_trained_at),
SpamClassifier::CcfhClassifier {
last_trained_at, ..
} => Some(*last_trained_at),
SpamClassifier::Disabled => None,
};
trc::event!(
Spam(SpamEvent::ModelLoaded),
Details = last_trained_at.map(trc::Value::Timestamp),
);
self.inner.data.spam_classifier.store(Arc::new(model));
} else {
trc::event!(Spam(SpamEvent::ModelNotFound));

View File

@@ -59,7 +59,7 @@ impl Display for Rfc1123DateTime {
let dt = DateTime::from_timestamp(self.0);
write!(
f,
"{}, {} {} {:04} {:02}:{:02}:{:02} GMT",
"{}, {:02} {} {:04} {:02}:{:02}:{:02} GMT",
DOW[dt.day_of_week() as usize],
dt.day,
MONTH

View File

@@ -107,7 +107,7 @@ impl CalendarFreebusyRequestHandler for Server {
// Obtain shared ids
let shared_ids = if !access_token.is_member(account_id) {
resources
.shared_containers(
.shared_items(
access_token,
[Acl::ReadItems, Acl::SchedulingReadFreeBusy],
false,

View File

@@ -90,7 +90,7 @@ impl CalendarQueryRequestHandler for Server {
// Obtain shared ids
let shared_ids = if !access_token.is_member(account_id) {
resources
.shared_containers(access_token, [Acl::ReadItems], false)
.shared_items(access_token, [Acl::ReadItems], false)
.into()
} else {
None

View File

@@ -77,7 +77,7 @@ impl CardQueryRequestHandler for Server {
// Obtain shared ids
let shared_ids = if !access_token.is_member(account_id) {
resources
.shared_containers(access_token, [Acl::ReadItems], false)
.shared_items(access_token, [Acl::ReadItems], false)
.into()
} else {
None

View File

@@ -595,7 +595,9 @@ impl ParseHttp for Server {
}
external => {
if path.next().is_none() {
return Ok(HttpResponse::redirect(format!("/{external}/")));
if !external.is_empty() {
return Ok(HttpResponse::redirect(format!("/{external}/")));
}
} else if let Some(resource) = self
.inner
.data

View File

@@ -131,6 +131,11 @@ pub async fn test(test: &TestServer) {
.properties(&owner_file)
.with_status(StatusCode::OK)
.is_defined(DavProperty::WebDav(WebDavProperty::GetETag));
sharee_client
.request("REPORT", &owner_folder, CALENDAR_QUERY_ANY_VEVENT)
.await
.with_status(StatusCode::MULTI_STATUS)
.with_hrefs([owner_file.as_str()]);
}
DavResourceName::Card => {
sharee_client
@@ -139,6 +144,11 @@ pub async fn test(test: &TestServer) {
.properties(&owner_file)
.with_status(StatusCode::OK)
.is_defined(DavProperty::WebDav(WebDavProperty::GetETag));
sharee_client
.request("REPORT", &owner_folder, ADDRESSBOOK_QUERY_ANY_FN)
.await
.with_status(StatusCode::MULTI_STATUS)
.with_hrefs([owner_file.as_str()]);
}
_ => {}
}
@@ -408,3 +418,21 @@ const ACL_PRINCIPAL_QUERY: &str = r#"<?xml version="1.0" encoding="utf-8" ?>
<D:displayname/>
</D:prop>
</D:acl-principal-prop-set>"#;
const CALENDAR_QUERY_ANY_VEVENT: &str = r#"<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop><D:getetag/></D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT"/>
</C:comp-filter>
</C:filter>
</C:calendar-query>"#;
const ADDRESSBOOK_QUERY_ANY_FN: &str = r#"<?xml version="1.0" encoding="utf-8" ?>
<C:addressbook-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav">
<D:prop><D:getetag/></D:prop>
<C:filter>
<C:prop-filter name="FN"/>
</C:filter>
</C:addressbook-query>"#;