diff --git a/crates/dav/src/methods/proppatch.rs b/crates/dav/src/methods/proppatch.rs index 58de468..93e615b 100644 --- a/crates/dav/src/methods/proppatch.rs +++ b/crates/dav/src/methods/proppatch.rs @@ -93,7 +93,14 @@ pub async fn route_proppatch( prop: PropertyElement { prop }, }) => { if prop.invalid_property() { - props_not_found.push(propname); + if ::list_all_props().contains(&propname.as_str()) { + // This happens in following cases: + // - read-only properties with #[serde(skip_deserializing)] + // - for read-only properties from extensions + props_conflict.push(propname) + } else { + props_not_found.push(propname); + } continue; } match resource.set_prop(prop) { diff --git a/crates/dav/src/resource/mod.rs b/crates/dav/src/resource/mod.rs index 45b1a05..ea6fbe9 100644 --- a/crates/dav/src/resource/mod.rs +++ b/crates/dav/src/resource/mod.rs @@ -43,6 +43,17 @@ pub trait Resource: Clone + 'static { Self::PropName::VARIANTS } + fn list_all_props() -> Vec<&'static str> { + let mut props = Self::list_props().to_vec(); + props.extend( + Self::list_extensions() + .into_iter() + .map(|ext| ext.list_props().to_vec()) + .concat(), + ); + props + } + fn get_prop( &self, rmap: &ResourceMap,