mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 19:22:26 +00:00
A little more preparation for new DAV Push spec
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use actix_web::{FromRequest, HttpRequest, ResponseError, http::StatusCode};
|
||||
use futures_util::future::{Ready, err, ok};
|
||||
use rustical_xml::ValueSerialize;
|
||||
use rustical_xml::{ValueDeserialize, ValueSerialize, XmlError};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
@@ -25,12 +25,25 @@ impl ValueSerialize for Depth {
|
||||
match self {
|
||||
Depth::Zero => "0",
|
||||
Depth::One => "1",
|
||||
Depth::Infinity => "Infinity",
|
||||
Depth::Infinity => "infinity",
|
||||
}
|
||||
.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl ValueDeserialize for Depth {
|
||||
fn deserialize(val: &str) -> Result<Self, XmlError> {
|
||||
match val {
|
||||
"0" => Ok(Self::Zero),
|
||||
"1" => Ok(Self::One),
|
||||
"infinity" | "Infinity" => Ok(Self::Infinity),
|
||||
_ => Err(XmlError::InvalidVariant(
|
||||
"Invalid value for depth".to_owned(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&[u8]> for Depth {
|
||||
type Error = InvalidDepthHeader;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{ContentUpdate, PropertyUpdate, SupportedTrigger, SupportedTriggers, Transports};
|
||||
use crate::{ContentUpdate, PropertyUpdate, SupportedTriggers, Transports, Trigger};
|
||||
use rustical_dav::header::Depth;
|
||||
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
||||
use rustical_xml::{EnumUnitVariants, EnumVariants, Unparsed, XmlDeserialize, XmlSerialize};
|
||||
|
||||
#[derive(XmlDeserialize, XmlSerialize, PartialEq, Clone, EnumUnitVariants, EnumVariants)]
|
||||
#[xml(unit_variants_ident = "DavPushExtensionPropName")]
|
||||
@@ -21,8 +21,8 @@ pub trait DavPushExtension {
|
||||
|
||||
fn supported_triggers(&self) -> SupportedTriggers {
|
||||
SupportedTriggers(vec![
|
||||
SupportedTrigger::ContentUpdate(ContentUpdate(Depth::One)),
|
||||
SupportedTrigger::PropertyUpdate(PropertyUpdate(Depth::One)),
|
||||
Trigger::ContentUpdate(ContentUpdate(Depth::One)),
|
||||
Trigger::PropertyUpdate(PropertyUpdate(Depth::One)),
|
||||
])
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rustical_dav::header::Depth;
|
||||
use rustical_xml::XmlSerialize;
|
||||
use rustical_xml::{Unparsed, XmlDeserialize, XmlSerialize};
|
||||
|
||||
#[derive(Debug, Clone, XmlSerialize, PartialEq)]
|
||||
pub enum Transport {
|
||||
@@ -22,23 +22,39 @@ impl Default for Transports {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(XmlSerialize, PartialEq, Clone)]
|
||||
pub struct SupportedTriggers(#[xml(flatten, ty = "untagged")] pub Vec<SupportedTrigger>);
|
||||
#[derive(XmlSerialize, XmlDeserialize, PartialEq, Clone)]
|
||||
pub struct SupportedTriggers(#[xml(flatten, ty = "untagged")] pub Vec<Trigger>);
|
||||
|
||||
#[derive(XmlSerialize, PartialEq, Clone)]
|
||||
pub enum SupportedTrigger {
|
||||
#[derive(XmlSerialize, XmlDeserialize, PartialEq, Debug, Clone)]
|
||||
pub enum Trigger {
|
||||
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||
ContentUpdate(ContentUpdate),
|
||||
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||
PropertyUpdate(PropertyUpdate),
|
||||
}
|
||||
|
||||
#[derive(XmlSerialize, PartialEq, Clone)]
|
||||
#[derive(XmlSerialize, XmlDeserialize, PartialEq, Clone, Debug)]
|
||||
pub struct ContentUpdate(
|
||||
#[xml(rename = b"depth", ns = "rustical_dav::namespace::NS_DAV")] pub Depth,
|
||||
);
|
||||
|
||||
#[derive(XmlSerialize, PartialEq, Clone)]
|
||||
#[derive(XmlSerialize, PartialEq, Clone, Debug)]
|
||||
pub struct PropertyUpdate(
|
||||
#[xml(rename = b"depth", ns = "rustical_dav::namespace::NS_DAV")] pub Depth,
|
||||
);
|
||||
|
||||
impl XmlDeserialize for PropertyUpdate {
|
||||
fn deserialize<R: std::io::BufRead>(
|
||||
reader: &mut quick_xml::NsReader<R>,
|
||||
start: &quick_xml::events::BytesStart,
|
||||
empty: bool,
|
||||
) -> Result<Self, rustical_xml::XmlError> {
|
||||
#[derive(XmlDeserialize, PartialEq, Clone, Debug)]
|
||||
struct FakePropertyUpdate(
|
||||
#[xml(rename = b"depth", ns = "rustical_dav::namespace::NS_DAV")] pub Depth,
|
||||
#[xml(rename = b"prop", ns = "rustical_dav::namespace::NS_DAV")] pub Unparsed,
|
||||
);
|
||||
let FakePropertyUpdate(depth, _) = FakePropertyUpdate::deserialize(reader, start, empty)?;
|
||||
Ok(Self(depth))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
use rustical_xml::{XmlDeserialize, XmlRootTag};
|
||||
use crate::Trigger;
|
||||
use rustical_xml::{XmlDeserialize, XmlRootTag, XmlSerialize};
|
||||
|
||||
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
|
||||
#[xml(ns = "crate::namespace::NS_DAVPUSH")]
|
||||
pub struct WebPushSubscription {
|
||||
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||
pub push_resource: String,
|
||||
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||
pub content_encoding: String,
|
||||
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||
pub subscription_public_key: SubscriptionPublicKey,
|
||||
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||
pub auth_secret: String,
|
||||
}
|
||||
|
||||
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
|
||||
pub struct SubscriptionPublicKey {
|
||||
#[xml(ty = "attr", rename = b"type")]
|
||||
ty: String,
|
||||
#[xml(ty = "text")]
|
||||
key: String,
|
||||
}
|
||||
|
||||
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
|
||||
@@ -13,6 +28,9 @@ pub struct SubscriptionElement {
|
||||
pub web_push_subscription: WebPushSubscription,
|
||||
}
|
||||
|
||||
#[derive(XmlDeserialize, XmlSerialize, Clone, Debug, PartialEq)]
|
||||
pub struct TriggerElement(#[xml(ty = "untagged", flatten)] Vec<Trigger>);
|
||||
|
||||
#[derive(XmlDeserialize, XmlRootTag, Clone, Debug, PartialEq)]
|
||||
#[xml(root = b"push-register")]
|
||||
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||
@@ -21,11 +39,16 @@ pub struct PushRegister {
|
||||
pub subscription: SubscriptionElement,
|
||||
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||
pub expires: Option<String>,
|
||||
#[xml(ns = "rustical_dav::namespace::NS_DAVPUSH")]
|
||||
pub trigger: TriggerElement,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{ContentUpdate, PropertyUpdate};
|
||||
|
||||
use super::*;
|
||||
use rustical_dav::header::Depth;
|
||||
use rustical_xml::XmlDocument;
|
||||
|
||||
#[test]
|
||||
@@ -33,12 +56,27 @@ mod tests {
|
||||
let push_register = PushRegister::parse_str(
|
||||
r#"
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<push-register xmlns="https://bitfire.at/webdav-push">
|
||||
<push-register xmlns="https://bitfire.at/webdav-push" xmlns:D="DAV:">
|
||||
<subscription>
|
||||
<web-push-subscription>
|
||||
<push-resource>https://up.example.net/yohd4yai5Phiz1wi</push-resource>
|
||||
<content-encoding>aes128gcm</content-encoding>
|
||||
<subscription-public-key type="p256dh">BCVxsr7N_eNgVRqvHtD0zTZsEc6-VV-JvLexhqUzORcxaOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4</subscription-public-key>
|
||||
<auth-secret>BTBZMqHH6r4Tts7J_aSIgg</auth-secret>
|
||||
</web-push-subscription>
|
||||
</subscription>
|
||||
<trigger>
|
||||
<content-update>
|
||||
<D:depth>infinity</D:depth>
|
||||
</content-update>
|
||||
<property-update>
|
||||
<D:depth>0</D:depth>
|
||||
<D:prop>
|
||||
<D:displayname/>
|
||||
<D:owner/>
|
||||
</D:prop>
|
||||
</property-update>
|
||||
</trigger>
|
||||
<expires>Wed, 20 Dec 2023 10:03:31 GMT</expires>
|
||||
</push-register>
|
||||
"#,
|
||||
@@ -49,10 +87,17 @@ mod tests {
|
||||
PushRegister {
|
||||
subscription: SubscriptionElement {
|
||||
web_push_subscription: WebPushSubscription {
|
||||
push_resource: "https://up.example.net/yohd4yai5Phiz1wi".to_owned()
|
||||
push_resource: "https://up.example.net/yohd4yai5Phiz1wi".to_owned(),
|
||||
content_encoding: "aes128gcm".to_owned(),
|
||||
subscription_public_key: SubscriptionPublicKey { ty: "p256dh".to_owned(), key: "BCVxsr7N_eNgVRqvHtD0zTZsEc6-VV-JvLexhqUzORcxaOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4".to_owned() },
|
||||
auth_secret: "BTBZMqHH6r4Tts7J_aSIgg".to_owned()
|
||||
}
|
||||
},
|
||||
expires: Some("Wed, 20 Dec 2023 10:03:31 GMT".to_owned())
|
||||
expires: Some("Wed, 20 Dec 2023 10:03:31 GMT".to_owned()),
|
||||
trigger: TriggerElement(vec![
|
||||
Trigger::ContentUpdate(ContentUpdate(Depth::Infinity)),
|
||||
Trigger::PropertyUpdate(PropertyUpdate(Depth::Zero)),
|
||||
])
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user