Skip to content
Permalink
Browse files

Implement XEP-0334: Message Processing Hints

This implements parsing and serialization of XEP-0334: Message
Processing Hints in version 0.3.0.

https://xmpp.org/extensions/xep-0334.html

Co-authored-by: Juan Aragon <jaaragont@gmail.com>
Co-authored-by: Sam Truscott <sam@wumpus.co.uk>
  • Loading branch information...
3 people committed Sep 4, 2019
1 parent e7394af commit 35256b7d95374717905f8ac8d4d524c4b691389e
@@ -3,6 +3,8 @@ QXmpp 1.0.1 (UNRELEASED)

New features:
- Add support for SCRAM-SHA-1 and SCRAM-SHA-256 (#183, @jlaine)
- Add XEP-0334: Message Processing Hints (v0.3.0) (#212, @lnjX, @jaragont,
@sam-truscott)
- Add XEP-0367: Message Attaching (v0.3.0) (#196, @lnjX)
- Add XEP-0380: Explicit Message Encryption (v0.3.0) (#199, @lnjX)
- Add XEP-0382: Spoiler messages (v0.2.0) (#195, @lnjX)
@@ -40,6 +40,7 @@ Complete:
- XEP-0308: Last Message Correction
- XEP-0313: Message Archive Management
- XEP-0319: Last User Interaction in Presence
- XEP-0334: Message Processing Hints (v0.3.0)
- XEP-0352: Client State Indication
- XEP-0367: Message Attaching (v0.3.0)
- XEP-0380: Explicit Message Encryption (v0.3.0)
@@ -133,6 +133,8 @@ const char* ns_mam = "urn:xmpp:mam:1";
const char* ns_idle = "urn:xmpp:idle:1";
// XEP-0333: Chat Markers
const char* ns_chat_markers = "urn:xmpp:chat-markers:0";
// XEP-0334: Message Processing Hints
const char* ns_message_processing_hints = "urn:xmpp:hints";
// XEP-0352: Client State Indication
const char* ns_csi = "urn:xmpp:csi:0";
// XEP-0363: HTTP File Upload
@@ -145,6 +145,8 @@ extern const char* ns_mam;
extern const char* ns_idle;
// XEP-0333: Char Markers
extern const char* ns_chat_markers;
// XEP-0334: Message Processing Hints:
extern const char* ns_message_processing_hints;
// XEP-0352: Client State Indication
extern const char* ns_csi;
// XEP-0363: HTTP File Upload
@@ -64,6 +64,13 @@ static const QStringList ENCRYPTION_NAMESPACES = {
ns_omemo
};

static const QStringList HINT_TYPES = {
QStringLiteral("no-permanent-store"),
QStringLiteral("no-store"),
QStringLiteral("no-copy"),
QStringLiteral("store")
};

static const QStringList ENCRYPTION_NAMES = {
QString(),
QString(),
@@ -121,6 +128,9 @@ class QXmppMessagePrivate : public QSharedData
// XEP-0308: Last Message Correction
QString replaceId;

// XEP-0334: Message Processing Hints
quint8 hints;

// XEP-0367: Message Attaching
QString attachId;

@@ -161,6 +171,8 @@ QXmppMessage::QXmppMessage(const QString& from, const QString& to, const
d->marker = NoMarker;

d->privatemsg = false;

d->hints = 0;
}

/// Constructs a copy of \a other.
@@ -546,6 +558,38 @@ void QXmppMessage::setReplaceId(const QString &replaceId)
d->replaceId = replaceId;
}

/// Returns true if the message contains the hint passed, as defined in
/// XEP-0334: Message Processing Hints

bool QXmppMessage::hasHint(const Hint hint) const
{
return d->hints & hint;
}

/// Adds a hint to the message, as defined in XEP-0334: Message Processing
/// Hints

void QXmppMessage::addHint(const Hint hint)
{
d->hints |= hint;
}

/// Removes a hint from the message, as defined in XEP-0334: Message Processing
/// Hints

void QXmppMessage::removeHint(const Hint hint)
{
d->hints &= ~hint;
}

/// Removes all hints from the message, as defined in XEP-0334: Message
/// Processing Hints

void QXmppMessage::removeAllHints()
{
d->hints = 0;
}

/// Returns the message id this message is linked/attached to. See XEP-0367:
/// Message Attaching for details.

@@ -848,6 +892,9 @@ void QXmppMessage::parse(const QDomElement &element)
else {
extensions << QXmppElement(xElement);
}
// XEP-0334: Message Processing Hints
} else if (xElement.namespaceURI() == ns_message_processing_hints && HINT_TYPES.contains(xElement.tagName())) {
addHint(Hint(1 << HINT_TYPES.indexOf(xElement.tagName())));
// XEP-0367: Message Attaching
} else if (xElement.tagName() == "attach-to" && xElement.namespaceURI() == ns_message_attaching) {
d->attachId = xElement.attribute("id");
@@ -1000,6 +1047,15 @@ void QXmppMessage::toXml(QXmlStreamWriter *xmlWriter) const
xmlWriter->writeEndElement();
}

// XEP-0334: Message Processing Hints
for (quint8 i = 0; i < HINT_TYPES.size(); i++) {
if (hasHint(Hint(1 << i))) {
xmlWriter->writeStartElement(HINT_TYPES.at(i));
xmlWriter->writeAttribute("xmlns", ns_message_processing_hints);
xmlWriter->writeEndElement();
}
}

// XEP-0367: Message Attaching
if (!d->attachId.isEmpty()) {
xmlWriter->writeStartElement("attach-to");
@@ -66,6 +66,14 @@ class QXMPP_EXPORT QXmppMessage : public QXmppStanza
Acknowledged
};

/// XEP-0334: Message Processing Hints
enum Hint {
NoPermanentStore = 1 << 0, ///< Do not allow permanent storage
NoStore = 1 << 1, ///< Do not store at all
NoCopy = 1 << 2, ///< Do not copy the message
Store = 1 << 3 ///< Do store the message
};

/// This enum describes different end-to-end encryption methods. These can
/// be used to mark a message explicitly as encrypted with a specific
/// algothim. See XEP-0380: Explicit Message Encryption for details.
@@ -152,6 +160,12 @@ class QXMPP_EXPORT QXmppMessage : public QXmppStanza
QString replaceId() const;
void setReplaceId(const QString&);

// XEP-0334: Message Processing Hints
bool hasHint(const Hint hint) const;
void addHint(const Hint hint);
void removeHint(const Hint hint);
void removeAllHints();

// XEP-0367: Message Attaching
QString attachId() const;
void setAttachId(const QString&);
@@ -52,6 +52,7 @@ private slots:
void testMix();
void testEme();
void testSpoiler();
void testProcessingHints();
};

void tst_QXmppMessage::testBasic_data()
@@ -117,6 +118,10 @@ void tst_QXmppMessage::testBasic()
QCOMPARE(message.xhtml(), QString());
QCOMPARE(message.encryptionMethod(), QXmppMessage::NoEncryption);
QVERIFY(!message.isSpoiler());
QVERIFY(!message.hasHint(QXmppMessage::NoPermanentStore));
QVERIFY(!message.hasHint(QXmppMessage::NoStore));
QVERIFY(!message.hasHint(QXmppMessage::NoCopy));
QVERIFY(!message.hasHint(QXmppMessage::Store));
serializePacket(message, xml);
}

@@ -748,5 +753,51 @@ void tst_QXmppMessage::testSpoiler()
QVERIFY(message.isSpoiler());
}

