From f3e46add7f512180833f91c3442ee9fb059b5f0c Mon Sep 17 00:00:00 2001 From: Roger Planas Date: Tue, 17 Jan 2017 14:42:38 +0000 Subject: Sluift: Add handling of block/unblock events Swiften handles blocklist event notifications, but those were not passed to Sluift, so a Sluift client, when querying events, would not be aware if an XMPP server pushes block/unblock. This patch adds an extra event type to Sluift so that method for_each_event reports block/unblock notifications, in addition to a new API 'get_block_list' to retrieve the blocklist from the server. Test-information: Used Sluift client to retrieve blocklist and it is as expected. Also used client to retrieve all items after adding, removing and removing all items in the blocklist, and Sluift clients can now see these events. Change-Id: I0b76289ebd9e63505ff8a99cd9c0aa0e93af0c22 diff --git a/Sluift/SluiftClient.cpp b/Sluift/SluiftClient.cpp index f1c0191..4680d4b 100644 --- a/Sluift/SluiftClient.cpp +++ b/Sluift/SluiftClient.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016 Isode Limited. + * Copyright (c) 2013-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -37,6 +38,8 @@ SluiftClient::SluiftClient( client->onPresenceReceived.connect(boost::bind(&SluiftClient::handleIncomingPresence, this, _1)); client->getPubSubManager()->onEvent.connect(boost::bind(&SluiftClient::handleIncomingPubSubEvent, this, _1, _2)); client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SluiftClient::handleInitialRosterPopulated, this)); + client->getClientBlockListManager()->getBlockList()->onItemAdded.connect(boost::bind(&SluiftClient::handleIncomingBlockEvent, this, _1)); + client->getClientBlockListManager()->getBlockList()->onItemRemoved.connect(boost::bind(&SluiftClient::handleIncomingUnblockEvent, this, _1)); } SluiftClient::~SluiftClient() { @@ -46,12 +49,14 @@ SluiftClient::~SluiftClient() { void SluiftClient::connect() { rosterReceived = false; + blockListReceived = false; disconnectedError = boost::optional(); client->connect(options); } void SluiftClient::connect(const std::string& host, int port) { rosterReceived = false; + blockListReceived = false; options.manualHostname = host; options.manualPort = port; disconnectedError = boost::optional(); @@ -126,6 +131,26 @@ boost::optional SluiftClient::getNextEvent( } } +std::vector SluiftClient::getBlockList(int timeout) { + Watchdog watchdog(timeout, networkFactories->getTimerFactory()); + if (!blockListReceived) { + // If we haven't requested it yet, request it for the first time + client->getClientBlockListManager()->requestBlockList(); + + // Wait for new events + while (!watchdog.getTimedOut() && client->getClientBlockListManager()->getBlockList()->getState() != BlockList::Available) { + eventLoop->runUntilEvents(); + } + + // Throw an error if we're timed out + if (watchdog.getTimedOut()) { + throw Lua::Exception("Timeout while requesting blocklist"); + } + } + blockListReceived = true; + return client->getClientBlockListManager()->getBlockList()->getItems(); +} + std::vector SluiftClient::getRoster(int timeout) { Watchdog watchdog(timeout, networkFactories->getTimerFactory()); if (!rosterReceived) { @@ -161,6 +186,14 @@ void SluiftClient::handleIncomingPubSubEvent(const JID& from, std::shared_ptr #include +#include #include #include #include @@ -42,13 +43,15 @@ namespace Swift { enum Type { MessageType, PresenceType, - PubSubEventType + PubSubEventType, + BlockEventType, + UnblockEventType }; Event(std::shared_ptr stanza) : type(MessageType), stanza(stanza) {} Event(std::shared_ptr stanza) : type(PresenceType), stanza(stanza) {} Event(const JID& from, std::shared_ptr payload) : type(PubSubEventType), from(from), pubsubEvent(payload) {} - + Event(const JID& item, Type type) : type(type), item(item) {} Type type; // Message & Presence @@ -57,6 +60,9 @@ namespace Swift { // PubSubEvent JID from; std::shared_ptr pubsubEvent; + + // Blocklist + JID item; }; SluiftClient( @@ -106,6 +112,7 @@ namespace Swift { boost::optional getNextEvent(int timeout, boost::function condition = 0); std::vector getRoster(int timeout); + std::vector getBlockList(int timeout); private: Sluift::Response doSendRequest(std::shared_ptr request, int timeout); @@ -113,6 +120,8 @@ namespace Swift { void handleIncomingMessage(std::shared_ptr stanza); void handleIncomingPresence(std::shared_ptr stanza); void handleIncomingPubSubEvent(const JID& from, std::shared_ptr event); + void handleIncomingBlockEvent(const JID& item); + void handleIncomingUnblockEvent(const JID& item); void handleInitialRosterPopulated(); void handleRequestResponse(std::shared_ptr response, std::shared_ptr error); void handleDisconnected(const boost::optional& error); @@ -124,6 +133,7 @@ namespace Swift { ClientOptions options; ClientXMLTracer* tracer; bool rosterReceived = false; + bool blockListReceived = false; std::deque pendingEvents; boost::optional disconnectedError; bool requestResponseReceived = false; diff --git a/Sluift/client.cpp b/Sluift/client.cpp index 186effc..53e253f 100644 --- a/Sluift/client.cpp +++ b/Sluift/client.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016 Isode Limited. + * Copyright (c) 2013-2017 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -206,6 +206,24 @@ SLUIFT_LUA_FUNCTION_WITH_HELP( } SLUIFT_LUA_FUNCTION_WITH_HELP( + Client, get_block_list, + "Returns a table of all the items in the blocking list.", + "self\n", + "" +) { + Sluift::globals.eventLoop.runOnce(); + SluiftClient* client = getClient(L); + lua_newtable(L); + int i = 0; + for (const auto& item : client->getBlockList(getGlobalTimeout(L))) { + lua_pushstring(L, item.toString().c_str()); + lua_rawseti(L, -2, boost::numeric_cast(++i)); + } + Lua::registerTableToString(L, -1); + return 1; +} + +SLUIFT_LUA_FUNCTION_WITH_HELP( Client, send_message, "Send a message.", "self\n" @@ -518,6 +536,23 @@ static void pushEvent(lua_State* L, const SluiftClient::Event& event) { lua_pushvalue(L, -3); lua_call(L, 1, 0); lua_pop(L, 1); + break; + } + case SluiftClient::Event::BlockEventType: { + Lua::Table result = boost::assign::map_list_of + ("type", std::make_shared(std::string("block"))) + ("jid", std::make_shared(event.item.toString())); + Lua::pushValue(L, result); + Lua::registerTableToString(L, -1); + break; + } + case SluiftClient::Event::UnblockEventType: { + Lua::Table result = boost::assign::map_list_of + ("type", std::make_shared(std::string("unblock"))) + ("jid", std::make_shared(event.item.toString())); + Lua::pushValue(L, result); + Lua::registerTableToString(L, -1); + break; } } } -- cgit v0.10.2-6-g49f6