diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-09-05 15:28:18 +0200 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-09-05 15:28:18 +0200 |
| commit | 9168d631d5c266ee79c3112840423d4fca0c96dd (patch) | |
| tree | d5e9d67627ca46cb04eb63e06a50ffa7dc38aa7d | |
| parent | 49d30871e8a605bea9679353afd9a6fb6a877664 (diff) | |
| download | qxmpp-9168d631d5c266ee79c3112840423d4fca0c96dd.tar.gz | |
Add support for X-OAUTH2 authentication for Google Talk.
| -rw-r--r-- | CHANGELOG | 1 | ||||
| -rw-r--r-- | src/base/QXmppSasl.cpp | 29 | ||||
| -rw-r--r-- | src/base/QXmppSasl_p.h | 11 | ||||
| -rw-r--r-- | src/client/QXmppConfiguration.cpp | 22 | ||||
| -rw-r--r-- | src/client/QXmppConfiguration.h | 3 | ||||
| -rw-r--r-- | src/client/QXmppOutgoingClient.cpp | 5 | ||||
| -rw-r--r-- | tests/sasl.cpp | 22 | ||||
| -rw-r--r-- | tests/sasl.h | 1 |
8 files changed, 91 insertions, 3 deletions
@@ -9,6 +9,7 @@ QXmpp 0.7.1 (Sep 3, 2012) ------------------------- - Fix export of QXmppVCardPhone class. + - Add support for X-OAUTH2 authentication for Google Talk. QXmpp 0.7.0 (Sep 3, 2012) ------------------------- diff --git a/src/base/QXmppSasl.cpp b/src/base/QXmppSasl.cpp index 54683032..bf50eaa6 100644 --- a/src/base/QXmppSasl.cpp +++ b/src/base/QXmppSasl.cpp @@ -230,7 +230,7 @@ QXmppSaslClient::~QXmppSaslClient() QStringList QXmppSaslClient::availableMechanisms() { - return QStringList() << "PLAIN" << "DIGEST-MD5" << "ANONYMOUS" << "X-FACEBOOK-PLATFORM" << "X-MESSENGER-OAUTH2"; + return QStringList() << "PLAIN" << "DIGEST-MD5" << "ANONYMOUS" << "X-FACEBOOK-PLATFORM" << "X-MESSENGER-OAUTH2" << "X-OAUTH2"; } /// Creates an SASL client for the given mechanism. @@ -247,6 +247,8 @@ QXmppSaslClient* QXmppSaslClient::create(const QString &mechanism, QObject *pare return new QXmppSaslClientFacebook(parent); } else if (mechanism == "X-MESSENGER-OAUTH2") { return new QXmppSaslClientWindowsLive(parent); + } else if (mechanism == "X-OAUTH2") { + return new QXmppSaslClientGoogle(parent); } else { return 0; } @@ -456,6 +458,31 @@ bool QXmppSaslClientFacebook::respond(const QByteArray &challenge, QByteArray &r } } +QXmppSaslClientGoogle::QXmppSaslClientGoogle(QObject *parent) + : QXmppSaslClient(parent) + , m_step(0) +{ +} + +QString QXmppSaslClientGoogle::mechanism() const +{ + return "X-OAUTH2"; +} + +bool QXmppSaslClientGoogle::respond(const QByteArray &challenge, QByteArray &response) +{ + Q_UNUSED(challenge); + if (m_step == 0) { + // send initial response + response = QString('\0' + username() + '\0' + password()).toUtf8(); + m_step++; + return true; + } else { + warning("QXmppSaslClientGoogle : Invalid step"); + return false; + } +} + QXmppSaslClientPlain::QXmppSaslClientPlain(QObject *parent) : QXmppSaslClient(parent) , m_step(0) diff --git a/src/base/QXmppSasl_p.h b/src/base/QXmppSasl_p.h index 153c4544..8e596ffe 100644 --- a/src/base/QXmppSasl_p.h +++ b/src/base/QXmppSasl_p.h @@ -240,6 +240,17 @@ private: int m_step; }; +class QXmppSaslClientGoogle : public QXmppSaslClient +{ +public: + QXmppSaslClientGoogle(QObject *parent = 0); + QString mechanism() const; + bool respond(const QByteArray &challenge, QByteArray &response); + +private: + int m_step; +}; + class QXmppSaslClientPlain : public QXmppSaslClient { public: diff --git a/src/client/QXmppConfiguration.cpp b/src/client/QXmppConfiguration.cpp index d8a4b82e..31ebcd29 100644 --- a/src/client/QXmppConfiguration.cpp +++ b/src/client/QXmppConfiguration.cpp @@ -43,6 +43,9 @@ public: QString facebookAccessToken; QString facebookAppId; + // Google + QString googleAccessToken; + // Windows Live QString windowsLiveAccessToken; @@ -331,6 +334,25 @@ void QXmppConfiguration::setFacebookAppId(const QString& appId) d->facebookAppId = appId; } +/// Returns the access token used for X-OAUTH2 authentication. + +QString QXmppConfiguration::googleAccessToken() const +{ + return d->googleAccessToken; +} + +/// Sets the access token used for X-OAUTH2 authentication. +/// +/// This token is returned by Google at the end of the OAuth authentication +/// process. +/// +/// \param accessToken + +void QXmppConfiguration::setGoogleAccessToken(const QString& accessToken) +{ + d->googleAccessToken = accessToken; +} + /// Returns the access token used for X-MESSENGER-OAUTH2 authentication. QString QXmppConfiguration::windowsLiveAccessToken() const diff --git a/src/client/QXmppConfiguration.h b/src/client/QXmppConfiguration.h index 4a690edf..e7d01d3b 100644 --- a/src/client/QXmppConfiguration.h +++ b/src/client/QXmppConfiguration.h @@ -107,6 +107,9 @@ public: QString facebookAppId() const; void setFacebookAppId(const QString&); + QString googleAccessToken() const; + void setGoogleAccessToken(const QString &accessToken); + QString windowsLiveAccessToken() const; void setWindowsLiveAccessToken(const QString &accessToken); diff --git a/src/client/QXmppOutgoingClient.cpp b/src/client/QXmppOutgoingClient.cpp index 6f84d090..d6b41202 100644 --- a/src/client/QXmppOutgoingClient.cpp +++ b/src/client/QXmppOutgoingClient.cpp @@ -370,7 +370,7 @@ void QXmppOutgoingClient::handleStanza(const QDomElement &nodeRecv) if (saslAvailable && configuration().useSASLAuthentication()) { // supported and preferred SASL auth mechanisms - const QStringList supportedMechanisms = QXmppSaslClient::availableMechanisms(); + QStringList supportedMechanisms = QXmppSaslClient::availableMechanisms(); const QString preferredMechanism = configuration().saslAuthMechanism(); // determine SASL Authentication mechanism to use @@ -405,6 +405,9 @@ void QXmppOutgoingClient::handleStanza(const QDomElement &nodeRecv) d->saslClient->setPassword(configuration().facebookAccessToken()); } else if (d->saslClient->mechanism() == "X-MESSENGER-OAUTH2") { d->saslClient->setPassword(configuration().windowsLiveAccessToken()); + } else if (d->saslClient->mechanism() == "X-OAUTH2") { + d->saslClient->setUsername(configuration().user()); + d->saslClient->setPassword(configuration().googleAccessToken()); } else { d->saslClient->setUsername(configuration().user()); d->saslClient->setPassword(configuration().password()); diff --git a/tests/sasl.cpp b/tests/sasl.cpp index 7cf2097d..3df81e59 100644 --- a/tests/sasl.cpp +++ b/tests/sasl.cpp @@ -153,7 +153,7 @@ void tst_QXmppSasl::testSuccess() void tst_QXmppSaslClient::testAvailableMechanisms() { - QCOMPARE(QXmppSaslClient::availableMechanisms(), QStringList() << "PLAIN" << "DIGEST-MD5" << "ANONYMOUS" << "X-FACEBOOK-PLATFORM" << "X-MESSENGER-OAUTH2"); + QCOMPARE(QXmppSaslClient::availableMechanisms(), QStringList() << "PLAIN" << "DIGEST-MD5" << "ANONYMOUS" << "X-FACEBOOK-PLATFORM" << "X-MESSENGER-OAUTH2" << "X-OAUTH2"); } void tst_QXmppSaslClient::testBadMechanism() @@ -243,6 +243,26 @@ void tst_QXmppSaslClient::testFacebook() delete client; } +void tst_QXmppSaslClient::testGoogle() +{ + QXmppSaslClient *client = QXmppSaslClient::create("X-OAUTH2"); + QVERIFY(client != 0); + QCOMPARE(client->mechanism(), QLatin1String("X-OAUTH2")); + + client->setUsername("foo"); + client->setPassword("bar"); + + // initial step returns data + QByteArray response; + QVERIFY(client->respond(QByteArray(), response)); + QCOMPARE(response, QByteArray("\0foo\0bar", 8)); + + // any further step is an error + QVERIFY(!client->respond(QByteArray(), response)); + + delete client; +} + void tst_QXmppSaslClient::testPlain() { QXmppSaslClient *client = QXmppSaslClient::create("PLAIN"); diff --git a/tests/sasl.h b/tests/sasl.h index 69288b01..f70ff9af 100644 --- a/tests/sasl.h +++ b/tests/sasl.h @@ -50,6 +50,7 @@ private slots: void testDigestMd5(); void testDigestMd5_data(); void testFacebook(); + void testGoogle(); void testPlain(); void testWindowsLive(); }; |