void tst_QXmppMessage::testProcessingHints()
{
const QByteArray xml(
"<message to=\"juliet@capulet.lit/laptop\" "
"from=\"romeo@montague.lit/laptop\" "
"type=\"chat\">"
"<body>V unir avtug'f pybnx gb uvqr zr sebz gurve fvtug</body>"
"<no-permanent-store xmlns=\"urn:xmpp:hints\"/>"
"<no-store xmlns=\"urn:xmpp:hints\"/>"
"<no-copy xmlns=\"urn:xmpp:hints\"/>"
"<store xmlns=\"urn:xmpp:hints\"/>"
"</message>"
);

// test parsing
QXmppMessage message;
parsePacket(message, xml);
QVERIFY(message.hasHint(QXmppMessage::NoPermanentStore));
QVERIFY(message.hasHint(QXmppMessage::NoStore));
QVERIFY(message.hasHint(QXmppMessage::NoCopy));
QVERIFY(message.hasHint(QXmppMessage::Store));

// test serialization
QXmppMessage message2;
message2.setType(QXmppMessage::Chat);
message2.setFrom(QString("romeo@montague.lit/laptop"));
message2.setTo(QString("juliet@capulet.lit/laptop"));
message2.setBody(QString("V unir avtug'f pybnx gb uvqr zr sebz gurve fvtug"));
message2.addHint(QXmppMessage::NoPermanentStore);
message2.addHint(QXmppMessage::NoStore);
message2.addHint(QXmppMessage::NoCopy);
message2.addHint(QXmppMessage::Store);
serializePacket(message2, xml);

// test remove hint
message2.removeHint(QXmppMessage::NoCopy);
QVERIFY(!message2.hasHint(QXmppMessage::NoCopy));

// test remove all hints
message2.removeAllHints();
QVERIFY(!message2.hasHint(QXmppMessage::NoPermanentStore));
QVERIFY(!message2.hasHint(QXmppMessage::NoStore));
QVERIFY(!message2.hasHint(QXmppMessage::NoCopy));
QVERIFY(!message2.hasHint(QXmppMessage::Store));
}

QTEST_MAIN(tst_QXmppMessage)
#include "tst_qxmppmessage.moc"

0 comments on commit 35256b7

Please sign in to comment.
You can’t perform that action at this time.