diff options
author | 2024-12-02 21:50:15 +0000 | |
---|---|---|
committer | 2024-12-02 21:50:15 +0000 | |
commit | be198ca15bbaf633c1535db5bae7091520546aed (patch) | |
tree | e7c33435851c4421bfb950818b285a00e63d93a0 /src/jabber.rs | |
parent | 859a19820d69eca5fca87fc01acad72a6355f97e (diff) | |
download | luz-be198ca15bbaf633c1535db5bae7091520546aed.tar.gz luz-be198ca15bbaf633c1535db5bae7091520546aed.tar.bz2 luz-be198ca15bbaf633c1535db5bae7091520546aed.zip |
implement bind
Diffstat (limited to 'src/jabber.rs')
-rw-r--r-- | src/jabber.rs | 111 |
1 files changed, 110 insertions, 1 deletions
diff --git a/src/jabber.rs b/src/jabber.rs index 599879d..96cd73a 100644 --- a/src/jabber.rs +++ b/src/jabber.rs @@ -13,6 +13,9 @@ use trust_dns_resolver::proto::rr::domain::IntoLabel; use crate::connection::{Tls, Unencrypted}; use crate::error::Error; +use crate::stanza::bind::{Bind, BindType, FullJidType, ResourceType}; +use crate::stanza::client::error::Error as ClientError; +use crate::stanza::client::iq::{Iq, IqType, Query}; use crate::stanza::sasl::{Auth, Challenge, Mechanisms, Response, ServerResponse}; use crate::stanza::starttls::{Proceed, StartTls}; use crate::stanza::stream::{Feature, Features, Stream}; @@ -147,7 +150,96 @@ where } pub async fn bind(&mut self) -> Result<()> { - todo!() + let iq_id = nanoid::nanoid!(); + if let Some(resource) = self.jid.clone().unwrap().resourcepart { + let iq = Iq { + from: None, + id: iq_id.clone(), + to: None, + r#type: IqType::Set, + lang: None, + query: Some(Query::Bind(Bind { + r#type: Some(BindType::Resource(ResourceType(resource))), + })), + errors: Vec::new(), + }; + self.writer.write_full(&iq).await?; + let result: Iq = self.reader.read().await?; + match result { + Iq { + from: _, + id, + to: _, + r#type: IqType::Result, + lang: _, + query: + Some(Query::Bind(Bind { + r#type: Some(BindType::Jid(FullJidType(jid))), + })), + errors: _, + } if id == iq_id => { + self.jid = Some(jid); + return Ok(()); + } + Iq { + from: _, + id, + to: _, + r#type: IqType::Error, + lang: _, + query: None, + errors, + } if id == iq_id => { + return Err(Error::ClientError( + errors.first().ok_or(Error::MissingError)?.clone(), + )) + } + _ => return Err(Error::UnexpectedElement(result.into_element())), + } + } else { + let iq = Iq { + from: None, + id: iq_id.clone(), + to: None, + r#type: IqType::Set, + lang: None, + query: Some(Query::Bind(Bind { r#type: None })), + errors: Vec::new(), + }; + self.writer.write_full(&iq).await?; + let result: Iq = self.reader.read().await?; + match result { + Iq { + from: _, + id, + to: _, + r#type: IqType::Result, + lang: _, + query: + Some(Query::Bind(Bind { + r#type: Some(BindType::Jid(FullJidType(jid))), + })), + errors: _, + } if id == iq_id => { + self.jid = Some(jid); + return Ok(()); + } + Iq { + from: _, + id, + to: _, + r#type: IqType::Error, + lang: _, + query: None, + errors, + } if id == iq_id => { + return Err(Error::ClientError( + errors.first().ok_or(Error::MissingError)?.clone(), + )) + } + _ => return Err(Error::UnexpectedElement(result.into_element())), + } + } } #[instrument] @@ -324,9 +416,12 @@ impl std::fmt::Debug for Jabber<Unencrypted> { #[cfg(test)] mod tests { + use std::time::Duration; + use super::*; use crate::connection::Connection; use test_log::test; + use tokio::time::sleep; #[test(tokio::test)] async fn start_stream() { @@ -373,4 +468,18 @@ mod tests { Feature::Unknown => todo!(), } } + + #[tokio::test] + async fn negotiate() { + let jabber = Connection::connect_user("test@blos.sm", "slayed".to_string()) + .await + .unwrap() + .ensure_tls() + .await + .unwrap() + .negotiate() + .await + .unwrap(); + sleep(Duration::from_secs(5)).await + } } |