summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swiften/Queries/IQRouter.h10
-rw-r--r--Swiften/Queries/Responder.h4
-rw-r--r--Swiften/Roster/RosterPushResponder.h9
-rw-r--r--Swiften/Roster/UnitTest/XMPPRosterControllerTest.cpp14
4 files changed, 35 insertions, 2 deletions
diff --git a/Swiften/Queries/IQRouter.h b/Swiften/Queries/IQRouter.h
index a21b24d..961ff59 100644
--- a/Swiften/Queries/IQRouter.h
+++ b/Swiften/Queries/IQRouter.h
@@ -57,18 +57,28 @@ namespace Swift {
* If a JID was specified using setFrom, the JID will
* be set as the 'from' address on iq before sending
* it.
*/
void sendIQ(boost::shared_ptr<IQ> iq);
std::string getNewIQID();
bool isAvailable();
+ /**
+ * Checks whether the given jid is the account JID (i.e. it is either
+ * the bare JID, or it is the empty JID).
+ * Can be used to check whether a stanza is sent by the server on behalf
+ * of the user's account.
+ */
+ bool isAccountJID(const JID& jid) {
+ return jid.isValid() ? jid_.toBare().equals(jid, JID::WithResource) : true;
+ }
+
private:
void handleIQ(boost::shared_ptr<IQ> iq);
void processPendingRemoves();
private:
IQChannel* channel_;
JID jid_;
JID from_;
std::vector< boost::shared_ptr<IQHandler> > handlers_;
diff --git a/Swiften/Queries/Responder.h b/Swiften/Queries/Responder.h
index 2ce8f10..28628e6 100644
--- a/Swiften/Queries/Responder.h
+++ b/Swiften/Queries/Responder.h
@@ -88,18 +88,22 @@ namespace Swift {
}
/**
* Convenience function for responding with an error from a specific from address.
*/
void sendError(const JID& to, const JID& from, const std::string& id, ErrorPayload::Condition condition, ErrorPayload::Type type) {
router_->sendIQ(IQ::createError(to, from, id, condition, type));
}
+ IQRouter* getIQRouter() const {
+ return router_;
+ }
+
private:
virtual bool handleIQ(boost::shared_ptr<IQ> iq) {
if (iq->getType() == IQ::Set || iq->getType() == IQ::Get) {
boost::shared_ptr<PAYLOAD_TYPE> payload(iq->getPayload<PAYLOAD_TYPE>());
if (payload) {
bool result;
if (iq->getType() == IQ::Set) {
result = handleSetRequest(iq->getFrom(), iq->getTo(), iq->getID(), payload);
}
diff --git a/Swiften/Roster/RosterPushResponder.h b/Swiften/Roster/RosterPushResponder.h
index b38914b..4e0bc4e 100644
--- a/Swiften/Roster/RosterPushResponder.h
+++ b/Swiften/Roster/RosterPushResponder.h
@@ -15,15 +15,20 @@ namespace Swift {
class RosterPushResponder : public SetResponder<RosterPayload> {
public:
RosterPushResponder(IQRouter* router) : SetResponder<RosterPayload>(router) {}
public:
boost::signal<void (boost::shared_ptr<RosterPayload>)> onRosterReceived;
private:
virtual bool handleSetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<RosterPayload> payload) {
- onRosterReceived(payload);
- sendResponse(from, id, boost::shared_ptr<RosterPayload>());
+ if (getIQRouter()->isAccountJID(from)) {
+ onRosterReceived(payload);
+ sendResponse(from, id, boost::shared_ptr<RosterPayload>());
+ }
+ else {
+ sendError(from, id, ErrorPayload::NotAuthorized, ErrorPayload::Cancel);
+ }
return true;
}
};
}
diff --git a/Swiften/Roster/UnitTest/XMPPRosterControllerTest.cpp b/Swiften/Roster/UnitTest/XMPPRosterControllerTest.cpp
index 4ef1cc1..997840f 100644
--- a/Swiften/Roster/UnitTest/XMPPRosterControllerTest.cpp
+++ b/Swiften/Roster/UnitTest/XMPPRosterControllerTest.cpp
@@ -17,27 +17,29 @@
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Roster/XMPPRosterImpl.h"
using namespace Swift;
class XMPPRosterControllerTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(XMPPRosterControllerTest);
CPPUNIT_TEST(testGet_EmptyResponse);
CPPUNIT_TEST(testAdd);
+ CPPUNIT_TEST(testAddFromNonAccount);
CPPUNIT_TEST(testModify);
CPPUNIT_TEST(testRemove);
CPPUNIT_TEST(testMany);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {
channel_ = new DummyStanzaChannel();
router_ = new IQRouter(channel_);
+ router_->setJID("me@bla.com");
xmppRoster_ = new XMPPRosterImpl();
handler_ = new XMPPRosterSignalHandler(xmppRoster_);
jid1_ = JID("foo@bar.com");
jid2_ = JID("alice@wonderland.lit");
jid3_ = JID("jane@austen.lit");
}
void tearDown() {
delete handler_;
@@ -62,18 +64,30 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture {
channel_->onIQReceived(IQ::createRequest(IQ::Set, JID(), "eou", payload));
CPPUNIT_ASSERT_EQUAL(Add, handler_->getLastEvent());
CPPUNIT_ASSERT_EQUAL(jid1_, handler_->getLastJID());
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), xmppRoster_->getGroupsForJID(jid1_).size());
CPPUNIT_ASSERT(xmppRoster_->containsJID(jid1_));
CPPUNIT_ASSERT_EQUAL(std::string("Bob"), xmppRoster_->getNameForJID(jid1_));
}
+ void testAddFromNonAccount() {
+ XMPPRosterController controller(router_, xmppRoster_);
+
+ boost::shared_ptr<RosterPayload> payload(new RosterPayload());
+ payload->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Both));
+ IQ::ref request = IQ::createRequest(IQ::Set, JID(), "eou", payload);
+ request->setFrom(jid2_);
+ channel_->onIQReceived(request);
+
+ CPPUNIT_ASSERT_EQUAL(None, handler_->getLastEvent());
+ }
+
void testModify() {
XMPPRosterController controller(router_, xmppRoster_);
boost::shared_ptr<RosterPayload> payload1(new RosterPayload());
payload1->addItem(RosterItemPayload(jid1_, "Bob", RosterItemPayload::Both));
channel_->onIQReceived(IQ::createRequest(IQ::Set, JID(), "id1", payload1));
CPPUNIT_ASSERT_EQUAL(Add, handler_->getLastEvent());
CPPUNIT_ASSERT_EQUAL(jid1_, handler_->getLastJID());
handler_->reset();