summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2011-09-20 20:38:30 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-09-20 20:38:30 (GMT)
commit703a1c28c3c87ac0fb365ff0683d7c64fcdd2210 (patch)
treed8a6628f64403df172dafc6a85a8b03fab3e455e
parent5c1ec7985808aba408bec724f5b90fed0dbcb7ce (diff)
downloadswift-contrib-703a1c28c3c87ac0fb365ff0683d7c64fcdd2210.zip
swift-contrib-703a1c28c3c87ac0fb365ff0683d7c64fcdd2210.tar.bz2
Added ClientBlockListManager.
-rw-r--r--Swiften/Client/BlockList.cpp13
-rw-r--r--Swiften/Client/BlockList.h33
-rw-r--r--Swiften/Client/BlockListImpl.cpp56
-rw-r--r--Swiften/Client/BlockListImpl.h37
-rw-r--r--Swiften/Client/ClientBlockListManager.cpp104
-rw-r--r--Swiften/Client/ClientBlockListManager.h46
-rw-r--r--Swiften/Queries/IQRouter.h10
-rw-r--r--Swiften/Queries/Request.cpp7
-rw-r--r--Swiften/Queries/Request.h1
-rw-r--r--Swiften/Queries/Responder.h4
-rw-r--r--Swiften/SConscript3
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",