xmpp-rs/tokio-xmpp/src/component/login.rs

61 lines
2 KiB
Rust
Raw Normal View History

use std::io;
use futures::{SinkExt, StreamExt};
use tokio::io::{AsyncBufRead, AsyncWrite};
2024-08-11 12:21:06 +02:00
use xmpp_parsers::{component::Handshake, jid::Jid, ns};
2017-07-22 01:59:51 +01:00
use crate::component::ServerConnector;
use crate::error::{AuthError, Error};
use crate::xmlstream::{ReadError, XmppStream, XmppStreamElement};
2024-08-11 12:21:06 +02:00
/// Log into an XMPP server as a client with a jid+pass
pub async fn component_login<C: ServerConnector>(
connector: C,
jid: Jid,
password: String,
) -> Result<XmppStream<C::Stream>, Error> {
let password = password;
let mut stream = connector.connect(&jid, ns::COMPONENT).await?;
let header = stream.take_header();
let mut stream = stream.skip_features();
let stream_id = match header.id {
Some(ref v) => &**v,
None => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"stream id missing on component stream",
)
.into())
}
};
auth(&mut stream, stream_id, &password).await?;
Ok(stream)
2024-08-11 12:21:06 +02:00
}
2017-07-22 01:59:51 +01:00
pub async fn auth<S: AsyncBufRead + AsyncWrite + Unpin>(
stream: &mut XmppStream<S>,
stream_id: &str,
password: &str,
2020-03-05 01:25:24 +01:00
) -> Result<(), Error> {
let nonza = Handshake::from_password_and_stream_id(password, stream_id);
stream
.send(&XmppStreamElement::ComponentHandshake(nonza))
.await?;
2020-03-05 01:25:24 +01:00
loop {
match stream.next().await {
Some(Ok(XmppStreamElement::ComponentHandshake(_))) => {
2020-03-05 01:25:24 +01:00
return Ok(());
}
Some(Ok(_)) => {
2020-03-05 01:25:24 +01:00
return Err(AuthError::ComponentFail.into());
}
Some(Err(ReadError::SoftTimeout)) => (),
Some(Err(ReadError::HardError(e))) => return Err(e.into()),
Some(Err(ReadError::ParseError(e))) => {
return Err(io::Error::new(io::ErrorKind::InvalidData, e).into())
}
Some(Err(ReadError::StreamFooterReceived)) | None => return Err(Error::Disconnected),
2017-07-22 01:59:51 +01:00
}
}
}