diff options
Diffstat (limited to 'src/stanza/sasl.rs')
-rw-r--r-- | src/stanza/sasl.rs | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/stanza/sasl.rs b/src/stanza/sasl.rs index 8b13789..6ac4fc9 100644 --- a/src/stanza/sasl.rs +++ b/src/stanza/sasl.rs @@ -1 +1,170 @@ +use std::ops::Deref; +use peanuts::{ + element::{FromElement, IntoElement}, + DeserializeError, Element, +}; +use tracing::debug; + +pub const XMLNS: &str = "urn:ietf:params:xml:ns:xmpp-sasl"; + +#[derive(Debug, Clone)] +pub struct Mechanisms { + pub mechanisms: Vec<String>, +} + +impl FromElement for Mechanisms { + fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { + element.check_name("mechanisms")?; + element.check_namespace(XMLNS)?; + debug!("getting mechanisms"); + let mechanisms: Vec<Mechanism> = element.pop_children()?; + debug!("gottting mechanisms"); + let mechanisms = mechanisms + .into_iter() + .map(|Mechanism(mechanism)| mechanism) + .collect(); + debug!("gottting mechanisms"); + + Ok(Mechanisms { mechanisms }) + } +} + +impl IntoElement for Mechanisms { + fn builder(&self) -> peanuts::element::ElementBuilder { + Element::builder("mechanisms", Some(XMLNS)).push_children( + self.mechanisms + .iter() + .map(|mechanism| Mechanism(mechanism.to_string())) + .collect(), + ) + } +} + +pub struct Mechanism(String); + +impl FromElement for Mechanism { + fn from_element(mut element: peanuts::Element) -> peanuts::element::DeserializeResult<Self> { + element.check_name("mechanism")?; + element.check_namespace(XMLNS)?; + + let mechanism = element.pop_value()?; + + Ok(Mechanism(mechanism)) + } +} + +impl IntoElement for Mechanism { + fn builder(&self) -> peanuts::element::ElementBuilder { + Element::builder("mechanism", Some(XMLNS)).push_text(self.0.clone()) + } +} + +impl Deref for Mechanism { + type Target = str; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug)] +pub struct Auth { + pub mechanism: String, + pub sasl_data: String, +} + +impl IntoElement for Auth { + fn builder(&self) -> peanuts::element::ElementBuilder { + Element::builder("auth", Some(XMLNS)) + .push_attribute("mechanism", self.mechanism.clone()) + .push_text(self.sasl_data.clone()) + } +} + +#[derive(Debug)] +pub struct Challenge(String); + +impl Deref for Challenge { + type Target = str; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl FromElement for Challenge { + fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { + element.check_name("challenge")?; + element.check_namespace(XMLNS)?; + + let sasl_data = element.value()?; + + Ok(Challenge(sasl_data)) + } +} + +#[derive(Debug)] +pub struct Success(String); + +impl Deref for Success { + type Target = str; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl FromElement for Success { + fn from_element(mut element: Element) -> peanuts::element::DeserializeResult<Self> { + element.check_name("success")?; + element.check_namespace(XMLNS)?; + + let sasl_data = element.value()?; + + Ok(Success(sasl_data)) + } +} + +#[derive(Debug)] +pub enum ServerResponse { + Challenge(Challenge), + Success(Success), +} + +impl FromElement for ServerResponse { + fn from_element(element: Element) -> peanuts::element::DeserializeResult<Self> { + match element.identify() { + (Some(XMLNS), "challenge") => { + Ok(ServerResponse::Challenge(Challenge::from_element(element)?)) + } + (Some(XMLNS), "success") => { + Ok(ServerResponse::Success(Success::from_element(element)?)) + } + _ => Err(DeserializeError::UnexpectedElement(element)), + } + } +} + +#[derive(Debug)] +pub struct Response(String); + +impl Response { + pub fn new(response: String) -> Self { + Self(response) + } +} + +impl Deref for Response { + type Target = str; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl IntoElement for Response { + fn builder(&self) -> peanuts::element::ElementBuilder { + Element::builder("reponse", Some(XMLNS)).push_text(self.0.clone()) + } +} |