diff --git a/src/lib.rs b/src/lib.rs index 36b4b3e7..3f3df913 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,6 +55,8 @@ pub mod presence; pub mod iq; /// RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core pub mod stanza_error; +/// RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core +pub mod sasl; /// RFC 6121: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence pub mod roster; diff --git a/src/macros.rs b/src/macros.rs index 8fb57363..24041cb0 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -344,7 +344,10 @@ macro_rules! generate_elem_id { } macro_rules! generate_element_with_text { - ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:expr, [$($(#[$attr_meta:meta])* $attr:ident: $attr_type:ty = $attr_name:tt => $attr_action:tt),+], $text_ident:ident: $codec:ident < $text_type:ty >) => ( + ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:expr, $text_ident:ident: $codec:ident < $text_type:ty >) => ( + generate_element_with_text!($(#[$meta])* $elem, $name, $ns, [], $text_ident: $codec<$text_type>); + ); + ($(#[$meta:meta])* $elem:ident, $name:tt, $ns:expr, [$($(#[$attr_meta:meta])* $attr:ident: $attr_type:ty = $attr_name:tt => $attr_action:tt),*], $text_ident:ident: $codec:ident < $text_type:ty >) => ( $(#[$meta])* #[derive(Debug, Clone)] pub struct $elem { diff --git a/src/ns.rs b/src/ns.rs index dcc3946c..f17e602b 100644 --- a/src/ns.rs +++ b/src/ns.rs @@ -9,6 +9,8 @@ pub const JABBER_CLIENT: &str = "jabber:client"; /// RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core pub const XMPP_STANZAS: &str = "urn:ietf:params:xml:ns:xmpp-stanzas"; +/// RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core +pub const SASL: &str = "urn:ietf:params:xml:ns:xmpp-sasl"; /// RFC 6121: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence pub const ROSTER: &str = "jabber:iq:roster"; diff --git a/src/sasl.rs b/src/sasl.rs new file mode 100644 index 00000000..a0ab15bb --- /dev/null +++ b/src/sasl.rs @@ -0,0 +1,53 @@ +// Copyright (c) 2018 Emmanuel Gil Peyrot +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +use try_from::TryFrom; +use std::str::FromStr; + +use minidom::{Element, IntoAttributeValue}; + +use error::Error; + +use ns; +use helpers::Base64; + +generate_attribute!(Mechanism, "mechanism", { + Plain => "PLAIN", + ScramSha1 => "SCRAM-SHA-1", + Anonymous => "ANONYMOUS", +}); + +generate_element_with_text!(Auth, "auth", ns::SASL, + [ + mechanism: Mechanism = "mechanism" => required + ], + data: Base64> +); + +generate_element_with_text!(Challenge, "challenge", ns::SASL, + data: Base64> +); + +generate_element_with_text!(Response, "response", ns::SASL, + data: Base64> +); + +generate_element_with_text!(Success, "success", ns::SASL, + data: Base64> +); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_simple() { + let elem: Element = "".parse().unwrap(); + let auth = Auth::try_from(elem).unwrap(); + assert_eq!(auth.mechanism, Mechanism::Plain); + assert!(auth.data.is_empty()); + } +}