use xso::{text::Base64, AsXml, FromXml};
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
use crate::ns;
generate_elem_id!(
Name,
"name",
SASL_CERT
);
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SASL_CERT, name = "x509cert")]
pub struct Cert {
#[xml(text = Base64)]
pub data: Vec<u8>,
}
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SASL_CERT, name = "no-cert-management")]
pub struct NoCertManagement;
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SASL_CERT, name = "append")]
pub struct Append {
#[xml(child)]
pub name: Name,
#[xml(child)]
pub cert: Cert,
#[xml(child(default))]
pub no_cert_management: Option<NoCertManagement>,
}
impl IqSetPayload for Append {}
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SASL_CERT, name = "items")]
pub struct ListCertsQuery;
impl IqGetPayload for ListCertsQuery {}
generate_elem_id!(
Resource,
"resource",
SASL_CERT
);
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SASL_CERT, name = "users")]
pub struct Users {
#[xml(child(n = ..))]
pub resources: Vec<Resource>,
}
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SASL_CERT, name = "item")]
pub struct Item {
#[xml(child)]
pub name: Name,
#[xml(child)]
pub cert: Cert,
#[xml(child(default))]
pub no_cert_management: Option<NoCertManagement>,
#[xml(child(default))]
pub users: Option<Users>,
}
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SASL_CERT, name = "items")]
pub struct ListCertsResponse {
#[xml(child(n = ..))]
pub items: Vec<Item>,
}
impl IqResultPayload for ListCertsResponse {}
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SASL_CERT, name = "disable")]
pub struct Disable {
#[xml(child)]
pub name: Name,
}
impl IqSetPayload for Disable {}
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::SASL_CERT, name = "revoke")]
pub struct Revoke {
#[xml(child)]
pub name: Name,
}
impl IqSetPayload for Revoke {}
#[cfg(test)]
mod tests {
use super::*;
use crate::ns;
use minidom::Element;
use std::str::FromStr;
#[cfg(target_pointer_width = "32")]
#[test]
fn test_size() {
assert_size!(NoCertManagement, 0);
assert_size!(Append, 28);
assert_size!(Disable, 12);
assert_size!(Revoke, 12);
assert_size!(ListCertsQuery, 0);
assert_size!(ListCertsResponse, 12);
assert_size!(Item, 40);
assert_size!(Resource, 12);
assert_size!(Users, 12);
assert_size!(Cert, 12);
}
#[cfg(target_pointer_width = "64")]
#[test]
fn test_size() {
assert_size!(NoCertManagement, 0);
assert_size!(Append, 56);
assert_size!(Disable, 24);
assert_size!(Revoke, 24);
assert_size!(ListCertsQuery, 0);
assert_size!(ListCertsResponse, 24);
assert_size!(Item, 80);
assert_size!(Resource, 24);
assert_size!(Users, 24);
assert_size!(Cert, 24);
}
#[test]
fn simple() {
let elem: Element = "<append xmlns='urn:xmpp:saslcert:1'><name>Mobile Client</name><x509cert>AAAA</x509cert></append>".parse().unwrap();
let append = Append::try_from(elem).unwrap();
assert_eq!(append.name.0, "Mobile Client");
assert_eq!(append.cert.data, b"\0\0\0");
let elem: Element =
"<disable xmlns='urn:xmpp:saslcert:1'><name>Mobile Client</name></disable>"
.parse()
.unwrap();
let disable = Disable::try_from(elem).unwrap();
assert_eq!(disable.name.0, "Mobile Client");
let elem: Element =
"<revoke xmlns='urn:xmpp:saslcert:1'><name>Mobile Client</name></revoke>"
.parse()
.unwrap();
let revoke = Revoke::try_from(elem).unwrap();
assert_eq!(revoke.name.0, "Mobile Client");
}
#[test]
fn list() {
let elem: Element = r#"<items xmlns='urn:xmpp:saslcert:1'>
<item>
<name>Mobile Client</name>
<x509cert>AAAA</x509cert>
<users>
<resource>Phone</resource>
</users>
</item>
<item>
<name>Laptop</name>
<x509cert>BBBB</x509cert>
</item>
</items>"#
.parse()
.unwrap();
let mut list = ListCertsResponse::try_from(elem).unwrap();
assert_eq!(list.items.len(), 2);
let item = list.items.pop().unwrap();
assert_eq!(item.name.0, "Laptop");
assert_eq!(item.cert.data, [4, 16, 65]);
assert!(item.users.is_none());
let item = list.items.pop().unwrap();
assert_eq!(item.name.0, "Mobile Client");
assert_eq!(item.cert.data, b"\0\0\0");
assert_eq!(item.users.unwrap().resources.len(), 1);
}
#[test]
fn test_serialise() {
let append = Append {
name: Name::from_str("Mobile Client").unwrap(),
cert: Cert {
data: b"\0\0\0".to_vec(),
},
no_cert_management: None,
};
let elem: Element = append.into();
assert!(elem.is("append", ns::SASL_CERT));
let disable = Disable {
name: Name::from_str("Mobile Client").unwrap(),
};
let elem: Element = disable.into();
assert!(elem.is("disable", ns::SASL_CERT));
let elem = elem.children().cloned().collect::<Vec<_>>().pop().unwrap();
assert!(elem.is("name", ns::SASL_CERT));
assert_eq!(elem.text(), "Mobile Client");
}
#[test]
fn test_serialize_item() {
let reference: Element = "<item xmlns='urn:xmpp:saslcert:1'><name>Mobile Client</name><x509cert>AAAA</x509cert></item>"
.parse()
.unwrap();
let item = Item {
name: Name::from_str("Mobile Client").unwrap(),
cert: Cert {
data: b"\0\0\0".to_vec(),
},
no_cert_management: None,
users: None,
};
let serialized: Element = item.into();
assert_eq!(serialized, reference);
}
#[test]
fn test_serialize_append() {
let reference: Element = "<append xmlns='urn:xmpp:saslcert:1'><name>Mobile Client</name><x509cert>AAAA</x509cert></append>"
.parse()
.unwrap();
let append = Append {
name: Name::from_str("Mobile Client").unwrap(),
cert: Cert {
data: b"\0\0\0".to_vec(),
},
no_cert_management: None,
};
let serialized: Element = append.into();
assert_eq!(serialized, reference);
}
#[test]
fn test_serialize_disable() {
let reference: Element =
"<disable xmlns='urn:xmpp:saslcert:1'><name>Mobile Client</name></disable>"
.parse()
.unwrap();
let disable = Disable {
name: Name::from_str("Mobile Client").unwrap(),
};
let serialized: Element = disable.into();
assert_eq!(serialized, reference);
}
#[test]
fn test_serialize_revoke() {
let reference: Element =
"<revoke xmlns='urn:xmpp:saslcert:1'><name>Mobile Client</name></revoke>"
.parse()
.unwrap();
let revoke = Revoke {
name: Name::from_str("Mobile Client").unwrap(),
};
let serialized: Element = revoke.into();
assert_eq!(serialized, reference);
}
}