diff options
| author | Kevin Smith <git@kismith.co.uk> | 2011-03-04 10:56:07 (GMT) | 
|---|---|---|
| committer | Kevin Smith <git@kismith.co.uk> | 2011-03-04 10:58:16 (GMT) | 
| commit | 37bfeaf6f2e0145731c32f79291ff3d48ae0e1b1 (patch) | |
| tree | e6455b4f21b3a5ba716526916a67cfd4b7e55051 | |
| parent | 12024229138787d7df91cb8101d0986996880e3d (diff) | |
| download | swift-37bfeaf6f2e0145731c32f79291ff3d48ae0e1b1.zip swift-37bfeaf6f2e0145731c32f79291ff3d48ae0e1b1.tar.bz2 | |
Upgrade XEP-0258 support to match 0.6.
Resolves: #183
Release-Notes: Security labels (XEP-0258) support has been updated to match the latest version of the specification.
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));  		}  }; | 
 Swift
 Swift