diff options
18 files changed, 158 insertions, 72 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp index 6e7825f..722d68c 100644 --- a/Swift/Controllers/Chat/ChatController.cpp +++ b/Swift/Controllers/Chat/ChatController.cpp @@ -112,7 +112,7 @@ void ChatController::preSendMessageRequest(boost::shared_ptr<Message> message) { } void ChatController::postSendMessage(const std::string& body, boost::shared_ptr<Stanza> sentStanza) { - std::string id = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel() : boost::optional<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time()); + std::string id = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time()); if (stanzaChannel_->getStreamManagementEnabled()) { chatWindow_->setAckState(id, ChatWindow::Pending); unackedStanzas_[sentStanza] = id; diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index a970d88..b819835 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -67,7 +67,7 @@ void ChatControllerBase::setOnline(bool online) { } void ChatControllerBase::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) { - if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::SecurityLabels)) { + if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::SecurityLabelsCatalogueFeature)) { //chatWindow_->setSecurityLabelsEnabled(true); //chatWindow_->setSecurityLabelsError(); GetSecurityLabelsCatalogRequest::ref request = GetSecurityLabelsCatalogRequest::create(JID(toJID_.toBare()), iqRouter_); @@ -96,10 +96,8 @@ void ChatControllerBase::handleSendMessageRequest(const std::string &body) { message->setTo(toJID_); message->setType(Swift::Message::Chat); message->setBody(body); - boost::optional<SecurityLabel> label; if (labelsEnabled_) { - message->addPayload(boost::shared_ptr<SecurityLabel>(new SecurityLabel(chatWindow_->getSelectedSecurityLabel()))); - label = boost::optional<SecurityLabel>(chatWindow_->getSelectedSecurityLabel()); + message->addPayload(chatWindow_->getSelectedSecurityLabel().getLabel()); } preSendMessageRequest(message); if (useDelayForLatency_) { @@ -112,12 +110,12 @@ void ChatControllerBase::handleSendMessageRequest(const std::string &body) { void ChatControllerBase::handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog> catalog, ErrorPayload::ref error) { if (!error) { - if (catalog->getLabels().size() == 0) { + if (catalog->getItems().size() == 0) { chatWindow_->setSecurityLabelsEnabled(false); labelsEnabled_ = false; } else { labelsEnabled_ = true; - chatWindow_->setAvailableSecurityLabels(catalog->getLabels()); + chatWindow_->setAvailableSecurityLabels(catalog->getItems()); chatWindow_->setSecurityLabelsEnabled(true); } } else { @@ -134,7 +132,7 @@ void ChatControllerBase::activateChatWindow() { chatWindow_->activate(); } -std::string ChatControllerBase::addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const std::string& avatarPath, const boost::posix_time::ptime& time) { +std::string ChatControllerBase::addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) { if (boost::starts_with(message, "/me ")) { return chatWindow_->addAction(String::getSplittedAtFirst(message, ' ').second, senderName, senderIsSelf, label, avatarPath, time); } else { @@ -174,7 +172,6 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m chatWindow_->addSystemMessage(std::string(s.str())); } boost::shared_ptr<SecurityLabel> label = message->getPayload<SecurityLabel>(); - boost::optional<SecurityLabel> maybeLabel = label ? boost::optional<SecurityLabel>(*label) : boost::optional<SecurityLabel>(); // Determine the timestamp boost::posix_time::ptime timeStamp = boost::posix_time::microsec_clock::universal_time(); @@ -183,7 +180,7 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m timeStamp = *messageTimeStamp; } - addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), maybeLabel, std::string(avatarManager_->getAvatarPath(from).string()), timeStamp); + addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), label, std::string(avatarManager_->getAvatarPath(from).string()), timeStamp); } chatWindow_->show(); chatWindow_->setUnreadMessageCount(unreadMessages_.size()); diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h index 4a1f8e0..6a92429 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.h +++ b/Swift/Controllers/Chat/ChatControllerBase.h @@ -43,7 +43,7 @@ namespace Swift { void activateChatWindow(); void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info); void handleIncomingMessage(boost::shared_ptr<MessageEvent> message); - std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const std::string& avatarPath, const boost::posix_time::ptime& time); + std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time); virtual void setOnline(bool online); virtual void setEnabled(bool enabled); virtual void setToJID(const JID& jid) {toJID_ = jid;}; diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index b90ae46..c7bcf1e 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -14,7 +14,7 @@ #include <vector> #include <string> -#include "Swiften/Elements/SecurityLabel.h" +#include "Swiften/Elements/SecurityLabelsCatalog.h" #include "Swiften/Elements/ChatState.h" namespace Swift { @@ -32,11 +32,11 @@ namespace Swift { /** Add message to window. * @return id of added message (for acks). */ - virtual std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0; + virtual std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0; /** Adds action to window. * @return id of added message (for acks); */ - virtual std::string addAction(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0; + virtual std::string addAction(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0; virtual void addSystemMessage(const std::string& message) = 0; virtual void addPresenceMessage(const std::string& message) = 0; virtual void addErrorMessage(const std::string& message) = 0; @@ -45,13 +45,13 @@ namespace Swift { virtual void setName(const std::string& name) = 0; virtual void show() = 0; virtual void activate() = 0; - virtual void setAvailableSecurityLabels(const std::vector<SecurityLabel>& labels) = 0; + virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) = 0; virtual void setSecurityLabelsEnabled(bool enabled) = 0; virtual void setUnreadMessageCount(int count) = 0; virtual void convertToMUC() = 0; // virtual TreeWidget *getTreeWidget() = 0; virtual void setSecurityLabelsError() = 0; - virtual SecurityLabel getSelectedSecurityLabel() = 0; + virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() = 0; virtual void setInputEnabled(bool enabled) = 0; virtual void setRosterModel(Roster* model) = 0; virtual void setTabComplete(TabComplete* completer) = 0; diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index 27b9c9e..53a90a7 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -14,8 +14,8 @@ namespace Swift { MockChatWindow() {}; virtual ~MockChatWindow(); - virtual std::string addMessage(const std::string& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, const boost::optional<SecurityLabel>& /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime&) {lastMessageBody_ = message; return "";}; - virtual std::string addAction(const std::string& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, const boost::optional<SecurityLabel>& /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime&) {lastMessageBody_ = message; return "";}; + virtual std::string addMessage(const std::string& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime&) {lastMessageBody_ = message; return "";}; + virtual std::string addAction(const std::string& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime&) {lastMessageBody_ = message; return "";}; virtual void addSystemMessage(const std::string& /*message*/) {}; virtual void addErrorMessage(const std::string& /*message*/) {}; virtual void addPresenceMessage(const std::string& /*message*/) {}; @@ -24,12 +24,12 @@ namespace Swift { virtual void setName(const std::string& name) {name_ = name;}; virtual void show() {}; virtual void activate() {}; - virtual void setAvailableSecurityLabels(const std::vector<SecurityLabel>& labels) {labels_ = labels;}; + virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) {labels_ = labels;}; virtual void setSecurityLabelsEnabled(bool enabled) {labelsEnabled_ = enabled;}; virtual void setUnreadMessageCount(int /*count*/) {}; virtual void convertToMUC() {}; virtual void setSecurityLabelsError() {}; - virtual SecurityLabel getSelectedSecurityLabel() {return SecurityLabel();}; + virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() {return SecurityLabelsCatalog::Item();}; virtual void setInputEnabled(bool /*enabled*/) {}; virtual void setRosterModel(Roster* /*roster*/) {}; virtual void setTabComplete(TabComplete*) {}; @@ -43,7 +43,7 @@ namespace Swift { std::string name_; std::string lastMessageBody_; - std::vector<SecurityLabel> labels_; + std::vector<SecurityLabelsCatalog::Item> labels_; bool labelsEnabled_; }; } diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp index f056a1d..998912a 100644 --- a/Swift/QtUI/QtChatWindow.cpp +++ b/Swift/QtUI/QtChatWindow.cpp @@ -151,15 +151,22 @@ void QtChatWindow::setRosterModel(Roster* roster) { treeWidget_->setRosterModel(roster); } -void QtChatWindow::setAvailableSecurityLabels(const std::vector<SecurityLabel>& labels) { +void QtChatWindow::setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) { availableLabels_ = labels; labelsWidget_->clear(); int i = 0; - foreach (SecurityLabel label, labels) { - QString labelName = P2QSTRING(label.getDisplayMarking()); + int defaultIndex = 0; + foreach (SecurityLabelsCatalog::Item label, labels) { + std::string selector = label.getSelector(); + std::string displayMarking = label.getLabel() ? label.getLabel()->getDisplayMarking() : ""; + QString labelName = selector.empty() ? displayMarking.c_str() : selector.c_str(); labelsWidget_->addItem(labelName, QVariant(i)); + if (label.getIsDefault()) { + defaultIndex = i; + } i++; } + labelsWidget_->setCurrentIndex(defaultIndex); } @@ -176,7 +183,7 @@ void QtChatWindow::setSecurityLabelsEnabled(bool enabled) { } } -SecurityLabel QtChatWindow::getSelectedSecurityLabel() { +SecurityLabelsCatalog::Item QtChatWindow::getSelectedSecurityLabel() { assert(labelsWidget_->isEnabled()); return availableLabels_[labelsWidget_->currentIndex()]; } @@ -248,11 +255,11 @@ void QtChatWindow::updateTitleWithUnreadCount() { emit titleUpdated(); } -std::string QtChatWindow::addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const std::string& avatarPath, const boost::posix_time::ptime& time) { +std::string QtChatWindow::addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) { return addMessage(message, senderName, senderIsSelf, label, avatarPath, "", time); } -std::string QtChatWindow::addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const std::string& avatarPath, const QString& style, const boost::posix_time::ptime& time) { +std::string QtChatWindow::addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const QString& style, const boost::posix_time::ptime& time) { if (isWidgetSelected()) { onAllMessagesRead(); } @@ -299,7 +306,7 @@ int QtChatWindow::getCount() { return unreadCount_; } -std::string QtChatWindow::addAction(const std::string &message, const std::string &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const std::string& avatarPath, const boost::posix_time::ptime& time) { +std::string QtChatWindow::addAction(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) { return addMessage(" *" + message + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time); } diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h index dbcfe9c..910019b 100644 --- a/Swift/QtUI/QtChatWindow.h +++ b/Swift/QtUI/QtChatWindow.h @@ -30,8 +30,8 @@ namespace Swift { public: QtChatWindow(const QString &contact, QtChatTheme* theme, UIEventStream* eventStream); ~QtChatWindow(); - std::string addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const std::string& avatarPath, const boost::posix_time::ptime& time); - std::string addAction(const std::string &message, const std::string &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const std::string& avatarPath, const boost::posix_time::ptime& time); + std::string addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time); + std::string addAction(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time); void addSystemMessage(const std::string& message); void addPresenceMessage(const std::string& message); void addErrorMessage(const std::string& errorMessage); @@ -40,10 +40,10 @@ namespace Swift { void setUnreadMessageCount(int count); void convertToMUC(); // TreeWidget *getTreeWidget(); - void setAvailableSecurityLabels(const std::vector<SecurityLabel>& labels); + void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels); void setSecurityLabelsEnabled(bool enabled); void setSecurityLabelsError(); - SecurityLabel getSelectedSecurityLabel(); + SecurityLabelsCatalog::Item getSelectedSecurityLabel(); void setName(const std::string& name); void setInputEnabled(bool enabled); QtTabbable::AlertType getWidgetAlertState(); @@ -75,7 +75,7 @@ namespace Swift { private: void updateTitleWithUnreadCount(); void tabComplete(); - std::string addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const std::string& avatarPath, const QString& style, const boost::posix_time::ptime& time); + std::string addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const QString& style, const boost::posix_time::ptime& time); int unreadCount_; bool contactIsTyping_; @@ -86,7 +86,7 @@ namespace Swift { QComboBox* labelsWidget_; QtTreeWidget* treeWidget_; TabComplete* completer_; - std::vector<SecurityLabel> availableLabels_; + std::vector<SecurityLabelsCatalog::Item> availableLabels_; bool previousMessageWasSelf_; bool previousMessageWasSystem_; bool previousMessageWasPresence_; diff --git a/Swiften/Elements/DiscoInfo.cpp b/Swiften/Elements/DiscoInfo.cpp index 9c43ef4..7ed8e88 100644 --- a/Swiften/Elements/DiscoInfo.cpp +++ b/Swiften/Elements/DiscoInfo.cpp @@ -10,6 +10,7 @@ namespace Swift { const std::string DiscoInfo::ChatStatesFeature = std::string("http://jabber.org/protocol/chatstates"); const std::string DiscoInfo::SecurityLabelsFeature = std::string("urn:xmpp:sec-label:0"); +const std::string DiscoInfo::SecurityLabelsCatalogueFeature = std::string("urn:xmpp:sec-label:catalog:2"); const std::string DiscoInfo::JabberSearchFeature = std::string("jabber:iq:search"); @@ -32,5 +33,4 @@ bool DiscoInfo::Identity::operator<(const Identity& other) const { } } -const std::string DiscoInfo::SecurityLabels = "urn:xmpp:sec-label:0"; } diff --git a/Swiften/Elements/DiscoInfo.h b/Swiften/Elements/DiscoInfo.h index 5101884..e433b26 100644 --- a/Swiften/Elements/DiscoInfo.h +++ b/Swiften/Elements/DiscoInfo.h @@ -21,9 +21,9 @@ namespace Swift { static const std::string ChatStatesFeature; static const std::string SecurityLabelsFeature; + static const std::string SecurityLabelsCatalogueFeature; static const std::string JabberSearchFeature; - const static std::string SecurityLabels; class Identity { public: Identity(const std::string& name, const std::string& category = "client", const std::string& type = "pc", const std::string& lang = "") : name_(name), category_(category), type_(type), lang_(lang) { diff --git a/Swiften/Elements/SecurityLabelsCatalog.h b/Swiften/Elements/SecurityLabelsCatalog.h index 1c13fdf..10ef459 100644 --- a/Swiften/Elements/SecurityLabelsCatalog.h +++ b/Swiften/Elements/SecurityLabelsCatalog.h @@ -17,14 +17,41 @@ namespace Swift { class SecurityLabelsCatalog : public Payload { public: + class Item { + public: + Item() : default_(false) {} + const boost::shared_ptr<SecurityLabel> getLabel() const { + return label_; + } + + void setLabel(boost::shared_ptr<SecurityLabel> label) { + label_ = label; + } + + const std::string& getSelector() const { return selector_; } + + void setSelector(const std::string& selector) { + selector_ = selector; + } + + bool getIsDefault() const { return default_; } + + void setIsDefault(bool isDefault) { + default_ = isDefault; + } + private: + boost::shared_ptr<SecurityLabel> label_; + std::string selector_; + bool default_; + }; SecurityLabelsCatalog(const JID& to = JID()) : to_(to) {} - const std::vector<SecurityLabel>& getLabels() const { - return labels_; + const std::vector<Item>& getItems() const { + return items_; } - void addLabel(const SecurityLabel& label) { - labels_.push_back(label); + void addItem(const Item& item) { + items_.push_back(item); } const JID& getTo() const { @@ -55,7 +82,7 @@ namespace Swift { JID to_; std::string name_; std::string description_; - std::vector<SecurityLabel> labels_; + std::vector<Item> items_; }; } diff --git a/Swiften/Parser/PayloadParsers/SecurityLabelParser.cpp b/Swiften/Parser/PayloadParsers/SecurityLabelParser.cpp index bf134d7..b769a47 100644 --- a/Swiften/Parser/PayloadParsers/SecurityLabelParser.cpp +++ b/Swiften/Parser/PayloadParsers/SecurityLabelParser.cpp @@ -62,4 +62,8 @@ void SecurityLabelParser::handleCharacterData(const std::string& data) { } } +boost::shared_ptr<SecurityLabel> SecurityLabelParser::getLabelPayload() { + return getPayloadInternal(); +} + } diff --git a/Swiften/Parser/PayloadParsers/SecurityLabelParser.h b/Swiften/Parser/PayloadParsers/SecurityLabelParser.h index bd80921..b54c3be 100644 --- a/Swiften/Parser/PayloadParsers/SecurityLabelParser.h +++ b/Swiften/Parser/PayloadParsers/SecurityLabelParser.h @@ -20,7 +20,7 @@ namespace Swift { virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); virtual void handleEndElement(const std::string& element, const std::string&); virtual void handleCharacterData(const std::string& data); - + boost::shared_ptr<SecurityLabel> getLabelPayload(); private: enum Level { TopLevel = 0, diff --git a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.cpp b/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.cpp index 1f2a6bc..a08cd11 100644 --- a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.cpp +++ b/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.cpp @@ -15,6 +15,7 @@ SecurityLabelsCatalogParser::SecurityLabelsCatalogParser() : level_(TopLevel), l } SecurityLabelsCatalogParser::~SecurityLabelsCatalogParser() { + //delete currentLabel_; delete labelParserFactory_; } @@ -25,6 +26,11 @@ void SecurityLabelsCatalogParser::handleStartElement(const std::string& element, getPayloadInternal()->setName(attributes.getAttribute("name")); getPayloadInternal()->setDescription(attributes.getAttribute("desc")); } + else if (level_ == ItemLevel && element == "item" && ns == "urn:xmpp:sec-label:catalog:2") { + currentItem_ = boost::shared_ptr<SecurityLabelsCatalog::Item>(new SecurityLabelsCatalog::Item()); + currentItem_->setSelector(attributes.getAttribute("selector")); + currentItem_->setIsDefault(attributes.getBoolAttribute("default", false)); + } else if (level_ == LabelLevel) { assert(!labelParser_); if (labelParserFactory_->canParse(element, ns, attributes)) { @@ -42,13 +48,19 @@ void SecurityLabelsCatalogParser::handleEndElement(const std::string& element, c if (labelParser_) { labelParser_->handleEndElement(element, ns); } - if (level_ == LabelLevel && labelParser_) { - SecurityLabel* label = dynamic_cast<SecurityLabel*>(labelParser_->getPayload().get()); - assert(label); - getPayloadInternal()->addLabel(SecurityLabel(*label)); + if (level_ == LabelLevel && labelParser_ && currentItem_) { + boost::shared_ptr<SecurityLabel> currentLabel = labelParser_->getLabelPayload(); + assert(currentLabel); + currentItem_->setLabel(currentLabel); delete labelParser_; labelParser_ = 0; } + else if (level_ == ItemLevel && element == "item" && ns == "urn:xmpp:sec-label:catalog:2") { + if (currentItem_) { + getPayloadInternal()->addItem(SecurityLabelsCatalog::Item(*currentItem_)); + currentItem_.reset(); + } + } --level_; } diff --git a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h b/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h index 2222117..ca422d1 100644 --- a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h +++ b/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParser.h @@ -27,11 +27,13 @@ namespace Swift { enum Level { TopLevel = 0, PayloadLevel = 1, - LabelLevel = 2 + ItemLevel = 2, + LabelLevel = 3 }; int level_; SecurityLabelParserFactory* labelParserFactory_; SecurityLabelParser* labelParser_; + boost::shared_ptr<SecurityLabelsCatalog::Item> currentItem_; }; } diff --git a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParserFactory.h b/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParserFactory.h index bb1da3a..a148d81 100644 --- a/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParserFactory.h +++ b/Swiften/Parser/PayloadParsers/SecurityLabelsCatalogParserFactory.h @@ -13,7 +13,7 @@ namespace Swift { class SecurityLabelsCatalogParserFactory : public GenericPayloadParserFactory<SecurityLabelsCatalogParser> { public: - SecurityLabelsCatalogParserFactory() : GenericPayloadParserFactory<SecurityLabelsCatalogParser>("catalog", "urn:xmpp:sec-label:catalog:0") {} + SecurityLabelsCatalogParserFactory() : GenericPayloadParserFactory<SecurityLabelsCatalogParser>("catalog", "urn:xmpp:sec-label:catalog:2") {} }; } diff --git a/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelsCatalogParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelsCatalogParserTest.cpp index 9925e34..e1e8594 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelsCatalogParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/SecurityLabelsCatalogParserTest.cpp @@ -25,26 +25,38 @@ class SecurityLabelsCatalogParserTest : public CppUnit::TestFixture PayloadsParserTester parser; CPPUNIT_ASSERT(parser.parse( - "<catalog desc=\"an example set of labels\" name=\"Default\" to=\"example.com\" xmlns=\"urn:xmpp:sec-label:catalog:0\">" + "<catalog desc=\"an example set of labels\" name=\"Default\" to=\"example.com\" xmlns=\"urn:xmpp:sec-label:catalog:2\">" + "<item selector='Classified|SECRET'>" "<securitylabel xmlns=\"urn:xmpp:sec-label:0\">" "<displaymarking bgcolor=\"red\" fgcolor=\"black\">SECRET</displaymarking>" "<label><esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQYCAQQGASk=</esssecuritylabel></label>" "</securitylabel>" + "</item>" + "<item selector='Classified|CONFIDENTIAL' default='true'>" "<securitylabel xmlns=\"urn:xmpp:sec-label:0\">" "<displaymarking bgcolor=\"navy\" fgcolor=\"black\">CONFIDENTIAL</displaymarking>" "<label><esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQMGASk=</esssecuritylabel></label>" "</securitylabel>" + "</item>" + "<item selector='Unclassified|UNCLASSIFIED'/>" "</catalog>")); SecurityLabelsCatalog* payload = dynamic_cast<SecurityLabelsCatalog*>(parser.getPayload().get()); CPPUNIT_ASSERT_EQUAL(std::string("Default"), payload->getName()); CPPUNIT_ASSERT_EQUAL(std::string("an example set of labels"), payload->getDescription()); CPPUNIT_ASSERT_EQUAL(JID("example.com"), payload->getTo()); - CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(payload->getLabels().size())); - CPPUNIT_ASSERT_EQUAL(std::string("SECRET"), payload->getLabels()[0].getDisplayMarking()); - CPPUNIT_ASSERT_EQUAL(std::string("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQYCAQQGASk=</esssecuritylabel>"), payload->getLabels()[0].getLabel()); - CPPUNIT_ASSERT_EQUAL(std::string("CONFIDENTIAL"), payload->getLabels()[1].getDisplayMarking()); - CPPUNIT_ASSERT_EQUAL(std::string("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQMGASk=</esssecuritylabel>"), payload->getLabels()[1].getLabel()); + CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(payload->getItems().size())); + CPPUNIT_ASSERT_EQUAL(std::string("SECRET"), payload->getItems()[0].getLabel()->getDisplayMarking()); + CPPUNIT_ASSERT_EQUAL(std::string("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQYCAQQGASk=</esssecuritylabel>"), payload->getItems()[0].getLabel()->getLabel()); + CPPUNIT_ASSERT_EQUAL(false, payload->getItems()[0].getIsDefault()); + CPPUNIT_ASSERT_EQUAL(std::string("Classified|SECRET"), payload->getItems()[0].getSelector()); + CPPUNIT_ASSERT_EQUAL(std::string("CONFIDENTIAL"), payload->getItems()[1].getLabel()->getDisplayMarking()); + CPPUNIT_ASSERT_EQUAL(std::string("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQMGASk=</esssecuritylabel>"), payload->getItems()[1].getLabel()->getLabel()); + CPPUNIT_ASSERT_EQUAL(true, payload->getItems()[1].getIsDefault()); + CPPUNIT_ASSERT_EQUAL(std::string("Classified|CONFIDENTIAL"), payload->getItems()[1].getSelector()); + CPPUNIT_ASSERT_EQUAL(false, payload->getItems()[2].getIsDefault()); + CPPUNIT_ASSERT_EQUAL(std::string("Unclassified|UNCLASSIFIED"), payload->getItems()[2].getSelector()); + CPPUNIT_ASSERT(!payload->getItems()[2].getLabel()); } }; diff --git a/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp b/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp index 5e4d8e4..7424c98 100644 --- a/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp @@ -16,7 +16,7 @@ SecurityLabelsCatalogSerializer::SecurityLabelsCatalogSerializer() : GenericPayl } std::string SecurityLabelsCatalogSerializer::serializePayload(boost::shared_ptr<SecurityLabelsCatalog> catalog) const { - XMLElement element("catalog", "urn:xmpp:sec-label:catalog:0"); + XMLElement element("catalog", "urn:xmpp:sec-label:catalog:2"); if (!catalog->getName().empty()) { element.setAttribute("name", catalog->getName()); } @@ -26,9 +26,17 @@ std::string SecurityLabelsCatalogSerializer::serializePayload(boost::shared_ptr< if (!catalog->getDescription().empty()) { element.setAttribute("desc", catalog->getDescription()); } - foreach (const SecurityLabel& label, catalog->getLabels()) { - std::string serializedLabel = SecurityLabelSerializer().serialize(boost::shared_ptr<SecurityLabel>(new SecurityLabel(label))); - element.addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(serializedLabel))); + foreach (const SecurityLabelsCatalog::Item& item, catalog->getItems()) { + boost::shared_ptr<XMLElement> itemElement(new XMLElement("item")); + itemElement->setAttribute("selector", item.getSelector()); + if (item.getIsDefault()) { + itemElement->setAttribute("default", "true"); + } + if (item.getLabel()) { + std::string serializedLabel = SecurityLabelSerializer().serialize(item.getLabel()); + itemElement->addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(serializedLabel))); + } + element.addNode(itemElement); } return element.serialize(); } diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp index 928f209..a7bf1b9 100644 --- a/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/SecurityLabelsCatalogSerializerTest.cpp @@ -27,30 +27,47 @@ class SecurityLabelsCatalogSerializerTest : public CppUnit::TestFixture catalog->setName("Default"); catalog->setDescription("an example set of labels"); - SecurityLabel securityLabel1; - securityLabel1.setDisplayMarking("SECRET"); - securityLabel1.setForegroundColor("black"); - securityLabel1.setBackgroundColor("red"); - securityLabel1.setLabel("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQYCAQQGASk=</esssecuritylabel>"); - catalog->addLabel(securityLabel1); - - SecurityLabel securityLabel2; - securityLabel2.setDisplayMarking("CONFIDENTIAL"); - securityLabel2.setForegroundColor("black"); - securityLabel2.setBackgroundColor("navy"); - securityLabel2.setLabel("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQMGASk=</esssecuritylabel>"); - catalog->addLabel(securityLabel2); + SecurityLabelsCatalog::Item item1; + boost::shared_ptr<SecurityLabel> securityLabel1(new SecurityLabel()); + item1.setLabel(securityLabel1); + securityLabel1->setDisplayMarking("SECRET"); + securityLabel1->setForegroundColor("black"); + securityLabel1->setBackgroundColor("red"); + item1.setIsDefault(false); + item1.setSelector("Classified|SECRET"); + securityLabel1->setLabel("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQYCAQQGASk=</esssecuritylabel>"); + catalog->addItem(item1); + + SecurityLabelsCatalog::Item item2; + boost::shared_ptr<SecurityLabel> securityLabel2(new SecurityLabel()); + item2.setLabel(securityLabel2); + securityLabel2->setDisplayMarking("CONFIDENTIAL"); + securityLabel2->setForegroundColor("black"); + securityLabel2->setBackgroundColor("navy"); + item2.setIsDefault(true); + item2.setSelector("Classified|CONFIDENTIAL"); + securityLabel2->setLabel("<esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQMGASk=</esssecuritylabel>"); + catalog->addItem(item2); + + SecurityLabelsCatalog::Item item3; + item3.setSelector("Unclassified|UNCLASSIFIED"); + catalog->addItem(item3); CPPUNIT_ASSERT_EQUAL(std::string( - "<catalog desc=\"an example set of labels\" name=\"Default\" to=\"example.com\" xmlns=\"urn:xmpp:sec-label:catalog:0\">" + "<catalog desc=\"an example set of labels\" name=\"Default\" to=\"example.com\" xmlns=\"urn:xmpp:sec-label:catalog:2\">" + "<item selector=\"Classified|SECRET\">" "<securitylabel xmlns=\"urn:xmpp:sec-label:0\">" "<displaymarking bgcolor=\"red\" fgcolor=\"black\">SECRET</displaymarking>" "<label><esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQYCAQQGASk=</esssecuritylabel></label>" "</securitylabel>" + "</item>" + "<item default=\"true\" selector=\"Classified|CONFIDENTIAL\">" "<securitylabel xmlns=\"urn:xmpp:sec-label:0\">" "<displaymarking bgcolor=\"navy\" fgcolor=\"black\">CONFIDENTIAL</displaymarking>" "<label><esssecuritylabel xmlns=\"urn:xmpp:sec-label:ess:0\">MQMGASk=</esssecuritylabel></label>" "</securitylabel>" + "</item>" + "<item selector=\"Unclassified|UNCLASSIFIED\"/>" "</catalog>"), testling.serialize(catalog)); } }; |