auth.rs

 1use futures::stream::StreamExt;
 2use std::marker::Unpin;
 3use tokio::io::{AsyncRead, AsyncWrite};
 4use xmpp_parsers::component::Handshake;
 5
 6use crate::xmpp_codec::Packet;
 7use crate::xmpp_stream::XMPPStream;
 8use crate::{AuthError, Error};
 9
10const NS_JABBER_COMPONENT_ACCEPT: &str = "jabber:component:accept";
11
12pub async fn auth<S: AsyncRead + AsyncWrite + Unpin>(
13    stream: &mut XMPPStream<S>,
14    password: String,
15) -> Result<(), Error> {
16    let nonza = Handshake::from_password_and_stream_id(&password, &stream.id);
17    stream.send_stanza(nonza).await?;
18
19    loop {
20        match stream.next().await {
21            Some(Ok(Packet::Stanza(ref stanza)))
22                if stanza.is("handshake", NS_JABBER_COMPONENT_ACCEPT) =>
23            {
24                return Ok(());
25            }
26            Some(Ok(Packet::Stanza(ref stanza)))
27                if stanza.is("error", "http://etherx.jabber.org/streams") =>
28            {
29                return Err(AuthError::ComponentFail.into());
30            }
31            Some(_) => {}
32            None => return Err(Error::Disconnected),
33        }
34    }
35}