Return error on nickname conflict

Fixing the 'join_nick_already_assigned' test on the way.

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
Maxime “pep” Buquet 2023-01-01 23:01:01 +01:00
parent 1a5101c9b2
commit 3f90060c08
Signed by: pep
GPG key ID: DEDA74AEECA9D0F2
2 changed files with 75 additions and 25 deletions

View file

@ -41,7 +41,28 @@ pub async fn handle_presence<C: ComponentTrait>(
if let Ok(presence) = PresenceFull::try_from(presence.clone()) { if let Ok(presence) = PresenceFull::try_from(presence.clone()) {
match presence.type_ { match presence.type_ {
PresenceType::None => { PresenceType::None => {
handle_presence_full_available(component, presence.clone(), rooms).await? match handle_presence_full_available(component, presence.clone(), rooms).await {
Ok(()) => (),
Err(Error::NickAlreadyAssigned(nick)) => {
let realjid = presence.from.clone().unwrap();
let participant = presence.to.clone().unwrap();
let error = Presence::new(PresenceType::Error)
.with_from(participant)
.with_to(realjid)
.with_payloads(vec![
Muc::new().into(),
StanzaError::new(
ErrorType::Cancel,
DefinedCondition::Conflict,
"en",
format!("Nickname conflict: {nick}"),
)
.into(),
]);
component.send_stanza(error).await?;
}
Err(_) => todo!(),
}
} }
PresenceType::Unavailable => { PresenceType::Unavailable => {
handle_presence_full_unavailable(component, presence.clone(), rooms).await? handle_presence_full_unavailable(component, presence.clone(), rooms).await?
@ -85,23 +106,7 @@ async fn handle_presence_full_available<C: ComponentTrait>(
debug!("Presence received to existing room: {}", &roomjid); debug!("Presence received to existing room: {}", &roomjid);
if let ControlFlow::Break(_) = muc { if let ControlFlow::Break(_) = muc {
// <{muc}x/> was found // <{muc}x/> was found
match room.add_session(component, presence.clone()).await { room.add_session(component, presence.clone()).await?;
Ok(_) => (),
Err(Error::NickAlreadyAssigned(nick)) => {
let error = Presence::new(PresenceType::Error)
.with_from(participant.clone())
.with_to(realjid.clone())
.with_payloads(vec![StanzaError::new(
ErrorType::Cancel,
DefinedCondition::Conflict,
"en",
format!("Nickname conflict: {nick}"),
)
.into()]);
component.send_stanza(error).await?;
}
err => err.unwrap(),
}
} else if let ControlFlow::Continue(_) = muc { } else if let ControlFlow::Continue(_) = muc {
// <{muc}x/> wasn't found // <{muc}x/> wasn't found

View file

@ -141,13 +141,16 @@ async fn join_nick_already_assigned() {
Presence::new(PresenceType::Error) Presence::new(PresenceType::Error)
.with_from(LOUISE_ROOM1_PART.clone()) .with_from(LOUISE_ROOM1_PART.clone())
.with_to(Jid::Full(SUGAKO_FULL1.clone())) .with_to(Jid::Full(SUGAKO_FULL1.clone()))
.with_payloads(vec![StanzaError::new( .with_payloads(vec![
ErrorType::Cancel, Muc::new().into(),
DefinedCondition::Conflict, StanzaError::new(
"en", ErrorType::Cancel,
format!("Nickname conflict: {}", LOUISE_NICK), DefinedCondition::Conflict,
) "en",
.into()]), format!("Nickname conflict: {}", LOUISE_NICK),
)
.into(),
]),
); );
handle_stanza(&mut component, &mut rooms).await.unwrap(); handle_stanza(&mut component, &mut rooms).await.unwrap();
@ -638,3 +641,45 @@ async fn nickname_change() {
handle_stanza(&mut component, &mut rooms).await.unwrap(); handle_stanza(&mut component, &mut rooms).await.unwrap();
} }
#[tokio::test]
async fn nickname_conflict() {
let mut rooms: HashMap<BareJid, Room> = HashMap::new();
rooms.insert(
ROOM1_BARE.clone(),
new_room(
ROOM1_BARE.clone(),
vec![
(LOUISE_NICK, vec![LOUISE_FULL1.clone()]),
(SUGAKO_NICK, vec![SUGAKO_FULL1.clone()]),
],
)
.await,
);
let update: Element = Presence::new(PresenceType::None)
.with_from(Jid::Full(LOUISE_FULL1.clone()))
.with_to(Jid::Full(SUGAKO_ROOM1_PART.clone()))
.into();
let mut component = TestComponent::new(vec![update]);
// Conflict presence
component.expect(
Presence::new(PresenceType::Error)
.with_from(Jid::Full(SUGAKO_ROOM1_PART.clone()))
.with_to(Jid::Full(LOUISE_FULL1.clone()))
.with_payloads(vec![
Muc::new().into(),
StanzaError::new(
ErrorType::Cancel,
DefinedCondition::Conflict,
"en",
format!("Nickname conflict: {}", SUGAKO_NICK),
)
.into(),
]),
);
handle_stanza(&mut component, &mut rooms).await.unwrap();
}