Make MultistatusElement responder, other refactoring

This commit is contained in:
Lennart
2024-06-21 18:03:58 +02:00
parent 584e325596
commit 12374926dd
10 changed files with 81 additions and 80 deletions

View File

@@ -75,6 +75,7 @@ pub async fn route_mkcol_calendar<A: CheckAuthentication, C: CalendarStore + ?Si
timezone: request.calendar_timezone,
color: request.calendar_color,
description: request.calendar_description,
deleted: false,
};
match context.store.read().await.get_calendar(&cid).await {

View File

@@ -1,14 +1,14 @@
use crate::{event::resource::EventFile, Error};
use actix_web::{
http::header::ContentType,
web::{Data, Path},
HttpRequest, HttpResponse,
HttpRequest, Responder,
};
use rustical_auth::{AuthInfoExtractor, CheckAuthentication};
use rustical_dav::{
namespace::Namespace,
propfind::{MultistatusElement, PropElement, PropfindType, ServicePrefix},
propfind::{PropElement, PropfindType, ServicePrefix},
resource::HandlePropfind,
xml::MultistatusElement,
};
use rustical_store::event::Event;
use rustical_store::CalendarStore;
@@ -143,7 +143,7 @@ pub async fn route_report_calendar<A: CheckAuthentication, C: CalendarStore + ?S
req: HttpRequest,
cal_store: Data<RwLock<C>>,
prefix: Data<ServicePrefix>,
) -> Result<HttpResponse, Error> {
) -> Result<impl Responder, Error> {
let (principal, cid) = path.into_inner();
if principal != auth.inner.user_id {
return Err(Error::Unauthorized);
@@ -188,20 +188,11 @@ pub async fn route_report_calendar<A: CheckAuthentication, C: CalendarStore + ?S
);
}
let mut output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".to_owned();
let mut ser = quick_xml::se::Serializer::new(&mut output);
ser.indent(' ', 4);
MultistatusElement {
Ok(MultistatusElement {
responses,
member_responses: Vec::<String>::new(),
ns_dav: Namespace::Dav.as_str(),
ns_caldav: Namespace::CalDAV.as_str(),
ns_ical: Namespace::ICal.as_str(),
}
.serialize(ser)
.unwrap();
Ok(HttpResponse::MultiStatus()
.content_type(ContentType::xml())
.body(output))
})
}

View File

@@ -5,6 +5,5 @@ pub mod propfind;
pub mod proppatch;
pub mod resource;
pub mod xml;
pub mod xml_snippets;
pub use error::Error;

View File

@@ -2,15 +2,15 @@ use crate::depth_extractor::Depth;
use crate::namespace::Namespace;
use crate::resource::HandlePropfind;
use crate::resource::ResourceService;
use crate::xml::tag_list::TagList;
use crate::xml::MultistatusElement;
use crate::xml::TagList;
use crate::Error;
use actix_web::http::header::ContentType;
use actix_web::web::{Data, Path};
use actix_web::{HttpRequest, HttpResponse};
use actix_web::HttpRequest;
use actix_web::Responder;
use log::debug;
use rustical_auth::{AuthInfoExtractor, CheckAuthentication};
use serde::Deserialize;
use serde::Serialize;
// This is not the final place for this struct
pub struct ServicePrefix(pub String);
@@ -37,21 +37,6 @@ struct PropfindElement {
prop: PropfindType,
}
#[derive(Serialize)]
#[serde(rename = "multistatus")]
pub struct MultistatusElement<T1: Serialize, T2: Serialize> {
#[serde(rename = "response")]
pub responses: Vec<T1>,
#[serde(rename = "response")]
pub member_responses: Vec<T2>,
#[serde(rename = "@xmlns")]
pub ns_dav: &'static str,
#[serde(rename = "@xmlns:C")]
pub ns_caldav: &'static str,
#[serde(rename = "@xmlns:IC")]
pub ns_ical: &'static str,
}
pub async fn route_propfind<A: CheckAuthentication, R: ResourceService + ?Sized>(
path: Path<R::PathComponents>,
body: String,
@@ -59,7 +44,7 @@ pub async fn route_propfind<A: CheckAuthentication, R: ResourceService + ?Sized>
prefix: Data<ServicePrefix>,
auth: AuthInfoExtractor<A>,
depth: Depth,
) -> Result<HttpResponse, R::Error> {
) -> Result<impl Responder, R::Error> {
debug!("{body}");
let auth_info = auth.inner;
let prefix = prefix.0.to_owned();
@@ -98,20 +83,11 @@ pub async fn route_propfind<A: CheckAuthentication, R: ResourceService + ?Sized>
let resource = resource_service.get_file().await?;
let response = resource.propfind(&prefix, props).await?;
let mut output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".to_owned();
let mut ser = quick_xml::se::Serializer::new(&mut output);
ser.indent(' ', 4);
MultistatusElement {
Ok(MultistatusElement {
responses: vec![response],
member_responses,
ns_dav: Namespace::Dav.as_str(),
ns_caldav: Namespace::CalDAV.as_str(),
ns_ical: Namespace::ICal.as_str(),
}
.serialize(ser)
.unwrap();
Ok(HttpResponse::MultiStatus()
.content_type(ContentType::xml())
.body(output))
})
}

