Reject presence updates when not joined (gc1 joins)

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2022-12-17 14:06:06 +01:00
parent 132757c8b3
commit 9b7d3fd9f9
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
2 changed files with 59 additions and 24 deletions

View file

@ -27,7 +27,10 @@ use xmpp_parsers::{
disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity}, disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity},
iq::{Iq, IqType}, iq::{Iq, IqType},
message::Message, message::Message,
muc::Muc, muc::{
user::{Affiliation, Item as MucItem, Reason, Role, Status as MucStatus},
Muc, MucUser,
},
ns, ns,
ping::Ping, ping::Ping,
presence::{Presence, Type as PresenceType}, presence::{Presence, Type as PresenceType},
@ -244,8 +247,8 @@ async fn handle_presence<C: ComponentTrait>(
Ok(_) => (), Ok(_) => (),
Err(Error::NickAlreadyAssigned(nick)) => { Err(Error::NickAlreadyAssigned(nick)) => {
let error = Presence::new(PresenceType::Error) let error = Presence::new(PresenceType::Error)
.with_from(participant) .with_from(participant.clone())
.with_to(realjid) .with_to(realjid.clone())
.with_payloads(vec![ .with_payloads(vec![
StanzaError::new( StanzaError::new(
ErrorType::Cancel, ErrorType::Cancel,
@ -259,10 +262,28 @@ async fn handle_presence<C: ComponentTrait>(
err => err.unwrap(), err => err.unwrap(),
} }
} else if let ControlFlow::Continue(_) = muc { } else if let ControlFlow::Continue(_) = muc {
if room.is_joined(&realjid) { match room.update_presence(component, presence.clone()).await {
room.update_presence(component, presence.clone()).await? Ok(()) => (),
} else { Err(Error::ParticipantNotFound(_)) => {
// TODO: We don't want to support GC1. Error let error = Presence::new(PresenceType::Unavailable)
.with_from(participant)
.with_to(realjid)
.with_payloads(vec![MucUser {
status: vec![
MucStatus::SelfPresence,
MucStatus::Kicked,
MucStatus::ServiceErrorKick,
],
items: {
let mut item = MucItem::new(Affiliation::None, Role::None);
item.reason = Some(Reason(String::from("You are not in the room.")));
vec![item]
},
}
.into()]);
component.send_stanza(error).await?
},
err => err?,
} }
} }
} else { } else {

View file

@ -18,7 +18,7 @@ use crate::handlers::handle_stanza;
use crate::room::Room; use crate::room::Room;
use crate::tests::templates::{ use crate::tests::templates::{
two_participant_room, LOUISE_FULL1, LOUISE_FULL2, LOUISE_NICK, LOUISE_ROOM1_PART, ROOM1_BARE, two_participant_room, LOUISE_FULL1, LOUISE_FULL2, LOUISE_NICK, LOUISE_ROOM1_PART, ROOM1_BARE,
SUGAKO_FULL1, SUGAKO_ROOM1_PART, ROSA_FULL1, ROSA_ROOM1_PART, SUGAKO_FULL1, SUGAKO_ROOM1_PART,
}; };
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
@ -28,7 +28,7 @@ use xmpp_parsers::{
delay::Delay, delay::Delay,
message::{Message, MessageType, Subject as MessageSubject}, message::{Message, MessageType, Subject as MessageSubject},
muc::{ muc::{
user::{Affiliation, Item as MucItem, Role, Status as MucStatus}, user::{Affiliation, Item as MucItem, Reason, Role, Status as MucStatus},
Muc, MucUser, Muc, MucUser,
}, },
presence::{Presence, Show as PresenceShow, Type as PresenceType}, presence::{Presence, Show as PresenceShow, Type as PresenceType},
@ -633,26 +633,40 @@ async fn test_presence_update_joined() {
handle_stanza(&mut component, &mut rooms).await.unwrap(); handle_stanza(&mut component, &mut rooms).await.unwrap();
} }
#[ignore]
#[tokio::test] #[tokio::test]
async fn test_presence_update_not_joined() { async fn test_presence_update_not_joined() {
// https://xmpp.org/extensions/xep-0045.html#example-43 // https://xmpp.org/extensions/xep-0045.html#example-43
// GC1 join presence // GC1 join presence
// <presence
// from='coven@chat.shakespeare.lit/thirdwitch'
// to='hag66@shakespeare.lit/pda'
// type='unavailable'>
// <x xmlns='http://jabber.org/protocol/muc#user'>
// <item affiliation='none' role='none'>
// <reason>You are not in the room.</reason>
// </item>
// <status code='110'/>
// <status code='307'/>
// <status code='333'/>
// </x>
// </presence>
todo!() let update: Element = Presence::new(PresenceType::None)
.with_from(Jid::Full(ROSA_FULL1.clone()))
.with_to(Jid::Full(ROSA_ROOM1_PART.clone()))
.into();
let mut component = TestComponent::new(vec![update]);
let mut rooms: HashMap<BareJid, Room> = HashMap::new();
rooms.insert(ROOM1_BARE.clone(), two_participant_room(ROOM1_BARE.clone()));
component.expect(
Presence::new(PresenceType::Unavailable)
.with_from(Jid::Full(ROSA_ROOM1_PART.clone()))
.with_to(Jid::Full(ROSA_FULL1.clone()))
.with_payloads(vec![MucUser {
status: vec![
MucStatus::SelfPresence,
MucStatus::Kicked,
MucStatus::ServiceErrorKick,
],
items: {
let mut item = MucItem::new(Affiliation::None, Role::None);
item.reason = Some(Reason(String::from("You are not in the room.")));
vec![item]
},
}
.into()]),
);
handle_stanza(&mut component, &mut rooms).await.unwrap();
} }
#[ignore] #[ignore]