From 7a9c3d136e8d5be70869950489036b665c462294 Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Wed, 21 Feb 2018 12:20:54 +0100
Subject: Fix handling of unusual JIDs in room bookmarks

Test-Information:

Added unit tests for bookmark handling for domain-only, bare,
and full JIDs.

Builds and unit tests pass on macOS 10.13.3.

Change-Id: I2855f4e9bdce4aa971575b2bad01e6dd166042bb

diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index a6f7fe0..19400f9 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2017 Isode Limited.
+ * Copyright (c) 2010-2018 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -331,11 +331,13 @@ void ChatsManager::handleBookmarksReady() {
 }
 
 void ChatsManager::handleMUCBookmarkAdded(const MUCBookmark& bookmark) {
-    std::map<JID, MUCController*>::iterator it = mucControllers_.find(bookmark.getRoom());
-    if (it == mucControllers_.end() && bookmark.getAutojoin()) {
-        handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false, false  );
+    if (bookmark.getRoom().isBare() && !bookmark.getRoom().getNode().empty()) {
+        std::map<JID, MUCController*>::iterator it = mucControllers_.find(bookmark.getRoom());
+        if (it == mucControllers_.end() && bookmark.getAutojoin()) {
+            handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false, false  );
+        }
+        chatListWindow_->addMUCBookmark(bookmark);
     }
-    chatListWindow_->addMUCBookmark(bookmark);
 }
 
 void ChatsManager::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) {
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index 1502dc9..08609ee 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2017 Isode Limited.
+ * Copyright (c) 2010-2018 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -32,9 +32,12 @@
 #include <Swiften/Elements/Forwarded.h>
 #include <Swiften/Elements/MUCInvitationPayload.h>
 #include <Swiften/Elements/MUCUserPayload.h>
+#include <Swiften/Elements/PrivateStorage.h>
+#include <Swiften/Elements/Storage.h>
 #include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
 #include <Swiften/Jingle/JingleSessionManager.h>
 #include <Swiften/MUC/MUCManager.h>
+#include <Swiften/MUC/UnitTest/MockMUC.h>
 #include <Swiften/Network/DummyTimerFactory.h>
 #include <Swiften/Presence/DirectedPresenceSender.h>
 #include <Swiften/Presence/PresenceOracle.h>
@@ -71,7 +74,6 @@
 #include <SwifTools/Notifier/Notifier.h>
 
 #include <Swift/QtUI/QtSwiftUtil.h>
-#include <Swiften/MUC/UnitTest/MockMUC.h>
 
 using namespace Swift;
 
@@ -155,6 +157,11 @@ class ChatsManagerTest : public CppUnit::TestFixture {
     CPPUNIT_TEST(testImpromptuChatWindowTitle);
     CPPUNIT_TEST(testStandardMUCChatWindowTitle);
 
+    // Bookmark tests
+    CPPUNIT_TEST(testReceivingBookmarksWithDomainJID);
+    CPPUNIT_TEST(testReceivingBookmarksWithBareJID);
+    CPPUNIT_TEST(testReceivingBookmarksWithFullJID);
+
     CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -1598,6 +1605,78 @@ public:
         CPPUNIT_ASSERT_EQUAL(std::string("mucroom"), window->name_);
     }
 
+    static std::shared_ptr<Storage> createBookmarkStorageWithJID(const JID& jid) {
+        auto storage = std::make_shared<Storage>();
+        auto room = Storage::Room();
+        room.jid = jid;
+        room.autoJoin = true;
+        storage->addRoom(room);
+        return storage;
+    }
+
+    void testReceivingBookmarksWithDomainJID() {
+        auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]);
+        CPPUNIT_ASSERT(bookmarkRequest);
+        CPPUNIT_ASSERT_EQUAL(IQ::Get, bookmarkRequest->getType());
+
+        auto privateStorage = bookmarkRequest->getPayload<PrivateStorage>();
+        CPPUNIT_ASSERT(privateStorage);
+
+        auto storage = std::dynamic_pointer_cast<Storage>(privateStorage->getPayload());
+        CPPUNIT_ASSERT(storage);
+
+        auto response = IQ::createResult(
+            bookmarkRequest->getFrom(),
+            bookmarkRequest->getTo(),
+            bookmarkRequest->getID(),
+            std::make_shared<PrivateStorage>(createBookmarkStorageWithJID("montague.lit"))
+        );
+        stanzaChannel_->onIQReceived(response);
+    }
+
+    void testReceivingBookmarksWithBareJID() {
+        auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]);
+        CPPUNIT_ASSERT(bookmarkRequest);
+        CPPUNIT_ASSERT_EQUAL(IQ::Get, bookmarkRequest->getType());
+
+        auto privateStorage = bookmarkRequest->getPayload<PrivateStorage>();
+        CPPUNIT_ASSERT(privateStorage);
+
+        auto storage = std::dynamic_pointer_cast<Storage>(privateStorage->getPayload());
+        CPPUNIT_ASSERT(storage);
+
+        MockChatWindow* window = new MockChatWindow();
+        mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID("example@montague.lit"), uiEventStream_).Return(window);
+
+        auto response = IQ::createResult(
+            bookmarkRequest->getFrom(),
+            bookmarkRequest->getTo(),
+            bookmarkRequest->getID(),
+            std::make_shared<PrivateStorage>(createBookmarkStorageWithJID("example@montague.lit"))
+        );
+        stanzaChannel_->onIQReceived(response);
+    }
+
+    void testReceivingBookmarksWithFullJID() {
+        auto bookmarkRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[0]);
+        CPPUNIT_ASSERT(bookmarkRequest);
+        CPPUNIT_ASSERT_EQUAL(IQ::Get, bookmarkRequest->getType());
+
+        auto privateStorage = bookmarkRequest->getPayload<PrivateStorage>();
+        CPPUNIT_ASSERT(privateStorage);
+
+        auto storage = std::dynamic_pointer_cast<Storage>(privateStorage->getPayload());
+        CPPUNIT_ASSERT(storage);
+
+        auto response = IQ::createResult(
+            bookmarkRequest->getFrom(),
+            bookmarkRequest->getTo(),
+            bookmarkRequest->getID(),
+            std::make_shared<PrivateStorage>(createBookmarkStorageWithJID("example@montague.lit/someresource"))
+        );
+        stanzaChannel_->onIQReceived(response);
+    }
+
 private:
     std::shared_ptr<Message> makeDeliveryReceiptTestMessage(const JID& from, const std::string& id) {
         std::shared_ptr<Message> message = std::make_shared<Message>();
@@ -1664,4 +1743,3 @@ private:
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(ChatsManagerTest);
-
-- 
cgit v0.10.2-6-g49f6