From 6a4a15088e7c97b3f6c1de179eee1defa2720bdb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sat, 1 Oct 2011 13:09:13 +0200
Subject: Fixed roster sender check.

Resolves: #993

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
@@ -63,6 +63,16 @@ namespace Swift {
 			
 			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();
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
@@ -94,6 +94,10 @@ namespace Swift {
 				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) {
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
@@ -21,8 +21,13 @@ namespace Swift {
 
 		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
@@ -23,6 +23,7 @@ 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);
@@ -32,6 +33,7 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture {
 		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");
@@ -68,6 +70,18 @@ class XMPPRosterControllerTest : public CppUnit::TestFixture {
 			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());
-- 
cgit v0.10.2-6-g49f6