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