diff options
| author | Remko Tronçon <git@el-tramo.be> | 2011-09-20 20:38:30 (GMT) | 
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2011-09-20 20:38:30 (GMT) | 
| commit | 703a1c28c3c87ac0fb365ff0683d7c64fcdd2210 (patch) | |
| tree | d8a6628f64403df172dafc6a85a8b03fab3e455e | |
| parent | 5c1ec7985808aba408bec724f5b90fed0dbcb7ce (diff) | |
| download | swift-contrib-703a1c28c3c87ac0fb365ff0683d7c64fcdd2210.zip swift-contrib-703a1c28c3c87ac0fb365ff0683d7c64fcdd2210.tar.bz2  | |
Added ClientBlockListManager.
| -rw-r--r-- | Swiften/Client/BlockList.cpp | 13 | ||||
| -rw-r--r-- | Swiften/Client/BlockList.h | 33 | ||||
| -rw-r--r-- | Swiften/Client/BlockListImpl.cpp | 56 | ||||
| -rw-r--r-- | Swiften/Client/BlockListImpl.h | 37 | ||||
| -rw-r--r-- | Swiften/Client/ClientBlockListManager.cpp | 104 | ||||
| -rw-r--r-- | Swiften/Client/ClientBlockListManager.h | 46 | ||||
| -rw-r--r-- | Swiften/Queries/IQRouter.h | 10 | ||||
| -rw-r--r-- | Swiften/Queries/Request.cpp | 7 | ||||
| -rw-r--r-- | Swiften/Queries/Request.h | 1 | ||||
| -rw-r--r-- | Swiften/Queries/Responder.h | 4 | ||||
| -rw-r--r-- | Swiften/SConscript | 3 | 
11 files changed, 308 insertions, 6 deletions
diff --git a/Swiften/Client/BlockList.cpp b/Swiften/Client/BlockList.cpp new file mode 100644 index 0000000..0b2fc12 --- /dev/null +++ b/Swiften/Client/BlockList.cpp @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Client/BlockList.h> + +using namespace Swift; + +BlockList::~BlockList() { + +} diff --git a/Swiften/Client/BlockList.h b/Swiften/Client/BlockList.h new file mode 100644 index 0000000..39a211d --- /dev/null +++ b/Swiften/Client/BlockList.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <set> + +#include <Swiften/JID/JID.h> +#include <Swiften/Base/boost_bsignals.h> + +namespace Swift { +	class BlockList { +		public: +			enum State { +				Requesting, +				Available, +				Error, +			}; +			virtual ~BlockList(); + +			virtual State getState() const = 0; + +			virtual const std::set<JID>& getItems() const = 0; + +		public: +			boost::signal<void ()> onStateChanged; +			boost::signal<void (const JID&)> onItemAdded; +			boost::signal<void (const JID&)> onItemRemoved; +	}; +} diff --git a/Swiften/Client/BlockListImpl.cpp b/Swiften/Client/BlockListImpl.cpp new file mode 100644 index 0000000..dfaaaf1 --- /dev/null +++ b/Swiften/Client/BlockListImpl.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Client/BlockListImpl.h> + +#include <Swiften/Base/foreach.h> + +using namespace Swift; + +BlockListImpl::BlockListImpl() { + +} + +void BlockListImpl::setItems(const std::vector<JID>& items) { +	this->items = std::set<JID>(items.begin(), items.end()); +} + +void BlockListImpl::addItem(const JID& item) { +	if (items.insert(item).second) { +		onItemAdded(item); +	} +} + +void BlockListImpl::removeItem(const JID& item) { +	if (items.erase(item)) { +		onItemRemoved(item); +	} +} + +void BlockListImpl::setState(State state) { +	if (this->state != state) { +		onStateChanged(); +	} +} + +void BlockListImpl::addItems(const std::vector<JID>& items) { +	foreach (const JID& item, items) { +		addItem(item); +	} +} + +void BlockListImpl::removeItems(const std::vector<JID>& items) { +	foreach (const JID& item, items) { +		removeItem(item); +	} +} + +void BlockListImpl::removeAllItems() { +	foreach (const JID& item, items) { +		removeItem(item); +	} +} + diff --git a/Swiften/Client/BlockListImpl.h b/Swiften/Client/BlockListImpl.h new file mode 100644 index 0000000..ef08340 --- /dev/null +++ b/Swiften/Client/BlockListImpl.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <Swiften/Client/BlockList.h> + +namespace Swift { +	class BlockListImpl : public BlockList { +		public: +			BlockListImpl(); + +			virtual State getState() const { +				return state; +			} + +			void setState(State state); + +			virtual const std::set<JID>& getItems() const { +				return items; +			} + +			void setItems(const std::vector<JID>& items); +			void addItem(const JID& item); +			void removeItem(const JID& item); +			void addItems(const std::vector<JID>& items); +			void removeItems(const std::vector<JID>& items); +			void removeAllItems(); + +		private: +			State state; +			std::set<JID> items; +	}; +} diff --git a/Swiften/Client/ClientBlockListManager.cpp b/Swiften/Client/ClientBlockListManager.cpp new file mode 100644 index 0000000..7222cea --- /dev/null +++ b/Swiften/Client/ClientBlockListManager.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <Swiften/Client/ClientBlockListManager.h> + +#include <boost/bind.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <cassert> + +#include <Swiften/Client/BlockListImpl.h> + +using namespace Swift; + +namespace { +	class BlockResponder : public SetResponder<BlockPayload> { +		public: +			BlockResponder(boost::shared_ptr<BlockListImpl> blockList, IQRouter* iqRouter) : SetResponder<BlockPayload>(iqRouter), blockList(blockList) { +			} + +			virtual bool handleSetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<BlockPayload> payload) { +				if (getIQRouter()->isAccountJID(from)) { +						if (payload) { +							blockList->addItems(payload->getItems()); +						} +						sendResponse(from, id, boost::shared_ptr<BlockPayload>()); +				} +				else { +					sendError(from, id, ErrorPayload::NotAuthorized, ErrorPayload::Cancel); +				} +				return true; +			} + +		private: +			boost::shared_ptr<BlockListImpl> blockList; +	}; + +	class UnblockResponder : public SetResponder<UnblockPayload> { +		public: +			UnblockResponder(boost::shared_ptr<BlockListImpl> blockList, IQRouter* iqRouter) : SetResponder<UnblockPayload>(iqRouter), blockList(blockList) { +			} + +			virtual bool handleSetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<UnblockPayload> payload) { +				if (getIQRouter()->isAccountJID(from)) { +					if (payload) { +						if (payload->getItems().empty()) { +							blockList->removeAllItems(); +						} +						else { +							blockList->removeItems(payload->getItems()); +						} +					} +					sendResponse(from, id, boost::shared_ptr<UnblockPayload>()); +				} +				else { +					sendError(from, id, ErrorPayload::NotAuthorized, ErrorPayload::Cancel); +				} +				return true; +			} + +		private: +			boost::shared_ptr<BlockListImpl> blockList; +	}; +} + +ClientBlockListManager::ClientBlockListManager(IQRouter* iqRouter) : iqRouter(iqRouter) { +} + +ClientBlockListManager::~ClientBlockListManager() { +	unblockResponder->stop(); +	blockResponder->stop(); +	if (getRequest) { +		getRequest->onResponse.disconnect(boost::bind(&ClientBlockListManager::handleBlockListReceived, this, _1, _2)); +	} +} + +boost::shared_ptr<BlockList> ClientBlockListManager::getBlockList() { +	if (!blockList) { +		blockList = boost::make_shared<BlockListImpl>(); +		blockList->setState(BlockList::Requesting); +		assert(!getRequest); +		getRequest = boost::make_shared< GenericRequest<BlockListPayload> >(IQ::Get, JID(), boost::make_shared<BlockListPayload>(), iqRouter); +		getRequest->onResponse.connect(boost::bind(&ClientBlockListManager::handleBlockListReceived, this, _1, _2)); +		getRequest->send(); +	} +	return blockList; +} + +void ClientBlockListManager::handleBlockListReceived(boost::shared_ptr<BlockListPayload> payload, ErrorPayload::ref error) { +	if (error || !payload) { +		blockList->setState(BlockList::Error); +	} +	else { +		blockList->setState(BlockList::Available); +		blockList->setItems(payload->getItems()); +		blockResponder = boost::make_shared<BlockResponder>(blockList, iqRouter); +		blockResponder->start(); +		unblockResponder = boost::make_shared<UnblockResponder>(blockList, iqRouter); +		unblockResponder->start(); +	} +} + diff --git a/Swiften/Client/ClientBlockListManager.h b/Swiften/Client/ClientBlockListManager.h new file mode 100644 index 0000000..21d35e3 --- /dev/null +++ b/Swiften/Client/ClientBlockListManager.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include <boost/shared_ptr.hpp> + +#include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Elements/BlockPayload.h> +#include <Swiften/Elements/BlockListPayload.h> +#include <Swiften/Elements/UnblockPayload.h> +#include <Swiften/Queries/SetResponder.h> +#include <Swiften/Queries/GenericRequest.h> +#include <Swiften/Client/BlockList.h> +#include <Swiften/Client/BlockListImpl.h> + +namespace Swift { +	class IQRouter; + +	class ClientBlockListManager { +		public: +			ClientBlockListManager(IQRouter *iqRouter); +			~ClientBlockListManager(); + +			bool isSupported() const; + +			/** +			 * Returns the blocklist. +			 */ +			boost::shared_ptr<BlockList> getBlockList(); + +		private: +			void handleBlockListReceived(boost::shared_ptr<BlockListPayload> payload, ErrorPayload::ref); + +		private: +			IQRouter* iqRouter; +			boost::shared_ptr<GenericRequest<BlockListPayload> > getRequest; +			boost::shared_ptr<SetResponder<BlockPayload> > blockResponder; +			boost::shared_ptr<SetResponder<UnblockPayload> > unblockResponder; +			boost::shared_ptr<BlockListImpl> blockList; +	}; +} + diff --git a/Swiften/Queries/IQRouter.h b/Swiften/Queries/IQRouter.h index 167cb8f..8dba334 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/Request.cpp b/Swiften/Queries/Request.cpp index 0126d62..382e44c 100644 --- a/Swiften/Queries/Request.cpp +++ b/Swiften/Queries/Request.cpp @@ -67,16 +67,13 @@ bool Request::handleIQ(boost::shared_ptr<IQ> iq) {  }  bool Request::isCorrectSender(const JID& jid) { -	if (isAccountJID(receiver_)) { -		return isAccountJID(jid); +	if (router_->isAccountJID(receiver_)) { +		return router_->isAccountJID(jid);  	}  	else {  		return jid.equals(receiver_, JID::WithResource);  	}  } -bool Request::isAccountJID(const JID& jid) { -	return jid.isValid() ? router_->getJID().toBare().equals(jid, JID::WithResource) : true; -}  } diff --git a/Swiften/Queries/Request.h b/Swiften/Queries/Request.h index a7139cf..677a758 100644 --- a/Swiften/Queries/Request.h +++ b/Swiften/Queries/Request.h @@ -60,7 +60,6 @@ namespace Swift {  		private:  			bool handleIQ(boost::shared_ptr<IQ>);  			bool isCorrectSender(const JID& jid); -			bool isAccountJID(const JID& jid);  		private:  			IQRouter* router_; diff --git a/Swiften/Queries/Responder.h b/Swiften/Queries/Responder.h index a9aab17..2ba9c24 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/SConscript b/Swiften/SConscript index f55485a..0144ddb 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -79,6 +79,9 @@ if env["SCONS_STAGE"] == "build" :  			"Client/Client.cpp",  			"Client/ClientXMLTracer.cpp",  			"Client/ClientSession.cpp", +			"Client/BlockList.cpp", +			"Client/BlockListImpl.cpp", +			"Client/ClientBlockListManager.cpp",  			"Client/MemoryStorages.cpp",  			"Client/NickResolver.cpp",  			"Client/NickManager.cpp",  | 
 Swift