aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2012-05-14 11:20:09 +0200
committerJeremy Lainé <jeremy.laine@m4x.org>2012-05-14 11:20:09 +0200
commita40682ebcdc4552b7185d4a6d0e9deb1dc5261cc (patch)
tree2b2691ee52f781256e6756d36955c6862703a233
parent79e2192b07694be32367feb8fad4d27e75cc87e7 (diff)
downloadqxmpp-a40682ebcdc4552b7185d4a6d0e9deb1dc5261cc.tar.gz
implement/test XEP-0115 verification strings for dataforms (issue: #140)
-rw-r--r--src/base/QXmppDiscoveryIq.cpp38
-rw-r--r--tests/tests.cpp43
-rw-r--r--tests/tests.h3
3 files changed, 82 insertions, 2 deletions
diff --git a/src/base/QXmppDiscoveryIq.cpp b/src/base/QXmppDiscoveryIq.cpp
index 05e407b3..228fd562 100644
--- a/src/base/QXmppDiscoveryIq.cpp
+++ b/src/base/QXmppDiscoveryIq.cpp
@@ -206,6 +206,33 @@ QByteArray QXmppDiscoveryIq::verificationString() const
S += QString("%1/%2/%3/%4<").arg(identity.category(), identity.type(), identity.language(), identity.name());
foreach (const QString &feature, sortedFeatures)
S += feature + QLatin1String("<");
+
+ if (!m_form.isNull()) {
+ QMap<QString, QXmppDataForm::Field> fieldMap;
+ foreach (const QXmppDataForm::Field &field, m_form.fields()) {
+ fieldMap.insert(field.key(), field);
+ }
+
+ if (fieldMap.contains("FORM_TYPE")) {
+ const QXmppDataForm::Field field = fieldMap.take("FORM_TYPE");
+ S += field.value().toString() + QLatin1String("<");
+
+ QStringList keys = fieldMap.keys();
+ qSort(keys);
+ foreach (const QString &key, keys) {
+ const QXmppDataForm::Field field = fieldMap.value(key);
+ S += key + QLatin1String("<");
+ if (field.value().canConvert<QStringList>())
+ S += field.value().toStringList().join(QLatin1String("<"));
+ else
+ S += field.value().toString();
+ S += QLatin1String("<");
+ }
+ } else {
+ qWarning("QXmppDiscoveryIq form does not contain FORM_TYPE");
+ }
+ }
+
QCryptographicHash hasher(QCryptographicHash::Sha1);
hasher.addData(S.toUtf8());
return hasher.result();
@@ -241,6 +268,17 @@ void QXmppDiscoveryIq::parseElementFromChild(const QDomElement &element)
identity.setCategory(itemElement.attribute("category"));
identity.setName(itemElement.attribute("name"));
identity.setType(itemElement.attribute("type"));
+
+ // FIXME: for some reason the language does not found,
+ // so we are forced to use QDomNamedNodeMap
+ QDomNamedNodeMap m(itemElement.attributes());
+ for (int i = 0; i < m.size(); ++i) {
+ if (m.item(i).nodeName() == "xml:lang") {
+ identity.setLanguage(m.item(i).nodeValue());
+ break;
+ }
+ }
+
m_identities.append(identity);
}
else if (itemElement.tagName() == "item")
diff --git a/tests/tests.cpp b/tests/tests.cpp
index 5aea4132..29c0253d 100644
--- a/tests/tests.cpp
+++ b/tests/tests.cpp
@@ -334,7 +334,7 @@ void TestPackets::testBindResult()
serializePacket(bind, xml);
}
-void TestPackets::testDiscoveryIq()
+void TestPackets::testDiscovery()
{
const QByteArray xml(
"<iq id=\"disco1\" from=\"benvolio@capulet.lit/230193\" type=\"result\">"
@@ -353,6 +353,47 @@ void TestPackets::testDiscoveryIq()
serializePacket(disco, xml);
}
+void TestPackets::testDiscoveryWithForm()
+{
+ const QByteArray xml(
+ "<iq id=\"disco1\" to=\"juliet@capulet.lit/chamber\" from=\"benvolio@capulet.lit/230193\" type=\"result\">"
+ "<query xmlns=\"http://jabber.org/protocol/disco#info\" node=\"http://psi-im.org#q07IKJEyjvHSyhy//CH0CxmKi8w=\">"
+ "<identity xml:lang=\"en\" category=\"client\" name=\"Psi 0.11\" type=\"pc\"/>"
+ "<identity xml:lang=\"el\" category=\"client\" name=\"Ψ 0.11\" type=\"pc\"/>"
+ "<feature var=\"http://jabber.org/protocol/caps\"/>"
+ "<feature var=\"http://jabber.org/protocol/disco#info\"/>"
+ "<feature var=\"http://jabber.org/protocol/disco#items\"/>"
+ "<feature var=\"http://jabber.org/protocol/muc\"/>"
+ "<x xmlns=\"jabber:x:data\" type=\"result\">"
+ "<field type=\"hidden\" var=\"FORM_TYPE\">"
+ "<value>urn:xmpp:dataforms:softwareinfo</value>"
+ "</field>"
+ "<field type=\"text-multi\" var=\"ip_version\">"
+ "<value>ipv4</value>"
+ "<value>ipv6</value>"
+ "</field>"
+ "<field type=\"text-single\" var=\"os\">"
+ "<value>Mac</value>"
+ "</field>"
+ "<field type=\"text-single\" var=\"os_version\">"
+ "<value>10.5.1</value>"
+ "</field>"
+ "<field type=\"text-single\" var=\"software\">"
+ "<value>Psi</value>"
+ "</field>"
+ "<field type=\"text-single\" var=\"software_version\">"
+ "<value>0.11</value>"
+ "</field>"
+ "</x>"
+ "</query>"
+ "</iq>");
+
+ QXmppDiscoveryIq disco;
+ parsePacket(disco, xml);
+ QCOMPARE(disco.verificationString(), QByteArray::fromBase64("q07IKJEyjvHSyhy//CH0CxmKi8w="));
+ serializePacket(disco, xml);
+}
+
void TestPackets::testMessage()
{
const QByteArray xml(
diff --git a/tests/tests.h b/tests/tests.h
index 0b91a11e..3816e6d9 100644
--- a/tests/tests.h
+++ b/tests/tests.h
@@ -50,7 +50,8 @@ private slots:
void testBindNoResource();
void testBindResource();
void testBindResult();
- void testDiscoveryIq();
+ void testDiscovery();
+ void testDiscoveryWithForm();
void testMessage();
void testMessageFull();
void testMessageAttention();