From 1b592500420080f773d460f8fb8f0da75cf32f25 Mon Sep 17 00:00:00 2001 From: Nikita Vilunov Date: Tue, 14 May 2024 14:44:49 +0000 Subject: [PATCH] xmpp: add x-user element to muc presence response (#67) Reviewed-on: https://git.vilunov.me/lavina/lavina/pulls/67 --- crates/projection-xmpp/src/presence.rs | 13 +++++++++---- crates/proto-xmpp/src/client.rs | 3 +++ crates/proto-xmpp/src/muc/mod.rs | 13 ++++++++++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/crates/projection-xmpp/src/presence.rs b/crates/projection-xmpp/src/presence.rs index 3602cca..3712baa 100644 --- a/crates/projection-xmpp/src/presence.rs +++ b/crates/projection-xmpp/src/presence.rs @@ -6,6 +6,7 @@ use quick_xml::events::Event; use lavina_core::room::RoomId; use proto_xmpp::bind::{Jid, Name, Server}; use proto_xmpp::client::Presence; +use proto_xmpp::muc::XUser; use proto_xmpp::xml::{Ignore, ToXml}; use crate::XmppConnection; @@ -60,10 +61,10 @@ impl<'a> XmppConnection<'a> { } // todo: return Presence and serialize on the outside. - async fn muc_presence(&mut self, name: &Name) -> Result<(Presence<()>)> { + async fn muc_presence(&mut self, name: &Name) -> Result<(Presence)> { let a = self.user_handle.join_room(RoomId::from(name.0.clone())?).await?; // TODO handle bans - let response = Presence::<()> { + let response = Presence { to: Some(Jid { name: Some(self.user.xmpp_name.clone()), server: Server(self.hostname.clone()), @@ -74,6 +75,7 @@ impl<'a> XmppConnection<'a> { server: Server(self.hostname_rooms.clone()), resource: Some(self.user.xmpp_muc_name.clone()), }), + custom: vec![XUser], ..Default::default() }; Ok(response) @@ -91,6 +93,7 @@ mod tests { use lavina_core::player::PlayerId; use proto_xmpp::bind::{Jid, Name, Resource, Server}; use proto_xmpp::client::Presence; + use proto_xmpp::muc::XUser; #[tokio::test] async fn test_muc_joining() -> Result<()> { @@ -110,7 +113,7 @@ mod tests { let mut conn = expect_user_authenticated(&server, &user, &mut player_conn).await.unwrap(); let response = conn.muc_presence(&user.xmpp_name).await.unwrap(); - let expected = Presence::<()> { + let expected = Presence { to: Some(Jid { name: Some(conn.user.xmpp_name.clone()), server: Server(conn.hostname.clone()), @@ -121,6 +124,7 @@ mod tests { server: Server(conn.hostname_rooms.clone()), resource: Some(conn.user.xmpp_muc_name.clone()), }), + custom: vec![XUser], ..Default::default() }; assert_eq!(expected, response); @@ -149,7 +153,7 @@ mod tests { let mut conn = expect_user_authenticated(&server, &user, &mut player_conn).await.unwrap(); let response = conn.muc_presence(&user.xmpp_name).await.unwrap(); - let expected = Presence::<()> { + let expected = Presence { to: Some(Jid { name: Some(conn.user.xmpp_name.clone()), server: Server(conn.hostname.clone()), @@ -160,6 +164,7 @@ mod tests { server: Server(conn.hostname_rooms.clone()), resource: Some(conn.user.xmpp_muc_name.clone()), }), + custom: vec![XUser], ..Default::default() }; assert_eq!(expected, response); diff --git a/crates/proto-xmpp/src/client.rs b/crates/proto-xmpp/src/client.rs index c515e63..7b96507 100644 --- a/crates/proto-xmpp/src/client.rs +++ b/crates/proto-xmpp/src/client.rs @@ -669,6 +669,9 @@ impl ToXml for Presence { Event::End(BytesEnd::new("priority")), ]); } + for c in &self.custom { + c.serialize(events); + } events.push(Event::End(BytesEnd::new("presence"))); } } diff --git a/crates/proto-xmpp/src/muc/mod.rs b/crates/proto-xmpp/src/muc/mod.rs index f357dd0..61cf933 100644 --- a/crates/proto-xmpp/src/muc/mod.rs +++ b/crates/proto-xmpp/src/muc/mod.rs @@ -1,12 +1,13 @@ #![allow(unused_variables)] -use quick_xml::events::Event; +use quick_xml::events::{BytesStart, Event}; use quick_xml::name::ResolveResult; use crate::xml::*; use anyhow::{anyhow, Result}; pub const XMLNS: &'static str = "http://jabber.org/protocol/muc"; +pub const XMLNS_USER: &'static str = "http://jabber.org/protocol/muc#user"; #[derive(PartialEq, Eq, Debug, Default)] pub struct History { @@ -143,6 +144,16 @@ impl FromXml for X { } } +#[derive(Debug, PartialEq, Eq)] +pub struct XUser; +impl ToXml for XUser { + fn serialize(&self, output: &mut Vec>) { + let mut tag = BytesStart::new("x"); + tag.push_attribute(("xmlns", XMLNS_USER)); + output.push(Event::Empty(tag)); + } +} + #[cfg(test)] mod test { use super::*;