forked from lavina/lavina
feat(xmpp): answer to bind requests
This commit is contained in:
parent
4730526fee
commit
4107c5b663
|
@ -23,8 +23,10 @@ use crate::core::player::PlayerRegistry;
|
|||
use crate::core::room::RoomRegistry;
|
||||
use crate::prelude::*;
|
||||
use crate::protos::xmpp;
|
||||
use crate::protos::xmpp::bind::{BindResponse, Jid, Name, Server};
|
||||
use crate::protos::xmpp::client::Iq;
|
||||
use crate::protos::xmpp::stream::*;
|
||||
use crate::util::xml::{Continuation, FromXml, Parser};
|
||||
use crate::util::xml::{Continuation, FromXml, Parser, ToXml};
|
||||
use crate::util::Terminator;
|
||||
|
||||
#[derive(Deserialize, Debug, Clone)]
|
||||
|
@ -277,7 +279,31 @@ async fn socket_final(
|
|||
match parser.consume(ns, &event) {
|
||||
Continuation::Final(res) => {
|
||||
let res = res?;
|
||||
dbg!(res);
|
||||
dbg!(&res);
|
||||
match res {
|
||||
proto::ClientPacket::Iq(iq) => match iq.body {
|
||||
proto::IqClientBody::Bind(b) => {
|
||||
let mut events = vec![];
|
||||
let req = Iq {
|
||||
from: None,
|
||||
id: iq.id,
|
||||
to: None,
|
||||
r#type: xmpp::client::IqType::Result,
|
||||
body: BindResponse(Jid {
|
||||
name: Name("darova".to_string()),
|
||||
server: Server("localhost".to_string()),
|
||||
resource: b.0,
|
||||
}),
|
||||
};
|
||||
req.serialize(&mut events);
|
||||
for i in events {
|
||||
xml_writer.write_event_async(i).await?;
|
||||
}
|
||||
xml_writer.get_mut().flush().await?;
|
||||
}
|
||||
},
|
||||
proto::ClientPacket::Message(_) => todo!(),
|
||||
}
|
||||
parser = proto::ClientPacket::parse();
|
||||
}
|
||||
Continuation::Continue(p) => parser = p,
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
use nom::AsBytes;
|
||||
use quick_xml::events::Event;
|
||||
use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
|
||||
use quick_xml::name::{Namespace, ResolveResult};
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::util::xml::{Continuation, FromXml, Parser};
|
||||
use crate::util::xml::{Continuation, FromXml, Parser, ToXml};
|
||||
|
||||
pub const XMLNS: &'static str = "urn:ietf:params:xml:ns:xmpp-bind";
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct Name(String);
|
||||
// TODO remove `pub` in newtypes, introduce validation
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct Server(String);
|
||||
pub struct Name(pub String);
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct Server(pub String);
|
||||
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct Resource(pub(super) String);
|
||||
|
@ -23,6 +25,12 @@ pub struct Jid {
|
|||
pub resource: Resource,
|
||||
}
|
||||
|
||||
impl Jid {
|
||||
pub fn to_string(&self) -> String {
|
||||
format!("{}@{}/{}", self.name.0, self.server.0, self.resource.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Request to bind to a resource.
|
||||
///
|
||||
/// Example:
|
||||
|
@ -121,7 +129,21 @@ impl Parser for BindRequestParser {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct BindResponse(Jid);
|
||||
pub struct BindResponse(pub Jid);
|
||||
|
||||
impl ToXml for BindResponse {
|
||||
fn serialize(&self, events: &mut Vec<Event<'static>>) {
|
||||
events.extend_from_slice(&[
|
||||
Event::Start(BytesStart::new(
|
||||
r#"bind xmlns="urn:ietf:params:xml:ns:xmpp-bind""#,
|
||||
)),
|
||||
Event::Start(BytesStart::new(r#"jid"#)),
|
||||
Event::Text(BytesText::new(self.0.to_string().as_str()).into_owned()),
|
||||
Event::End(BytesEnd::new("jid")),
|
||||
Event::End(BytesEnd::new("bind")),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use derive_more::From;
|
||||
use quick_xml::events::Event;
|
||||
use quick_xml::name::ResolveResult;
|
||||
use quick_xml::events::attributes::Attribute;
|
||||
use quick_xml::events::{BytesEnd, BytesStart, Event};
|
||||
use quick_xml::name::{QName, ResolveResult};
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::util::xml::*;
|
||||
|
@ -298,6 +299,47 @@ impl IqType {
|
|||
t => Err(ffail!("Unknown iq type: {t}")),
|
||||
}
|
||||
}
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
IqType::Error => "error",
|
||||
IqType::Get => "get",
|
||||
IqType::Result => "result",
|
||||
IqType::Set => "set",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToXml> ToXml for Iq<T> {
|
||||
fn serialize(&self, events: &mut Vec<Event<'static>>) {
|
||||
let start = format!(r#"iq xmlns="{}""#, XMLNS);
|
||||
let mut start = BytesStart::new(start);
|
||||
let mut attrs = vec![];
|
||||
if let Some(ref from) = self.from {
|
||||
attrs.push(Attribute {
|
||||
key: QName(b"from"),
|
||||
value: from.as_bytes().into(),
|
||||
});
|
||||
};
|
||||
if let Some(ref to) = self.to {
|
||||
attrs.push(Attribute {
|
||||
key: QName(b"to"),
|
||||
value: to.as_bytes().into(),
|
||||
});
|
||||
}
|
||||
attrs.push(Attribute {
|
||||
key: QName(b"id"),
|
||||
value: self.id.as_bytes().into(),
|
||||
});
|
||||
attrs.push(Attribute {
|
||||
key: QName(b"type"),
|
||||
value: self.r#type.as_str().as_bytes().into(),
|
||||
});
|
||||
start.extend_attributes(attrs.into_iter());
|
||||
|
||||
events.push(Event::Start(start));
|
||||
self.body.serialize(events);
|
||||
events.push(Event::End(BytesEnd::new("iq")));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -9,6 +9,10 @@ pub trait FromXml: Sized {
|
|||
fn parse() -> Self::P;
|
||||
}
|
||||
|
||||
pub trait ToXml: Sized {
|
||||
fn serialize(&self, events: &mut Vec<Event<'static>>);
|
||||
}
|
||||
|
||||
pub trait Parser: Sized {
|
||||
type Output;
|
||||
|
||||
|
|
Loading…
Reference in New Issue