diff options
| author | Peter Burgess <pete.burgess@isode.com> | 2018-01-19 14:01:53 (GMT) | 
|---|---|---|
| committer | Kevin Smith <kevin.smith@isode.com> | 2018-02-22 17:41:26 (GMT) | 
| commit | 85a144fe80d0fe89b5fed852013b6986b44978d4 (patch) | |
| tree | ce5509ff53353b70cdce9332fa42bb464539e530 /Swift/Controllers | |
| parent | 5eed7fcd3c8d42837a013855114deb6cdcaf47d0 (diff) | |
| download | swift-85a144fe80d0fe89b5fed852013b6986b44978d4.zip swift-85a144fe80d0fe89b5fed852013b6986b44978d4.tar.bz2 | |
Request and display security markings for MUC chat windows
Disco#info requested and handled by MUCController on rejoin().
UI display of disco#info implemented for QtChatWindow.
Test-Information:
Tests written for new MUCController features, and all tests passed.
Swift runs with changes and security markings show as and when
expected in local isode MUC windows.
Change-Id: Ibef4a31f6f8c4cff5f518a66106266a7f961d103
Diffstat (limited to 'Swift/Controllers')
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.cpp | 55 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/MUCController.h | 4 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp | 8 | ||||
| -rw-r--r-- | Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp | 170 | ||||
| -rw-r--r-- | Swift/Controllers/UIInterfaces/ChatWindow.h | 8 | ||||
| -rw-r--r-- | Swift/Controllers/UnitTest/MockChatWindow.h | 11 | 
6 files changed, 250 insertions, 6 deletions
| diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index ff8efa2..9e12a66 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.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.   */ @@ -23,6 +23,7 @@  #include <Swiften/Client/ClientBlockListManager.h>  #include <Swiften/Client/StanzaChannel.h>  #include <Swiften/Disco/EntityCapsProvider.h> +#include <Swiften/Disco/GetDiscoInfoRequest.h>  #include <Swiften/Elements/Delay.h>  #include <Swiften/Elements/Thread.h>  #include <Swiften/MUC/MUC.h> @@ -273,6 +274,9 @@ void MUCController::rejoin() {              lastActivity_ = historyController_->getLastTimeStampFromMUC(selfJID_, toJID_);          }  #endif + +        requestSecurityMarking(); +          if (lastActivity_ == boost::posix_time::not_a_date_time) {              muc_->joinAs(nick_);          } @@ -1243,4 +1247,53 @@ void MUCController::setChatWindowTitle(const std::string& title) {      chatWindow_->setName(chatWindowTitle_);  } +void MUCController::requestSecurityMarking() { +    auto discoInfoRequest = GetDiscoInfoRequest::create(muc_->getJID(), iqRouter_); +    discoInfoRequest->onResponse.connect( +        [this](std::shared_ptr<DiscoInfo> discoInfoRef, ErrorPayload::ref errorPayloadRef) { +            if (!discoInfoRef || errorPayloadRef) { +                return; +            } +            const std::vector<Form::ref>& extensionsList = discoInfoRef->getExtensions(); +            if (extensionsList.empty()) { +                return; +            } +            // Get the correct form if it exists +            Form::ref roomInfoForm; +            for (const auto& form : extensionsList) { +                if (form->getFormType() == "http://jabber.org/protocol/muc#roominfo") { +                    roomInfoForm = form; +                    break; +                } +            } +            if (!roomInfoForm) { +                return; +            } +            // It exists, now examine the security marking data +            auto marking = roomInfoForm->getField("x-isode#roominfo_marking"); +            if (!marking) { +                return; +            } +            // Now we know the marking is valid +            auto markingValue = marking->getTextSingleValue(); +            if (markingValue == "") { +                chatWindow_->removeChatSecurityMarking(); +                return; +            } +            auto markingForegroundColor = roomInfoForm->getField("x-isode#roominfo_marking_fg_color"); +            auto markingBackgroundColor = roomInfoForm->getField("x-isode#roominfo_marking_bg_color"); +            std::string markingForegroundColorValue = "Black"; +            std::string markingBackgroundColorValue = "White"; +            if (markingForegroundColor) { +                markingForegroundColorValue = markingForegroundColor->getTextSingleValue(); +            } +            if (markingBackgroundColor) { +                markingBackgroundColorValue = markingBackgroundColor->getTextSingleValue(); +            } +            chatWindow_->setChatSecurityMarking(markingValue, markingForegroundColorValue, markingBackgroundColorValue); +        } +    ); +    discoInfoRequest->send(); +} +  } diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index 4b39f54..949f530 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -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.   */ @@ -148,6 +148,8 @@ namespace Swift {              void displaySubjectIfChanged(const std::string& sucject);              void addChatSystemMessage(); +            void requestSecurityMarking(); +          private:              MUC::ref muc_;              std::string nick_; diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp index 8f6c3a8..e06a3c7 100644 --- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp @@ -776,7 +776,7 @@ public:          // send message to participantA          auto messageBody = std::string("message body to send");          window->onSendMessageRequest(messageBody, false); -        auto sendMessageStanza = stanzaChannel_->getStanzaAtIndex<Message>(2); +        auto sendMessageStanza = stanzaChannel_->getStanzaAtIndex<Message>(3);          CPPUNIT_ASSERT_EQUAL(messageBody, *sendMessageStanza->getBody());          // receive reply with error @@ -1537,7 +1537,11 @@ public:          uiEventStream_->send(std::make_shared<CreateImpromptuMUCUIEvent>(jids, mucJID, ""));          CPPUNIT_ASSERT_EQUAL(std::string("bar@test.com, foo@test.com"), manager_->getRecentChats()[0].getTitle()); -        auto mucJoinPresence = std::dynamic_pointer_cast<Presence>(stanzaChannel_->sentStanzas[2]); +        // Check the MUC security marking request +        auto mucInfoRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[2]); +        CPPUNIT_ASSERT(mucInfoRequest); + +        auto mucJoinPresence = std::dynamic_pointer_cast<Presence>(stanzaChannel_->sentStanzas[3]);          CPPUNIT_ASSERT(mucJoinPresence);          // MUC presence reply diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp index 1f69f4f..06486d3 100644 --- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp @@ -68,6 +68,14 @@ class MUCControllerTest : public CppUnit::TestFixture {      CPPUNIT_TEST(testNonImpromptuMUCWindowTitle); +    CPPUNIT_TEST(testSecurityMarkingRequestCompleteMarking); +    CPPUNIT_TEST(testSecurityMarkingRequestCompleteMarkingWithExtraForm); +    CPPUNIT_TEST(testSecurityMarkingRequestEmptyMarking); +    CPPUNIT_TEST(testSecurityMarkingRequestWithMarkingNoFormType); +    CPPUNIT_TEST(testSecurityMarkingRequestNoMarking); +    CPPUNIT_TEST(testSecurityMarkingRequestNoForm); +    CPPUNIT_TEST(testSecurityMarkingRequestError); +      CPPUNIT_TEST_SUITE_END();  public: @@ -593,6 +601,168 @@ public:          CPPUNIT_ASSERT_EQUAL(muc_->getJID().getNode(), window_->name_);      } +    void testSecurityMarkingRequestCompleteMarking() { +        auto formTypeField = std::make_shared<FormField>(FormField::Type::HiddenType, "http://jabber.org/protocol/muc#roominfo"); +        auto markingField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Test | Highest Possible Security"); +        auto markingForegroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Black"); +        auto markingBackgroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Red"); +        formTypeField->setName("FORM_TYPE"); +        markingField->setName("x-isode#roominfo_marking"); +        markingForegroundColorField->setName("x-isode#roominfo_marking_fg_color"); +        markingBackgroundColorField->setName("x-isode#roominfo_marking_bg_color"); + +        auto form = std::make_shared<Form>(Form::Type::ResultType); +        form->addField(formTypeField); +        form->addField(markingField); +        form->addField(markingForegroundColorField); +        form->addField(markingBackgroundColorField); + +        auto discoInfoRef = std::make_shared<DiscoInfo>(); +        discoInfoRef->addExtension(form); + +        auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); +        iqChannel_->onIQReceived(infoResponse); +        CPPUNIT_ASSERT_EQUAL(std::string("Test | Highest Possible Security"), window_->markingValue_); +        CPPUNIT_ASSERT_EQUAL(std::string("Black"), window_->markingForegroundColorValue_); +        CPPUNIT_ASSERT_EQUAL(std::string("Red"), window_->markingBackgroundColorValue_); +    } + +    void testSecurityMarkingRequestCompleteMarkingWithExtraForm() { +        auto formTypeField = std::make_shared<FormField>(FormField::Type::HiddenType, "http://jabber.org/protocol/muc#roominfo"); +        auto markingField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Test | Highest Possible Security"); +        auto markingForegroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Black"); +        auto markingBackgroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Red"); +        formTypeField->setName("FORM_TYPE"); +        markingField->setName("x-isode#roominfo_marking"); +        markingForegroundColorField->setName("x-isode#roominfo_marking_fg_color"); +        markingBackgroundColorField->setName("x-isode#roominfo_marking_bg_color"); + +        auto extraForm = std::make_shared<Form>(Form::Type::ResultType); +        auto form = std::make_shared<Form>(Form::Type::ResultType); +        form->addField(formTypeField); +        form->addField(markingField); +        form->addField(markingForegroundColorField); +        form->addField(markingBackgroundColorField); + +        auto discoInfoRef = std::make_shared<DiscoInfo>(); +        discoInfoRef->addExtension(extraForm); +        discoInfoRef->addExtension(form); + +        auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); +        iqChannel_->onIQReceived(infoResponse); +        CPPUNIT_ASSERT_EQUAL(std::string("Test | Highest Possible Security"), window_->markingValue_); +        CPPUNIT_ASSERT_EQUAL(std::string("Black"), window_->markingForegroundColorValue_); +        CPPUNIT_ASSERT_EQUAL(std::string("Red"), window_->markingBackgroundColorValue_); +    } + +    void testSecurityMarkingRequestNoColorsInMarking() { +        auto formTypeField = std::make_shared<FormField>(FormField::Type::HiddenType, "http://jabber.org/protocol/muc#roominfo"); +        auto markingField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Test | Highest Possible Security"); +        auto markingForegroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, ""); +        auto markingBackgroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, ""); +        formTypeField->setName("FORM_TYPE"); +        markingField->setName("x-isode#roominfo_marking"); +        markingForegroundColorField->setName("x-isode#roominfo_marking_fg_color"); +        markingBackgroundColorField->setName("x-isode#roominfo_marking_bg_color"); + +        auto form = std::make_shared<Form>(Form::Type::ResultType); +        form->addField(formTypeField); +        form->addField(markingField); +        form->addField(markingForegroundColorField); +        form->addField(markingBackgroundColorField); + +        auto discoInfoRef = std::make_shared<DiscoInfo>(); +        discoInfoRef->addExtension(form); + +        auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); +        iqChannel_->onIQReceived(infoResponse); +        CPPUNIT_ASSERT_EQUAL(std::string("Test | Highest Possible Security"), window_->markingValue_); +        CPPUNIT_ASSERT_EQUAL(std::string("Black"), window_->markingForegroundColorValue_); +        CPPUNIT_ASSERT_EQUAL(std::string("White"), window_->markingBackgroundColorValue_); +    } + +    void testSecurityMarkingRequestEmptyMarking() { +        auto formTypeField = std::make_shared<FormField>(FormField::Type::HiddenType, "http://jabber.org/protocol/muc#roominfo"); +        auto markingField = std::make_shared<FormField>(FormField::Type::TextSingleType, ""); +        auto markingForegroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, ""); +        auto markingBackgroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, ""); +        formTypeField->setName("FORM_TYPE"); +        markingField->setName("x-isode#roominfo_marking"); +        markingForegroundColorField->setName("x-isode#roominfo_marking_fg_color"); +        markingBackgroundColorField->setName("x-isode#roominfo_marking_bg_color"); + +        auto form = std::make_shared<Form>(Form::Type::ResultType); +        form->addField(formTypeField); +        form->addField(markingField); +        form->addField(markingForegroundColorField); +        form->addField(markingBackgroundColorField); + +        auto discoInfoRef = std::make_shared<DiscoInfo>(); +        discoInfoRef->addExtension(form); + +        auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); +        iqChannel_->onIQReceived(infoResponse); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingValue_); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingForegroundColorValue_); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingBackgroundColorValue_); +    } + +    void testSecurityMarkingRequestWithMarkingNoFormType() { +        auto markingField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Test | Highest Possible Security"); +        auto markingForegroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Black"); +        auto markingBackgroundColorField = std::make_shared<FormField>(FormField::Type::TextSingleType, "Red"); +        markingField->setName("x-isode#roominfo_marking"); +        markingForegroundColorField->setName("x-isode#roominfo_marking_fg_color"); +        markingBackgroundColorField->setName("x-isode#roominfo_marking_bg_color"); + +        auto form = std::make_shared<Form>(Form::Type::ResultType); +        form->addField(markingField); +        form->addField(markingForegroundColorField); +        form->addField(markingBackgroundColorField); + +        auto discoInfoRef = std::make_shared<DiscoInfo>(); +        discoInfoRef->addExtension(form); + +        auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); +        iqChannel_->onIQReceived(infoResponse); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingValue_); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingForegroundColorValue_); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingBackgroundColorValue_); +    } + +    void testSecurityMarkingRequestNoMarking() { +        auto form = std::make_shared<Form>(Form::Type::ResultType); + +        auto discoInfoRef = std::make_shared<DiscoInfo>(); +        discoInfoRef->addExtension(form); + +        auto infoResponse = IQ::createResult(self_, mucJID_, "test-id", discoInfoRef); +        iqChannel_->onIQReceived(infoResponse); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingValue_); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingForegroundColorValue_); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingBackgroundColorValue_); +    } + +    void testSecurityMarkingRequestNoForm() { +        auto discoInfoRef = std::make_shared<DiscoInfo>(); + +        auto infoResponse = IQ::createResult( self_, mucJID_, "test-id", discoInfoRef); +        iqChannel_->onIQReceived(infoResponse); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingValue_); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingForegroundColorValue_); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingBackgroundColorValue_); +    } + +    void testSecurityMarkingRequestError() { +        auto errorPayload = std::make_shared<ErrorPayload>(ErrorPayload::Condition::NotAuthorized, ErrorPayload::Type::Auth); + +        auto infoResponse = IQ::createResult( self_, mucJID_, "test-id", errorPayload); +        iqChannel_->onIQReceived(infoResponse); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingValue_); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingForegroundColorValue_); +        CPPUNIT_ASSERT_EQUAL(std::string(""), window_->markingBackgroundColorValue_); +    } +  private:      JID self_;      JID mucJID_; diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index 8273802..13cbb7d 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -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.   */ @@ -33,6 +33,8 @@ namespace Swift {      class ContactRosterItem;      class FileTransferController;      class UserSearchWindow; +    class DiscoInfo; +    class ErrorPayload;      class ChatWindow { @@ -219,6 +221,9 @@ namespace Swift {              virtual void showBookmarkWindow(const MUCBookmark& bookmark) = 0;              virtual void setBookmarkState(RoomBookmarkState bookmarkState) = 0; +            virtual void setChatSecurityMarking(const std::string& markingValue, const std::string& markingForegroundColorValue, const std::string& markingBackgroundColorValue) = 0; +            virtual void removeChatSecurityMarking() = 0; +              /**               * A handle that uniquely identities an alert message.               */ @@ -282,4 +287,3 @@ namespace Swift {              boost::signals2::signal<void ()> onUnblockUserRequest;      };  } - diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index 7682781..56f118d 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -133,6 +133,14 @@ namespace Swift {                  lastAddedMessageSenderIsSelf_ = lastAddedActionSenderIsSelf_ = false;              } +            void setChatSecurityMarking(const std::string& markingValue, const std::string& markingForegroundColorValue, const std::string& markingBackgroundColorValue) { +                markingValue_ = markingValue; +                markingForegroundColorValue_ = markingForegroundColorValue; +                markingBackgroundColorValue_ = markingBackgroundColorValue; +            } + +            void removeChatSecurityMarking() {} +              std::string name_;              ChatMessage lastAddedMessage_;              std::string lastAddedMessageSenderName_; @@ -154,6 +162,9 @@ namespace Swift {              Roster* roster_ = nullptr;              std::vector<std::pair<std::string, ReceiptState>> receiptChanges_;              boost::optional<MUCType> mucType_; +            std::string markingValue_; +            std::string markingForegroundColorValue_; +            std::string markingBackgroundColorValue_;      };  } | 
 Swift
 Swift