diff options
-rw-r--r-- | Swiften/Queries/IQRouter.h | 10 | ||||
-rw-r--r-- | Swiften/Queries/Responder.h | 4 | ||||
-rw-r--r-- | Swiften/Roster/RosterPushResponder.h | 9 | ||||
-rw-r--r-- | Swiften/Roster/UnitTest/XMPPRosterControllerTest.cpp | 14 |
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(); |