summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Burgess <pete.burgess@isode.com>2018-01-19 14:01:53 (GMT)
committerKevin Smith <kevin.smith@isode.com>2018-02-22 17:41:26 (GMT)
commit85a144fe80d0fe89b5fed852013b6986b44978d4 (patch)
treece5509ff53353b70cdce9332fa42bb464539e530 /Swift/Controllers/Chat
parent5eed7fcd3c8d42837a013855114deb6cdcaf47d0 (diff)
downloadswift-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/Chat')
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp55
-rw-r--r--Swift/Controllers/Chat/MUCController.h4
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp8
-rw-r--r--Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp170
4 files changed, 233 insertions, 4 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_;