forked from lavina/lavina
Dirty
This commit is contained in:
parent
1996c3d6c7
commit
32e228b4d3
|
@ -4,7 +4,7 @@ use quick_xml::events::Event;
|
||||||
|
|
||||||
use lavina_core::room::{RoomId, RoomRegistry};
|
use lavina_core::room::{RoomId, RoomRegistry};
|
||||||
use proto_xmpp::bind::{BindResponse, Jid, Name, Server};
|
use proto_xmpp::bind::{BindResponse, Jid, Name, Server};
|
||||||
use proto_xmpp::client::{Iq, IqError, IqErrorType, IqType};
|
use proto_xmpp::client::{Iq, IqError, IqErrorType, IqType, Message, MessageType};
|
||||||
use proto_xmpp::disco::{Feature, Identity, InfoQuery, Item, ItemQuery};
|
use proto_xmpp::disco::{Feature, Identity, InfoQuery, Item, ItemQuery};
|
||||||
use proto_xmpp::roster::RosterQuery;
|
use proto_xmpp::roster::RosterQuery;
|
||||||
use proto_xmpp::session::Session;
|
use proto_xmpp::session::Session;
|
||||||
|
@ -12,7 +12,7 @@ use proto_xmpp::session::Session;
|
||||||
use crate::proto::IqClientBody;
|
use crate::proto::IqClientBody;
|
||||||
use crate::XmppConnection;
|
use crate::XmppConnection;
|
||||||
|
|
||||||
use proto_xmpp::xml::ToXml;
|
use proto_xmpp::xml::{Ignore, ToXml};
|
||||||
|
|
||||||
impl<'a> XmppConnection<'a> {
|
impl<'a> XmppConnection<'a> {
|
||||||
pub async fn handle_iq(&self, output: &mut Vec<Event<'static>>, iq: Iq<IqClientBody>) {
|
pub async fn handle_iq(&self, output: &mut Vec<Event<'static>>, iq: Iq<IqClientBody>) {
|
||||||
|
@ -87,6 +87,9 @@ impl<'a> XmppConnection<'a> {
|
||||||
};
|
};
|
||||||
req.serialize(output);
|
req.serialize(output);
|
||||||
}
|
}
|
||||||
|
IqClientBody::MessageArchiveRequest(request) => {
|
||||||
|
// let response = self.mam().await?;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let req = Iq {
|
let req = Iq {
|
||||||
from: None,
|
from: None,
|
||||||
|
@ -220,4 +223,22 @@ impl<'a> XmppConnection<'a> {
|
||||||
};
|
};
|
||||||
ItemQuery { item }
|
ItemQuery { item }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn mam(&self) -> Result<Message<Ignore>, ()> {
|
||||||
|
// return Ok(());
|
||||||
|
Ok(Message::<Ignore> {
|
||||||
|
from: None,
|
||||||
|
id: Some("aacea".to_string()),
|
||||||
|
to: Some(Jid {
|
||||||
|
name: Some(Name("nikita".into())),
|
||||||
|
server: Server("vlnv.dev".into()),
|
||||||
|
resource: None,
|
||||||
|
}),
|
||||||
|
r#type: MessageType::Chat,
|
||||||
|
lang: None,
|
||||||
|
subject: Some("daa".into()),
|
||||||
|
body: "bbb".into(),
|
||||||
|
custom: vec![Ignore],
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ use lavina_core::prelude::*;
|
||||||
use proto_xmpp::bind::BindRequest;
|
use proto_xmpp::bind::BindRequest;
|
||||||
use proto_xmpp::client::{Iq, Message, Presence};
|
use proto_xmpp::client::{Iq, Message, Presence};
|
||||||
use proto_xmpp::disco::{InfoQuery, ItemQuery};
|
use proto_xmpp::disco::{InfoQuery, ItemQuery};
|
||||||
|
use proto_xmpp::mam::MessageArchiveRequest;
|
||||||
use proto_xmpp::roster::RosterQuery;
|
use proto_xmpp::roster::RosterQuery;
|
||||||
use proto_xmpp::session::Session;
|
use proto_xmpp::session::Session;
|
||||||
use proto_xmpp::xml::*;
|
use proto_xmpp::xml::*;
|
||||||
|
@ -18,6 +19,7 @@ pub enum IqClientBody {
|
||||||
Roster(RosterQuery),
|
Roster(RosterQuery),
|
||||||
DiscoInfo(InfoQuery),
|
DiscoInfo(InfoQuery),
|
||||||
DiscoItem(ItemQuery),
|
DiscoItem(ItemQuery),
|
||||||
|
MessageArchiveRequest(MessageArchiveRequest),
|
||||||
Unknown(Ignore),
|
Unknown(Ignore),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +40,7 @@ impl FromXml for IqClientBody {
|
||||||
RosterQuery,
|
RosterQuery,
|
||||||
InfoQuery,
|
InfoQuery,
|
||||||
ItemQuery,
|
ItemQuery,
|
||||||
|
MessageArchiveRequest,
|
||||||
{
|
{
|
||||||
delegate_parsing!(Ignore, namespace, event).into()
|
delegate_parsing!(Ignore, namespace, event).into()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
|
use std::str::from_utf8;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
@ -6,6 +7,7 @@ use anyhow::Result;
|
||||||
use assert_matches::*;
|
use assert_matches::*;
|
||||||
use prometheus::Registry as MetricsRegistry;
|
use prometheus::Registry as MetricsRegistry;
|
||||||
use quick_xml::events::Event;
|
use quick_xml::events::Event;
|
||||||
|
use quick_xml::name::LocalName;
|
||||||
use quick_xml::NsReader;
|
use quick_xml::NsReader;
|
||||||
use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader};
|
use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader};
|
||||||
use tokio::io::{ReadHalf as GenericReadHalf, WriteHalf as GenericWriteHalf};
|
use tokio::io::{ReadHalf as GenericReadHalf, WriteHalf as GenericWriteHalf};
|
||||||
|
@ -22,6 +24,10 @@ use lavina_core::room::RoomRegistry;
|
||||||
use projection_xmpp::{launch, RunningServer, ServerConfig};
|
use projection_xmpp::{launch, RunningServer, ServerConfig};
|
||||||
use proto_xmpp::xml::{Continuation, FromXml, Parser};
|
use proto_xmpp::xml::{Continuation, FromXml, Parser};
|
||||||
|
|
||||||
|
fn element_name<'a>(local_name: &LocalName<'a>) -> &'a str {
|
||||||
|
from_utf8(local_name.into_inner()).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn read_irc_message(reader: &mut BufReader<ReadHalf<'_>>, buf: &mut Vec<u8>) -> Result<usize> {
|
pub async fn read_irc_message(reader: &mut BufReader<ReadHalf<'_>>, buf: &mut Vec<u8>) -> Result<usize> {
|
||||||
let mut size = 0;
|
let mut size = 0;
|
||||||
let res = reader.read_until(b'\n', buf).await?;
|
let res = reader.read_until(b'\n', buf).await?;
|
||||||
|
@ -107,6 +113,7 @@ impl<'a> TestScopeTls<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IgnoreCertVerification;
|
struct IgnoreCertVerification;
|
||||||
|
|
||||||
impl ServerCertVerifier for IgnoreCertVerification {
|
impl ServerCertVerifier for IgnoreCertVerification {
|
||||||
fn verify_server_cert(
|
fn verify_server_cert(
|
||||||
&self,
|
&self,
|
||||||
|
@ -128,6 +135,7 @@ struct TestServer {
|
||||||
players: PlayerRegistry,
|
players: PlayerRegistry,
|
||||||
server: RunningServer,
|
server: RunningServer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestServer {
|
impl TestServer {
|
||||||
async fn start() -> Result<TestServer> {
|
async fn start() -> Result<TestServer> {
|
||||||
let _ = tracing_subscriber::fmt::try_init();
|
let _ = tracing_subscriber::fmt::try_init();
|
||||||
|
@ -300,3 +308,88 @@ async fn terminate_socket() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_message_archive_request() -> Result<()> {
|
||||||
|
let mut server = TestServer::start().await?;
|
||||||
|
|
||||||
|
// test scenario
|
||||||
|
|
||||||
|
server.storage.create_user("tester").await?;
|
||||||
|
server.storage.set_password("tester", "password").await?;
|
||||||
|
|
||||||
|
let mut stream = TcpStream::connect(server.server.addr).await?;
|
||||||
|
let mut s = TestScope::new(&mut stream);
|
||||||
|
tracing::info!("TCP connection established");
|
||||||
|
|
||||||
|
s.send(r#"<?xml version="1.0"?>"#).await?;
|
||||||
|
s.send(r#"<stream:stream xmlns:stream="http://etherx.jabber.org/streams" to="127.0.0.1" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns="jabber:client" version="1.0">"#).await?;
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Decl(_) => {});
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Start(b) => assert_eq!(b.local_name().into_inner(), b"stream"));
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Start(b) => assert_eq!(b.local_name().into_inner(), b"features"));
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Start(b) => assert_eq!(b.local_name().into_inner(), b"starttls"));
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Empty(b) => assert_eq!(b.local_name().into_inner(), b"required"));
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::End(b) => assert_eq!(b.local_name().into_inner(), b"starttls"));
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::End(b) => assert_eq!(b.local_name().into_inner(), b"features"));
|
||||||
|
s.send(r#"<starttls/>"#).await?;
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Empty(b) => assert_eq!(b.local_name().into_inner(), b"proceed"));
|
||||||
|
let buffer = s.buffer;
|
||||||
|
tracing::info!("TLS feature negotiation complete");
|
||||||
|
|
||||||
|
let connector = TlsConnector::from(Arc::new(
|
||||||
|
ClientConfig::builder()
|
||||||
|
.with_safe_defaults()
|
||||||
|
.with_custom_certificate_verifier(Arc::new(IgnoreCertVerification))
|
||||||
|
.with_no_client_auth(),
|
||||||
|
));
|
||||||
|
tracing::info!("Initiating TLS connection...");
|
||||||
|
let mut stream = connector.connect(ServerName::IpAddress(server.server.addr.ip()), stream).await?;
|
||||||
|
tracing::info!("TLS connection established");
|
||||||
|
|
||||||
|
let mut s = TestScopeTls::new(&mut stream, buffer);
|
||||||
|
|
||||||
|
s.send(r#"<?xml version="1.0"?>"#).await?;
|
||||||
|
s.send(r#"<stream:stream xmlns:stream="http://etherx.jabber.org/streams" to="127.0.0.1" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns="jabber:client" version="1.0">"#).await?;
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Decl(_) => {});
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Start(b) => assert_eq!(b.local_name().into_inner(), b"stream"));
|
||||||
|
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Start(b) => {
|
||||||
|
let local_name: &str = from_utf8(b.local_name().into_inner()).unwrap();
|
||||||
|
assert_eq!(local_name, "features")
|
||||||
|
});
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Start(b) => {
|
||||||
|
let local_name: &str = from_utf8(b.local_name().into_inner()).unwrap();
|
||||||
|
assert_eq!(local_name, "mechanisms")
|
||||||
|
});
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Start(b) => {
|
||||||
|
let local_name: &str = from_utf8(b.local_name().into_inner()).unwrap();
|
||||||
|
assert_eq!(local_name, "mechanism")
|
||||||
|
});
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Text(b) => {
|
||||||
|
// b.
|
||||||
|
// let local_name: &str = from_utf8(b.local_name().into_inner()).unwrap();
|
||||||
|
// assert_eq!(local_name, "mechanism")
|
||||||
|
});
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::End(b) => {
|
||||||
|
// let local_name: &str = from_utf8(b.local_name().into_inner()).unwrap();
|
||||||
|
// assert_eq!(local_name, "mechanism")
|
||||||
|
});
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::End(b) => {
|
||||||
|
let local_name: &str = from_utf8(b.local_name().into_inner()).unwrap();
|
||||||
|
assert_eq!(local_name, "mechanisms")
|
||||||
|
});
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::End(b) => {
|
||||||
|
assert_eq!(element_name(&b.local_name()), "features")
|
||||||
|
});
|
||||||
|
// s.send(r#"<iq type='get' id='juliet1'><query xmlns='urn:xmpp:mam:tmp' queryid='f27'/></iq>"#).await?;
|
||||||
|
assert_matches!(s.next_xml_event().await?, Event::Start(b) => {
|
||||||
|
assert_eq!(element_name(&b.local_name()), "message")
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.shutdown().await?;
|
||||||
|
|
||||||
|
// wrap up
|
||||||
|
|
||||||
|
server.server.terminate().await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -10,17 +10,17 @@ pub const DATA_XMLNS: &'static str = "jabber:x:data";
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||||
pub struct MessageArchiveRequest {
|
pub struct MessageArchiveRequest {
|
||||||
x: Option<X>,
|
pub x: Option<X>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||||
pub struct X {
|
pub struct X {
|
||||||
fields: Vec<Field>,
|
pub fields: Vec<Field>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||||
pub struct Field {
|
pub struct Field {
|
||||||
values: Vec<String>,
|
pub values: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromXmlTag for X {
|
impl FromXmlTag for X {
|
||||||
|
|
Loading…
Reference in New Issue