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::core::room::RoomRegistry;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::protos::xmpp;
|
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::protos::xmpp::stream::*;
|
||||||
use crate::util::xml::{Continuation, FromXml, Parser};
|
use crate::util::xml::{Continuation, FromXml, Parser, ToXml};
|
||||||
use crate::util::Terminator;
|
use crate::util::Terminator;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
@ -277,7 +279,31 @@ async fn socket_final(
|
||||||
match parser.consume(ns, &event) {
|
match parser.consume(ns, &event) {
|
||||||
Continuation::Final(res) => {
|
Continuation::Final(res) => {
|
||||||
let res = 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();
|
parser = proto::ClientPacket::parse();
|
||||||
}
|
}
|
||||||
Continuation::Continue(p) => parser = p,
|
Continuation::Continue(p) => parser = p,
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
use nom::AsBytes;
|
use nom::AsBytes;
|
||||||
use quick_xml::events::Event;
|
use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
|
||||||
use quick_xml::name::{Namespace, ResolveResult};
|
use quick_xml::name::{Namespace, ResolveResult};
|
||||||
|
|
||||||
use crate::prelude::*;
|
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";
|
pub const XMLNS: &'static str = "urn:ietf:params:xml:ns:xmpp-bind";
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
// TODO remove `pub` in newtypes, introduce validation
|
||||||
pub struct Name(String);
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
#[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)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub struct Resource(pub(super) String);
|
pub struct Resource(pub(super) String);
|
||||||
|
@ -23,6 +25,12 @@ pub struct Jid {
|
||||||
pub resource: Resource,
|
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.
|
/// Request to bind to a resource.
|
||||||
///
|
///
|
||||||
/// Example:
|
/// 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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use derive_more::From;
|
use derive_more::From;
|
||||||
use quick_xml::events::Event;
|
use quick_xml::events::attributes::Attribute;
|
||||||
use quick_xml::name::ResolveResult;
|
use quick_xml::events::{BytesEnd, BytesStart, Event};
|
||||||
|
use quick_xml::name::{QName, ResolveResult};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::util::xml::*;
|
use crate::util::xml::*;
|
||||||
|
@ -298,6 +299,47 @@ impl IqType {
|
||||||
t => Err(ffail!("Unknown iq type: {t}")),
|
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)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -9,6 +9,10 @@ pub trait FromXml: Sized {
|
||||||
fn parse() -> Self::P;
|
fn parse() -> Self::P;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ToXml: Sized {
|
||||||
|
fn serialize(&self, events: &mut Vec<Event<'static>>);
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Parser: Sized {
|
pub trait Parser: Sized {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue