From db764b18f7f181807225ddf97c4f9b4256a197cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Tue, 27 Dec 2022 00:21:10 +0100 Subject: [PATCH] session: implement filter_presence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime “pep” Buquet --- src/occupant.rs | 4 ++-- src/presence.rs | 8 ++++++- src/session.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/occupant.rs b/src/occupant.rs index 9b416b7..9501980 100644 --- a/src/occupant.rs +++ b/src/occupant.rs @@ -174,7 +174,7 @@ mod tests { err => panic!("Err: {:?}", err), } - assert_eq!(occupant.sessions[0].presence, presence1); + assert_eq!(occupant.sessions[0].presence.show, Some(PresenceShow::Away)); let presence2 = PresenceFull::try_from( Presence::new(PresenceType::None) @@ -189,7 +189,7 @@ mod tests { err => panic!("Error: {:?}", err), } - assert_eq!(occupant.sessions[1].presence, presence2); + assert_eq!(occupant.sessions[1].presence.show, Some(PresenceShow::Xa)); let presence_leave_louise2 = PresenceFull::try_from( Presence::new(PresenceType::Unavailable) diff --git a/src/presence.rs b/src/presence.rs index 189eeed..9a1b208 100644 --- a/src/presence.rs +++ b/src/presence.rs @@ -15,7 +15,7 @@ use crate::error::Error; use std::convert::TryFrom; -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; use xmpp_parsers::{presence::Presence, Jid}; /// Presence that has a FullJid as destination (to). @@ -44,3 +44,9 @@ impl Deref for PresenceFull { &self.0 } } + +impl DerefMut for PresenceFull { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/src/session.rs b/src/session.rs index ac0a66f..1ff3123 100644 --- a/src/session.rs +++ b/src/session.rs @@ -16,7 +16,7 @@ use crate::error::Error; use crate::presence::PresenceFull; -use xmpp_parsers::{presence::Presence, FullJid, Jid}; +use xmpp_parsers::{presence::Presence, Element, FullJid, Jid}; pub type Nick = String; @@ -28,7 +28,16 @@ pub struct Session { impl Session { /// Ensure presence doesn't contain payloads that would impersonate us - fn filter_presence(presence: PresenceFull) -> PresenceFull { + fn filter_presence(mut presence: PresenceFull) -> PresenceFull { + presence.payloads.retain(|payload| { + // TODO: Add a ::is_a method in xmpp-parsers which takes a ref to avoid having to + // clone, and use this instead. + // TODO: Finish this list + !(Element::is(payload, "x", "http://jabber.org/protocol/muc") + || Element::is(payload, "x", "http://jabber.org/protocol/muc#user") + || Element::is(payload, "x", "http://jabber.org/protocol/muc#owner") + || Element::is(payload, "occupant-id", "urn:xmpp:occupant-id:0")) + }); presence } @@ -72,3 +81,50 @@ impl TryFrom for Session { }) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::templates::{LOUISE_FULL1, LOUISE_ROOM1_PART}; + use chrono::{FixedOffset, Utc}; + use xmpp_parsers::{ + date::DateTime, + idle::Idle, + muc::{Muc, MucUser}, + presence::{Presence, Type as PresenceType}, + Jid, + }; + + #[test] + fn filter_presence() { + let idle = Idle { + since: DateTime(Utc::now().with_timezone(&FixedOffset::east_opt(0).unwrap())), + }; + + let presence = PresenceFull::try_from( + Presence::new(PresenceType::None) + .with_from(Jid::Full(LOUISE_FULL1.clone())) + .with_to(Jid::Full(LOUISE_ROOM1_PART.clone())) + .with_payloads(vec![ + Muc::new().into(), + MucUser { + status: vec![], + items: vec![], + } + .into(), + idle.clone().into(), + ]), + ) + .unwrap(); + + let result = PresenceFull::try_from( + Presence::new(PresenceType::None) + .with_from(Jid::Full(LOUISE_FULL1.clone())) + .with_to(Jid::Full(LOUISE_ROOM1_PART.clone())) + .with_payloads(vec![idle.into()]), + ) + .unwrap(); + + assert_eq!(Session::filter_presence(presence), result); + } +}