View File

@@ -1,15 +1,15 @@
use crate::namespace::Namespace;
use crate::propfind::MultistatusElement;
use crate::resource::InvalidProperty;
use crate::resource::Resource;
use crate::resource::ResourceService;
use crate::resource::{PropstatElement, PropstatResponseElement, PropstatType};
use crate::xml::tag_list::TagList;
use crate::xml::tag_name::TagName;
use crate::xml::MultistatusElement;
use crate::xml::TagList;
use crate::xml::TagName;
use crate::Error;
use actix_web::http::header::ContentType;
use actix_web::http::StatusCode;
use actix_web::{web::Path, HttpRequest, HttpResponse};
use actix_web::Responder;
use actix_web::{web::Path, HttpRequest};
use log::debug;
use rustical_auth::{AuthInfoExtractor, CheckAuthentication};
use serde::{Deserialize, Serialize};
@@ -49,7 +49,7 @@ pub async fn route_proppatch<A: CheckAuthentication, R: ResourceService + ?Sized
body: String,
req: HttpRequest,
auth: AuthInfoExtractor<A>,
) -> Result<HttpResponse, R::Error> {
) -> Result<impl Responder, R::Error> {
let auth_info = auth.inner;
let path_components = path.into_inner();
let href = req.path().to_owned();
@@ -132,10 +132,7 @@ pub async fn route_proppatch<A: CheckAuthentication, R: ResourceService + ?Sized
resource_service.save_file(resource).await?;
}
let mut output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".to_owned();
let mut ser = quick_xml::se::Serializer::new(&mut output);
ser.indent(' ', 4);
MultistatusElement {
Ok(MultistatusElement {
responses: vec![PropstatResponseElement {
href,
propstat: vec![
@@ -158,12 +155,5 @@ pub async fn route_proppatch<A: CheckAuthentication, R: ResourceService + ?Sized
ns_dav: Namespace::Dav.as_str(),
ns_caldav: Namespace::CalDAV.as_str(),
ns_ical: Namespace::ICal.as_str(),
}
.serialize(ser)
.unwrap();
debug!("{output}");
Ok(HttpResponse::MultiStatus()
.content_type(ContentType::xml())
.body(output))
})
}

View File

@@ -1,2 +1,20 @@
pub mod multistatus;
pub mod tag_list;
pub mod tag_name;
pub use multistatus::MultistatusElement;
pub use tag_list::TagList;
pub use tag_name::TagName;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct HrefElement {
pub href: String,
}
impl HrefElement {
pub fn new(href: String) -> Self {
Self { href }
}
}

View File

@@ -0,0 +1,38 @@
use actix_web::{
body::BoxBody, http::header::ContentType, HttpRequest, HttpResponse, Responder, ResponseError,
};
use log::debug;
use serde::Serialize;
#[derive(Serialize)]
#[serde(rename = "multistatus")]
pub struct MultistatusElement<T1: Serialize, T2: Serialize> {
#[serde(rename = "response")]
pub responses: Vec<T1>,
#[serde(rename = "response")]
pub member_responses: Vec<T2>,
#[serde(rename = "@xmlns")]
pub ns_dav: &'static str,
#[serde(rename = "@xmlns:C")]
pub ns_caldav: &'static str,
#[serde(rename = "@xmlns:IC")]
pub ns_ical: &'static str,
}
impl<T1: Serialize, T2: Serialize> Responder for MultistatusElement<T1, T2> {
type Body = BoxBody;
fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body> {
let mut output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".to_owned();
let mut ser = quick_xml::se::Serializer::new(&mut output);
ser.indent(' ', 4);
if let Err(err) = self.serialize(ser) {
return crate::Error::from(err).error_response();
}
debug!("Return multistatus:\n{output}");
HttpResponse::MultiStatus()
.content_type(ContentType::xml())
.body(output)
}
}

View File

@@ -3,8 +3,8 @@ use serde::{
Deserialize,
};
#[derive(Debug, Clone)]
pub struct TagName(String);
#[derive(Debug, Clone, PartialEq)]
pub struct TagName(pub String);
impl From<TagName> for String {
fn from(value: TagName) -> Self {

View File

@@ -1,12 +0,0 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct HrefElement {
pub href: String,
}
impl HrefElement {
pub fn new(href: String) -> Self {
Self { href }
}
}

View File

@@ -1,4 +1,4 @@
use rustical_dav::xml::tag_list::TagList;
use rustical_dav::xml::TagList;
use serde::{Deserialize, Serialize};
const INPUT: &str = r#"<Document>