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", |