aboutsummaryrefslogtreecommitdiffstats
path: root/src/stanza/sasl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/stanza/sasl.rs')
-rw-r--r--src/stanza/sasl.rs169
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())
+ }
+}