1// Copyright (c) 2018 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7use helpers::PlainText;
8use sha1::Sha1;
9use digest::Digest;
10
11generate_element!(
12 /// The main authentication mechanism for components.
13 Handshake, "handshake", COMPONENT,
14 text: (
15 /// If Some, contains the hex-encoded SHA-1 of the concatenation of the
16 /// stream id and the password, and is used to authenticate against the
17 /// server.
18 ///
19 /// If None, it is the successful reply from the server, the stream is now
20 /// fully established and both sides can now exchange stanzas.
21 data: PlainText<Option<String>>
22 )
23);
24
25impl Handshake {
26 /// Creates a successful reply from a server.
27 pub fn new() -> Handshake {
28 Handshake {
29 data: None,
30 }
31 }
32
33 /// Creates an authentication request from the component.
34 pub fn from_password_and_stream_id(password: &str, stream_id: &str) -> Handshake {
35 let input = String::from(stream_id) + password;
36 let hash = Sha1::digest(input.as_bytes());
37 let content = format!("{:x}", hash);
38 Handshake {
39 data: Some(content),
40 }
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47 use try_from::TryFrom;
48 use minidom::Element;
49
50 #[test]
51 fn test_size() {
52 assert_size!(Handshake, 24);
53 }
54
55 #[test]
56 fn test_simple() {
57 let elem: Element = "<handshake xmlns='jabber:component:accept'/>".parse().unwrap();
58 let handshake = Handshake::try_from(elem).unwrap();
59 assert_eq!(handshake.data, None);
60
61 let elem: Element = "<handshake xmlns='jabber:component:accept'>Coucou</handshake>".parse().unwrap();
62 let handshake = Handshake::try_from(elem).unwrap();
63 assert_eq!(handshake.data, Some(String::from("Coucou")));
64 }
65
66 #[test]
67 fn test_constructors() {
68 let handshake = Handshake::new();
69 assert_eq!(handshake.data, None);
70
71 let handshake = Handshake::from_password_and_stream_id("123456", "sid");
72 assert_eq!(handshake.data, Some(String::from("9accec263ab84a43c6037ccf7cd48cb1d3f6df8e")));
73 }
74}