From ea41bd07a0e014c12cce144b421abac9f21d1269 Mon Sep 17 00:00:00 2001
From: Mili Verma <mili.verma@isode.com>
Date: Tue, 23 Jun 2015 10:08:56 +0100
Subject: Parse hostname for xep-0233

Test-information:
Verified with M-Link.
Unit tests pass.

Change-Id: Ic675c8d7cd70e01be61c51c0280e1d7208b364ba

diff --git a/Swiften/Elements/StreamFeatures.h b/Swiften/Elements/StreamFeatures.h
index 26dc1ba..10563a9 100644
--- a/Swiften/Elements/StreamFeatures.h
+++ b/Swiften/Elements/StreamFeatures.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -8,6 +8,7 @@
 
 #include <vector>
 #include <string>
+#include <boost/optional.hpp>
 #include <boost/shared_ptr.hpp>
 
 #include <Swiften/Base/API.h>
@@ -68,6 +69,14 @@ namespace Swift {
 				return !authenticationMechanisms_.empty();
 			}
 
+			const boost::optional<std::string> getAuthenticationHostname() const {
+				return authenticationHostname_;
+			}
+
+			void setAuthenticationHostname(const boost::optional<std::string> authenticationHostname) {
+				authenticationHostname_ = authenticationHostname;
+			}
+
 			bool hasStreamManagement() const {
 				return hasStreamManagement_;
 			}
@@ -92,5 +101,6 @@ namespace Swift {
 			bool hasSession_;
 			bool hasStreamManagement_;
 			bool hasRosterVersioning_;
+			boost::optional<std::string> authenticationHostname_;
 	};
 }
diff --git a/Swiften/Parser/StreamFeaturesParser.cpp b/Swiften/Parser/StreamFeaturesParser.cpp
index f0b8c9a..913c50d 100644
--- a/Swiften/Parser/StreamFeaturesParser.cpp
+++ b/Swiften/Parser/StreamFeaturesParser.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -8,7 +8,7 @@
 
 namespace Swift {
 
-StreamFeaturesParser::StreamFeaturesParser() : GenericElementParser<StreamFeatures>(), currentDepth_(0), inMechanisms_(false), inMechanism_(false), inCompression_(false), inCompressionMethod_(false) {
+StreamFeaturesParser::StreamFeaturesParser() : GenericElementParser<StreamFeatures>(), currentDepth_(0), inMechanisms_(false), inMechanism_(false), inAuthenticationHostname_(false), inCompression_(false), inCompressionMethod_(false) {
 }
 
 void StreamFeaturesParser::handleStartElement(const std::string& element, const std::string& ns, const AttributeMap&) {
@@ -44,6 +44,11 @@ void StreamFeaturesParser::handleStartElement(const std::string& element, const
 			inMechanism_ = true;
 			currentText_ = "";
 		}
+		else if (inMechanisms_ && element == "hostname" && ns == "urn:xmpp:domain-based-name:1") {
+			inAuthenticationHostname_ = true;
+			currentText_ = "";
+		}
+
 	}
 	++currentDepth_;
 }
@@ -63,6 +68,10 @@ void StreamFeaturesParser::handleEndElement(const std::string&, const std::strin
 			getElementGeneric()->addAuthenticationMechanism(currentText_);
 			inMechanism_ = false;
 		}
+		else if (inAuthenticationHostname_) {
+			getElementGeneric()->setAuthenticationHostname(currentText_);
+			inAuthenticationHostname_ = false;
+		}
 	}
 }
 
diff --git a/Swiften/Parser/StreamFeaturesParser.h b/Swiften/Parser/StreamFeaturesParser.h
index 20eabdc..9ae5fd8 100644
--- a/Swiften/Parser/StreamFeaturesParser.h
+++ b/Swiften/Parser/StreamFeaturesParser.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -26,6 +26,7 @@ namespace Swift {
 			std::string currentText_;
 			bool inMechanisms_;
 			bool inMechanism_;
+			bool inAuthenticationHostname_;
 			bool inCompression_;
 			bool inCompressionMethod_;
 	};
