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