xmpp: Rework the stanza handler
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import "package:test/test.dart";
|
||||
|
||||
import "package:moxxyv2/xmpp/stanza.dart";
|
||||
import "package:moxxyv2/xmpp/managers/handlers.dart";
|
||||
import "package:moxxyv2/xmpp/stringxml.dart";
|
||||
import "package:moxxyv2/xmpp/managers/handlers.dart";
|
||||
import "package:moxxyv2/xmpp/managers/data.dart";
|
||||
|
||||
final stanza1 = Stanza.iq(children: [
|
||||
XMLNode.xmlns(tag: "tag", xmlns: "owo")
|
||||
@@ -13,7 +14,7 @@ final stanza2 = Stanza.message(children: [
|
||||
|
||||
void main() {
|
||||
test("match all", () {
|
||||
final handler = StanzaHandler(callback: (_) async => true);
|
||||
final handler = StanzaHandler(callback: (stanza, _) async => StanzaHandlerData(true,stanza));
|
||||
|
||||
expect(handler.matches(Stanza.iq()), true);
|
||||
expect(handler.matches(Stanza.message()), true);
|
||||
@@ -22,7 +23,10 @@ void main() {
|
||||
expect(handler.matches(stanza2), true);
|
||||
});
|
||||
test("xmlns matching", () {
|
||||
final handler = StanzaHandler(callback: (_) async => true, tagXmlns: "owo");
|
||||
final handler = StanzaHandler(
|
||||
callback: (stanza, _) async => StanzaHandlerData(true, stanza),
|
||||
tagXmlns: "owo"
|
||||
);
|
||||
|
||||
expect(handler.matches(Stanza.iq()), false);
|
||||
expect(handler.matches(Stanza.message()), false);
|
||||
@@ -32,9 +36,9 @@ void main() {
|
||||
});
|
||||
test("stanzaTag matching", () {
|
||||
bool run = false;
|
||||
final handler = StanzaHandler(callback: (_) async {
|
||||
final handler = StanzaHandler(callback: (stanza, _) async {
|
||||
run = true;
|
||||
return true;
|
||||
return StanzaHandlerData(true, stanza);
|
||||
}, stanzaTag: "iq");
|
||||
|
||||
expect(handler.matches(Stanza.iq()), true);
|
||||
@@ -43,11 +47,14 @@ void main() {
|
||||
expect(handler.matches(stanza1), true);
|
||||
expect(handler.matches(stanza2), false);
|
||||
|
||||
handler.callback(stanza2);
|
||||
handler.callback(stanza2, StanzaHandlerData(false, stanza2));
|
||||
expect(run, true);
|
||||
});
|
||||
test("tagName matching", () {
|
||||
final handler = StanzaHandler(callback: (_) async => true, tagName: "tag");
|
||||
final handler = StanzaHandler(
|
||||
callback: (stanza, _) async => StanzaHandlerData(true, stanza),
|
||||
tagName: "tag"
|
||||
);
|
||||
|
||||
expect(handler.matches(Stanza.iq()), false);
|
||||
expect(handler.matches(Stanza.message()), false);
|
||||
@@ -56,7 +63,12 @@ void main() {
|
||||
expect(handler.matches(stanza2), false);
|
||||
});
|
||||
test("combined matching", () {
|
||||
final handler = StanzaHandler(callback: (_) async => true, tagName: "tag", stanzaTag: "iq", tagXmlns: "owo");
|
||||
final handler = StanzaHandler(
|
||||
callback: (stanza, _) async => StanzaHandlerData(true, stanza),
|
||||
tagName: "tag",
|
||||
stanzaTag: "iq",
|
||||
tagXmlns: "owo"
|
||||
);
|
||||
|
||||
expect(handler.matches(Stanza.iq()), false);
|
||||
expect(handler.matches(Stanza.message()), false);
|
||||
@@ -64,4 +76,18 @@ void main() {
|
||||
expect(handler.matches(stanza1), true);
|
||||
expect(handler.matches(stanza2), false);
|
||||
});
|
||||
|
||||
test("sorting", () {
|
||||
final handlerList = [
|
||||
StanzaHandler(callback: (stanza, _) async => StanzaHandlerData(true, stanza), tagName: "1", priority: 100),
|
||||
StanzaHandler(callback: (stanza, _) async => StanzaHandlerData(true, stanza), tagName: "2"),
|
||||
StanzaHandler(callback: (stanza, _) async => StanzaHandlerData(true, stanza), tagName: "3", priority: 50)
|
||||
];
|
||||
|
||||
handlerList.sort(stanzaHandlerSortComparator);
|
||||
|
||||
expect(handlerList[0].tagName, "1");
|
||||
expect(handlerList[1].tagName, "3");
|
||||
expect(handlerList[2].tagName, "2");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import "package:moxxyv2/xmpp/managers/attributes.dart";
|
||||
import "package:moxxyv2/xmpp/stringxml.dart";
|
||||
import "package:moxxyv2/xmpp/events.dart";
|
||||
import "package:moxxyv2/xmpp/stanza.dart";
|
||||
import "package:moxxyv2/xmpp/settings.dart";
|
||||
import "package:moxxyv2/xmpp/jid.dart";
|
||||
import "package:moxxyv2/xmpp/managers/attributes.dart";
|
||||
import "package:moxxyv2/xmpp/managers/data.dart";
|
||||
import "package:moxxyv2/xmpp/xeps/xep_0198/xep_0198.dart";
|
||||
import "package:moxxyv2/xmpp/xeps/xep_0198/state.dart";
|
||||
|
||||
@@ -11,6 +12,18 @@ import "../helpers/xml.dart";
|
||||
|
||||
import "package:test/test.dart";
|
||||
|
||||
Future<void> runIncomingStanzaHandlers(StreamManagementManager man, Stanza stanza) async {
|
||||
for (final handler in man.getIncomingStanzaHandlers()) {
|
||||
if (handler.matches(stanza)) await handler.callback(stanza, StanzaHandlerData(false, stanza));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> runOutgoingStanzaHandlers(StreamManagementManager man, Stanza stanza) async {
|
||||
for (final handler in man.getOutgoingStanzaHandlers()) {
|
||||
if (handler.matches(stanza)) await handler.callback(stanza, StanzaHandlerData(false, stanza));
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
final stanza = Stanza(
|
||||
to: "some.user@server.example",
|
||||
@@ -46,14 +59,14 @@ void main() {
|
||||
manager.onXmppEvent(StreamManagementEnabledEvent(id: "0", resource: "h"));
|
||||
|
||||
// Receive a fake stanza
|
||||
await manager.runStanzaHandlers(stanza);
|
||||
await manager.runStanzaHandlers(stanza);
|
||||
await runIncomingStanzaHandlers(manager, stanza);
|
||||
await runIncomingStanzaHandlers(manager, stanza);
|
||||
expect(manager.state.s2c, 2, reason: "The S2C counter must count correctly");
|
||||
|
||||
// Send some fake stanzas
|
||||
manager.onXmppEvent(StanzaSentEvent(stanza: stanza));
|
||||
manager.onXmppEvent(StanzaSentEvent(stanza: stanza));
|
||||
manager.onXmppEvent(StanzaSentEvent(stanza: stanza));
|
||||
runOutgoingStanzaHandlers(manager, stanza);
|
||||
runOutgoingStanzaHandlers(manager, stanza);
|
||||
runOutgoingStanzaHandlers(manager, stanza);
|
||||
expect(manager.state.c2s, 3, reason: "The C2S counter must count correctly");
|
||||
|
||||
final ack = XMLNode.xmlns(tag: "a", xmlns: "urn:xmpp:sm:3", attributes: { "h": "3" });
|
||||
@@ -63,7 +76,7 @@ void main() {
|
||||
expect(manager.state.s2c, 2, reason: "Sending stanzas must not change the S2C counter");
|
||||
|
||||
// Send a stanza which we will not acknowledge
|
||||
manager.onXmppEvent(StanzaSentEvent(stanza: stanza));
|
||||
runOutgoingStanzaHandlers(manager, stanza);
|
||||
expect(manager.state.c2s, 4, reason: "Sending a stanza must increment the C2S counter");
|
||||
await manager.runNonzaHandlers(ack);
|
||||
manager.onTimerElapsed(null, ignoreTimestamps: true);
|
||||
@@ -101,9 +114,9 @@ void main() {
|
||||
manager.register(attributes);
|
||||
|
||||
// Send some stanzas
|
||||
manager.onXmppEvent(StanzaSentEvent(stanza: stanza));
|
||||
manager.onXmppEvent(StanzaSentEvent(stanza: stanza));
|
||||
manager.onXmppEvent(StanzaSentEvent(stanza: stanza));
|
||||
runOutgoingStanzaHandlers(manager, stanza);
|
||||
runOutgoingStanzaHandlers(manager, stanza);
|
||||
runOutgoingStanzaHandlers(manager, stanza);
|
||||
|
||||
// Simulate a resumption
|
||||
manager.onXmppEvent(StreamResumedEvent(h: 2));
|
||||
|
||||
@@ -9,8 +9,9 @@ import "package:moxxyv2/xmpp/presence.dart";
|
||||
import "package:moxxyv2/xmpp/roster.dart";
|
||||
import "package:moxxyv2/xmpp/events.dart";
|
||||
import "package:moxxyv2/xmpp/managers/attributes.dart";
|
||||
import "package:moxxyv2/xmpp/managers/handlers.dart";
|
||||
import "package:moxxyv2/xmpp/managers/data.dart";
|
||||
import "package:moxxyv2/xmpp/xeps/xep_0030/xep_0030.dart";
|
||||
import "package:moxxyv2/xmpp/xeps/xep_0030/cachemanager.dart";
|
||||
|
||||
import "helpers/xmpp.dart";
|
||||
|
||||
@@ -40,14 +41,9 @@ Future<bool> testRosterManager(String bareJid, String resource, String stanzaStr
|
||||
));
|
||||
|
||||
final stanza = Stanza.fromXMLNode(XMLNode.fromString(stanzaString));
|
||||
await Future.forEach(
|
||||
roster.getStanzaHandlers(),
|
||||
(StanzaHandler handler) async {
|
||||
if (handler.matches(stanza)) {
|
||||
await handler.callback(stanza);
|
||||
}
|
||||
}
|
||||
);
|
||||
for (final handler in roster.getIncomingStanzaHandlers()) {
|
||||
if (handler.matches(stanza)) await handler.callback(stanza, StanzaHandlerData(false, stanza));
|
||||
}
|
||||
|
||||
return eventTriggered;
|
||||
}
|
||||
@@ -216,6 +212,7 @@ void main() {
|
||||
),
|
||||
]
|
||||
);
|
||||
// TODO: This test is broken since we query the server and enable carbons
|
||||
final XmppConnection conn = XmppConnection(socket: fakeSocket);
|
||||
conn.setConnectionSettings(ConnectionSettings(
|
||||
jid: JID.fromString("polynomdivision@test.server"),
|
||||
@@ -225,6 +222,7 @@ void main() {
|
||||
));
|
||||
conn.registerManager(RosterManager());
|
||||
conn.registerManager(DiscoManager());
|
||||
conn.registerManager(DiscoCacheManager());
|
||||
conn.registerManager(PresenceManager());
|
||||
|
||||
await conn.connect();
|
||||
@@ -509,14 +507,10 @@ void main() {
|
||||
// NOTE: Based on https://gultsch.de/gajim_roster_push_and_message_interception.html
|
||||
// NOTE: Added a from attribute as a server would add it itself.
|
||||
final maliciousStanza = Stanza.fromXMLNode(XMLNode.fromString("<iq type=\"set\" from=\"eve@siacs.eu/bbbbb\" to=\"some.user@example.server/aaaaa\"><query xmlns='jabber:iq:roster'><item subscription=\"both\" jid=\"eve@siacs.eu\" name=\"Bob\" /></query></iq>"));
|
||||
await Future.forEach(
|
||||
roster.getStanzaHandlers(),
|
||||
(StanzaHandler handler) async {
|
||||
if (handler.matches(maliciousStanza)) {
|
||||
await handler.callback(maliciousStanza);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
for (final handler in roster.getIncomingStanzaHandlers()) {
|
||||
if (handler.matches(maliciousStanza)) await handler.callback(maliciousStanza, StanzaHandlerData(false, maliciousStanza));
|
||||
}
|
||||
|
||||
expect(eventTriggered, false, reason: "Was able to inject a malicious roster push");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user