diff --git a/Swiften/Parser/UnitTest/StreamFeaturesParserTest.cpp b/Swiften/Parser/UnitTest/StreamFeaturesParserTest.cpp
index 8dd3a22..f6c9336 100644
--- a/Swiften/Parser/UnitTest/StreamFeaturesParserTest.cpp
+++ b/Swiften/Parser/UnitTest/StreamFeaturesParserTest.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2015 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -16,6 +16,8 @@ class StreamFeaturesParserTest : public CppUnit::TestFixture {
 		CPPUNIT_TEST_SUITE(StreamFeaturesParserTest);
 		CPPUNIT_TEST(testParse);
 		CPPUNIT_TEST(testParse_Empty);
+		CPPUNIT_TEST(testParse_AuthenticationHostname);
+		CPPUNIT_TEST(testParse_AuthenticationHostnameEmpty);
 		CPPUNIT_TEST_SUITE_END();
 
 	public:
@@ -49,6 +51,7 @@ class StreamFeaturesParserTest : public CppUnit::TestFixture {
 			CPPUNIT_ASSERT(element->hasAuthenticationMechanisms());
 			CPPUNIT_ASSERT(element->hasAuthenticationMechanism("DIGEST-MD5"));
 			CPPUNIT_ASSERT(element->hasAuthenticationMechanism("PLAIN"));
+			CPPUNIT_ASSERT(!element->getAuthenticationHostname());
 			CPPUNIT_ASSERT(element->hasStreamManagement());
 			CPPUNIT_ASSERT(element->hasRosterVersioning());
 		}
@@ -65,6 +68,41 @@ class StreamFeaturesParserTest : public CppUnit::TestFixture {
 			CPPUNIT_ASSERT(!element->hasResourceBind());
 			CPPUNIT_ASSERT(!element->hasAuthenticationMechanisms());
 		}
+
+		void testParse_AuthenticationHostname() {
+			StreamFeaturesParser testling;
+			ElementParserTester parser(&testling);
+			std::string hostname("auth42.us.example.com");
+
+			CPPUNIT_ASSERT(parser.parse(
+				"<stream:features xmlns:stream='http://etherx.jabber.org/streams'>"
+					"<mechanisms xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"
+						"<mechanism>GSSAPI</mechanism>"
+						"<hostname xmlns=\"urn:xmpp:domain-based-name:1\">auth42.us.example.com</hostname>"
+					"</mechanisms>"
+				"</stream:features>"));
+
+			StreamFeatures::ref element = boost::dynamic_pointer_cast<StreamFeatures>(testling.getElement());
+			CPPUNIT_ASSERT(element->hasAuthenticationMechanism("GSSAPI"));
+			CPPUNIT_ASSERT_EQUAL(*element->getAuthenticationHostname(), hostname);
+		}
+
+		void testParse_AuthenticationHostnameEmpty() {
+			StreamFeaturesParser testling;
+			ElementParserTester parser(&testling);
+
+			CPPUNIT_ASSERT(parser.parse(
+				"<stream:features xmlns:stream='http://etherx.jabber.org/streams'>"
+					"<mechanisms xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"
+						"<mechanism>GSSAPI</mechanism>"
+						"<hostname xmlns=\"urn:xmpp:domain-based-name:1\"></hostname>"
+					"</mechanisms>"
+				"</stream:features>"));
+
+			StreamFeatures::ref element = boost::dynamic_pointer_cast<StreamFeatures>(testling.getElement());
+			CPPUNIT_ASSERT(element->hasAuthenticationMechanism("GSSAPI"));
+			CPPUNIT_ASSERT(element->getAuthenticationHostname()->empty());
+		}
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(StreamFeaturesParserTest);
-- 
cgit v0.10.2-6-g49f6