From 24ddcdb0a82cbd33deb5b72ad9f86f1c46fc9d13 Mon Sep 17 00:00:00 2001
From: Roger Planas <roger.planas@isode.com>
Date: Fri, 16 Nov 2018 11:04:27 +0000
Subject: Sluift: Added handling of roster push event

Swiften handles roster push event notifications, but those were
not passed to Sluift, so a Sluift client, when querying events,
would not be aware if an XMPP server roster pushes.

This patch adds extra events types to Sluift so that method
for_each_event reports roster pushes notifications.

Test-information:

Used sluift client to retrieve all items after adding, removing and
updating roster items, and now Sluift clients can see these events.

Change-Id: Ide5597bf2b39e3cc20014c66ba9153c551eec670

diff --git a/Sluift/SluiftClient.cpp b/Sluift/SluiftClient.cpp
index 5243ed0..99892a9 100644
--- a/Sluift/SluiftClient.cpp
+++ b/Sluift/SluiftClient.cpp
@@ -38,6 +38,9 @@ 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->getRoster()->onJIDAdded.connect(boost::bind(&SluiftClient::handleIncomingRosterAdd, this, _1));
+    client->getRoster()->onJIDRemoved.connect(boost::bind(&SluiftClient::handleIncomingRosterRemove, this, _1));
+    client->getRoster()->onJIDUpdated.connect(boost::bind(&SluiftClient::handleIncomingRosterUpdate, this, _1));
     client->getClientBlockListManager()->getBlockList()->onItemAdded.connect(boost::bind(&SluiftClient::handleIncomingBlockEvent, this, _1));
     client->getClientBlockListManager()->getBlockList()->onItemRemoved.connect(boost::bind(&SluiftClient::handleIncomingUnblockEvent, this, _1));
 }
@@ -192,6 +195,18 @@ void SluiftClient::handleInitialRosterPopulated() {
     rosterReceived = true;
 }
 
+void SluiftClient::handleIncomingRosterAdd(const JID& item) {
+    pendingEvents.push_back(Event(item, Event::RosterAddType));
+}
+
+void SluiftClient::handleIncomingRosterRemove(const JID& item) {
+    pendingEvents.push_back(Event(item, Event::RosterRemoveType));
+}
+
+void SluiftClient::handleIncomingRosterUpdate(const JID& item) {
+    pendingEvents.push_back(Event(item, Event::RosterUpdateType));
+}
+
 void SluiftClient::handleRequestResponse(std::shared_ptr<Payload> response, std::shared_ptr<ErrorPayload> error) {
     requestResponse = response;
     requestError = error;
diff --git a/Sluift/SluiftClient.h b/Sluift/SluiftClient.h
index 39ff0a8..ac4c582 100644
--- a/Sluift/SluiftClient.h
+++ b/Sluift/SluiftClient.h
@@ -45,7 +45,10 @@ namespace Swift {
                     PresenceType,
                     PubSubEventType,
                     BlockEventType,
-                    UnblockEventType
+                    UnblockEventType,
+                    RosterAddType,
+                    RosterRemoveType,
+                    RosterUpdateType
                 };
 
                 Event(std::shared_ptr<Message> stanza) : type(MessageType), stanza(stanza) {}
@@ -61,7 +64,7 @@ namespace Swift {
                 JID from;
                 std::shared_ptr<PubSubEventPayload> pubsubEvent;
 
-                // Blocklist
+                // Blocklist & Roster Push
                 JID item;
             };
 
@@ -122,6 +125,9 @@ namespace Swift {
             void handleIncomingBlockEvent(const JID& item);
             void handleIncomingUnblockEvent(const JID& item);
             void handleInitialRosterPopulated();
+            void handleIncomingRosterAdd(const JID& item);
+            void handleIncomingRosterRemove(const JID& item);
+            void handleIncomingRosterUpdate(const JID& item);
             void handleRequestResponse(std::shared_ptr<Payload> response, std::shared_ptr<ErrorPayload> error);
             void handleDisconnected(const boost::optional<ClientError>& error);
 
diff --git a/Sluift/client.cpp b/Sluift/client.cpp
index ec208bc..24ece85 100644
--- a/Sluift/client.cpp
+++ b/Sluift/client.cpp
@@ -599,6 +599,33 @@ static void pushEvent(lua_State* L, const SluiftClient::Event& event) {
             Lua::registerTableToString(L, -1);
             break;
         }
+        case SluiftClient::Event::RosterAddType: {
+            Lua::Table result = boost::assign::map_list_of
+                ("type", std::make_shared<Lua::Value>(std::string("rosterpush")))
+                ("jid",  std::make_shared<Lua::Value>(event.item.toString()))
+                ("action", std::make_shared<Lua::Value>(std::string("added")));
+            Lua::pushValue(L, result);
+            Lua::registerTableToString(L, -1);
+            break;
+        }
+        case SluiftClient::Event::RosterRemoveType: {
+            Lua::Table result = boost::assign::map_list_of
+                ("type", std::make_shared<Lua::Value>(std::string("rosterpush")))
+                ("jid",  std::make_shared<Lua::Value>(event.item.toString()))
+                ("action", std::make_shared<Lua::Value>(std::string("removed")));
+            Lua::pushValue(L, result);
+            Lua::registerTableToString(L, -1);
+            break;
+        }
+        case SluiftClient::Event::RosterUpdateType: {
+            Lua::Table result = boost::assign::map_list_of
+                ("type", std::make_shared<Lua::Value>(std::string("rosterpush")))
+                ("jid",  std::make_shared<Lua::Value>(event.item.toString()))
+                ("action", std::make_shared<Lua::Value>(std::string("updated")));
+            Lua::pushValue(L, result);
+            Lua::registerTableToString(L, -1);
+            break;
+        }
     }
 }
 
-- 
cgit v0.10.2-6-g49f6