basic implementation for mkcol

This commit is contained in:
Lennart
2023-09-13 18:00:30 +02:00
parent 31c7dcbd7d
commit 460f5d17db
2 changed files with 66 additions and 31 deletions

View File

@@ -70,6 +70,29 @@ pub fn write_invalid_props_response<W: Write>(
Ok(())
}
pub fn write_propstat_element<F, W: Write>(
writer: &mut Writer<W>,
status: StatusCode,
prop_closure: F,
) -> Result<(), quick_xml::Error>
where
F: FnOnce(&mut Writer<W>) -> Result<(), quick_xml::Error>,
{
writer
.create_element("propstat")
.write_inner_content(|writer| {
writer
.create_element("prop")
.write_inner_content(prop_closure)?;
writer
.create_element("status")
.write_text_content(BytesText::new(&format!("HTTP/1.1 {}", status)))?;
Ok(())
})?;
Ok(())
}
// Writes a propstat response into a multistatus
// closure hooks into the <prop> element
pub fn write_propstat_response<F, W: Write>(
@@ -88,18 +111,7 @@ where
.create_element("href")
.write_text_content(BytesText::new(href))?;
writer
.create_element("propstat")
.write_inner_content(|writer| {
writer
.create_element("prop")
.write_inner_content(prop_closure)?;
writer
.create_element("status")
.write_text_content(BytesText::new(&format!("HTTP/1.1 {}", status)))?;
Ok(())
})?;
write_propstat_element(writer, status, prop_closure)?;
Ok(())
})?;
@@ -124,3 +136,22 @@ where
std::str::from_utf8(&output_buffer)?
))
}
pub fn generate_mkcol_response<'a, F, A>(namespaces: A, closure: F) -> Result<String>
where
F: FnOnce(&mut Writer<&mut Vec<u8>>) -> Result<(), quick_xml::Error>,
A: IntoIterator,
A::Item: Into<Attribute<'a>>,
{
let mut output_buffer = Vec::new();
let mut writer = Writer::new_with_indent(&mut output_buffer, b' ', 2);
writer
.create_element("mkcol-response")
.with_attributes(namespaces)
.write_inner_content(closure)?;
Ok(format!(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n{}",
std::str::from_utf8(&output_buffer)?
))
}

View File

@@ -1,5 +1,7 @@
use crate::namespace::Namespace;
use crate::propfind::{generate_multistatus, write_propstat_response};
use crate::propfind::{
generate_mkcol_response, generate_multistatus, write_propstat_element, write_propstat_response,
};
use crate::proptypes::write_string_prop;
use crate::{CalDavContext, Error};
use actix_web::http::header::ContentType;
@@ -167,24 +169,26 @@ pub async fn route_mkcol_calendar<A: CheckAuthentication, C: CalendarStore>(
_ => return Err(Error::BadRequest),
}
for set_node in mkcol_node.children() {
if set_node.tag_name().name() != "set" {
return Err(Error::BadRequest);
}
let prop_node = set_node.first_element_child().ok_or(Error::BadRequest)?;
if prop_node.tag_name().name() != "prop" {
return Err(Error::BadRequest);
}
handle_mkcol_calendar_set(
&context.store,
prop_node,
cid.clone(),
auth.inner.user_id.clone(),
)
.await
.map_err(|_e| Error::InternalError)?;
// TODO: Why does the spec (rfc5689) allow multiple <set/> elements but only one resource? :/
// Well, for now just bother with the first one
let set_node = mkcol_node.first_element_child().ok_or(Error::BadRequest)?;
match set_node.tag_name().name() {
"set" => {}
_ => return Err(Error::BadRequest),
}
println!("{body}");
Err(Error::InternalError)
let prop_node = set_node.first_element_child().ok_or(Error::BadRequest)?;
if prop_node.tag_name().name() != "prop" {
return Err(Error::BadRequest);
}
handle_mkcol_calendar_set(
&context.store,
prop_node,
cid.clone(),
auth.inner.user_id.clone(),
)
.await
.map_err(|_e| Error::InternalError)?;
Ok(HttpResponse::Created().body(""))
}