handlers: pinging room unsupported until affiliations are implemented
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
2a2d8cd051
commit
132757c8b3
3 changed files with 97 additions and 28 deletions
|
@ -38,6 +38,8 @@ pub enum Error {
|
|||
SecondarySession(Session),
|
||||
/// Raised when a JID was supposed to be present
|
||||
MissingJid,
|
||||
/// Unhandled Iq with error description
|
||||
UnhandledIq(String),
|
||||
/// Jid Parse errors
|
||||
Jid(Box<JidParseError>),
|
||||
/// TokioXMPP errors
|
||||
|
@ -58,6 +60,7 @@ impl fmt::Display for Error {
|
|||
Error::ParticipantNotFound(err) => write!(f, "Participant not found: {}", err),
|
||||
Error::SecondarySession(err) => write!(f, "Secondary session: {:?}", err),
|
||||
Error::MissingJid => write!(f, "Missing JID"),
|
||||
Error::UnhandledIq(err) => write!(f, "Unhandled Iq: {:?}", err),
|
||||
Error::Jid(err) => write!(f, "Jid Parse error: {}", err),
|
||||
Error::Xmpp(err) => write!(f, "XMPP error: {}", err),
|
||||
Error::Parser(err) => write!(f, "Parser error: {}", err),
|
||||
|
|
|
@ -91,7 +91,7 @@ async fn handle_iq_ping<C: ComponentTrait>(
|
|||
let success = Iq::empty_result(iq.from.as_ref().unwrap().clone(), iq.id.clone())
|
||||
.with_to(from.clone());
|
||||
|
||||
// Pinging a participant
|
||||
// Pinging a participant. The resource needs to be currently joined.
|
||||
if let Jid::Full(participant) = to.clone() {
|
||||
// TODO: Reply from participant if joined and nick is correct
|
||||
let bare = BareJid::from(to.clone());
|
||||
|
@ -112,17 +112,12 @@ async fn handle_iq_ping<C: ComponentTrait>(
|
|||
let domain = BareJid::from_str(&to.domain).unwrap();
|
||||
let success = success.clone().with_from(Jid::Bare(domain));
|
||||
component.send_stanza(success).await?;
|
||||
// Pinging a room
|
||||
// Pinging a room. User is required to have an affiliation other than none if
|
||||
// member-only.
|
||||
} else {
|
||||
if let Some(room) = rooms.get(&to) {
|
||||
if room.is_joined(&from) {
|
||||
let success = success.clone().with_from(Jid::Bare(to));
|
||||
component.send_stanza(success).await?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
let success = success.clone().with_from(Jid::Bare(to));
|
||||
component.send_stanza(success).await?;
|
||||
return Err(Error::UnhandledIq(String::from(
|
||||
"Pinging a room is not yet supported",
|
||||
)));
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
|
@ -158,23 +153,39 @@ async fn handle_iq<C: ComponentTrait>(
|
|||
) -> Result<(), Error> {
|
||||
match iq.payload {
|
||||
IqType::Get(ref payload) => {
|
||||
if payload.is("query", ns::DISCO_INFO) {
|
||||
handle_iq_disco(component, iq.clone(), payload.clone()).await?
|
||||
} else if payload.is("ping", ns::PING) {
|
||||
handle_iq_ping(component, iq.clone(), payload.clone(), rooms).await?
|
||||
} else {
|
||||
// We MUST answer unhandled get iqs with a service-unavailable error.
|
||||
let error = StanzaError::new(
|
||||
ErrorType::Cancel,
|
||||
DefinedCondition::ServiceUnavailable,
|
||||
"en",
|
||||
"No handler defined for this kind of iq.",
|
||||
);
|
||||
let iq: Element = Iq::from_error(iq.id, error)
|
||||
.with_from(iq.to.unwrap())
|
||||
.with_to(iq.from.unwrap())
|
||||
.into();
|
||||
component.send_stanza(iq).await?;
|
||||
let iq_result = {
|
||||
if payload.is("query", ns::DISCO_INFO) {
|
||||
handle_iq_disco(component, iq.clone(), payload.clone()).await
|
||||
} else if payload.is("ping", ns::PING) {
|
||||
handle_iq_ping(component, iq.clone(), payload.clone(), rooms).await
|
||||
} else {
|
||||
// We MUST answer unhandled get iqs with a service-unavailable error.
|
||||
handle_unhandled_iq(
|
||||
component,
|
||||
iq.id.clone(),
|
||||
iq.to.clone().unwrap(),
|
||||
iq.from.clone().unwrap(),
|
||||
"en",
|
||||
"No handler defined for this kind of iq.",
|
||||
)
|
||||
.await
|
||||
}
|
||||
};
|
||||
|
||||
match iq_result {
|
||||
Ok(()) => (),
|
||||
Err(Error::UnhandledIq(desc)) => {
|
||||
handle_unhandled_iq(
|
||||
component,
|
||||
iq.id,
|
||||
iq.to.unwrap(),
|
||||
iq.from.unwrap(),
|
||||
"en",
|
||||
desc.as_str(),
|
||||
)
|
||||
.await?
|
||||
}
|
||||
err => err?,
|
||||
}
|
||||
}
|
||||
_ => error!("Not handled iq: {:?}", iq),
|
||||
|
@ -183,6 +194,24 @@ async fn handle_iq<C: ComponentTrait>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_unhandled_iq<C: ComponentTrait>(
|
||||
component: &mut C,
|
||||
id: String,
|
||||
from: Jid,
|
||||
to: Jid,
|
||||
lang: &str,
|
||||
desc: &str,
|
||||
) -> Result<(), Error> {
|
||||
let error = StanzaError::new(
|
||||
ErrorType::Cancel,
|
||||
DefinedCondition::ServiceUnavailable,
|
||||
lang,
|
||||
desc,
|
||||
);
|
||||
let iq: Element = Iq::from_error(id, error).with_from(from).with_to(to).into();
|
||||
component.send_stanza(iq).await
|
||||
}
|
||||
|
||||
async fn handle_presence<C: ComponentTrait>(
|
||||
component: &mut C,
|
||||
presence: Presence,
|
||||
|
|
|
@ -150,3 +150,40 @@ async fn test_self_ping_participant_non_existing() {
|
|||
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_ping_room() {
|
||||
let realjid1 = Jid::Full(FullJid::from_str("foo@bar/qxx").unwrap());
|
||||
let roomjid = COMPONENT_JID.clone().with_node("room");
|
||||
|
||||
let ping: Element = Iq {
|
||||
from: Some(realjid1.clone()),
|
||||
to: Some(Jid::Bare(roomjid.clone())),
|
||||
id: String::from("ping"),
|
||||
payload: IqType::Get(Ping {}.into()),
|
||||
}
|
||||
.into();
|
||||
|
||||
let mut component = TestComponent::new(vec![ping]);
|
||||
let mut rooms: HashMap<BareJid, Room> = HashMap::new();
|
||||
|
||||
component.expect_iq(
|
||||
realjid1.clone(),
|
||||
move |iq| {
|
||||
let from = roomjid.clone();
|
||||
let to = realjid1.clone();
|
||||
assert_eq!(iq.from.unwrap(), Jid::Bare(from));
|
||||
assert_eq!(iq.to.unwrap(), to);
|
||||
match iq.payload {
|
||||
IqType::Error(err) => {
|
||||
assert_eq!(err.type_, ErrorType::Cancel);
|
||||
assert_eq!(err.defined_condition, DefinedCondition::ServiceUnavailable);
|
||||
}
|
||||
payload => panic!("Unexpected payload for iq ping reply: {:?}", payload),
|
||||
}
|
||||
},
|
||||
"ServiceUnavailable iq error",
|
||||
);
|
||||
|
||||
handle_stanza(&mut component, &mut rooms).await.unwrap();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue