Commit b4aeee76 authored by Jesus Fernandez's avatar Jesus Fernandez

Added QOAuth1Signature

parent b069ade1
......@@ -13,25 +13,31 @@ QT += core core-private network
DEFINES += OAUTH_LIBRARY
# Input
HEADERS += qabstractoauth.h \
HEADERS += \
qoauth1.h \
qabstractoauth.h \
qabstractoauth2.h \
private/qabstractoauth2_p.h \
private/qabstractoauth_p.h \
qoauth1signature.h \
qoauthoobreplyhandler.h \
qoauth2implicitgrantflow.h \
qabstractoauthreplyhandler.h \
qoauth1.h \
private/qoauth1_p.h \
qoauth2authorizationcodeflow.h \
private/qoauth2authorizationcodeflow_p.h \
qoauth2implicitgrantflow.h \
private/qoauth2implicitgrantflow_p.h \
qoauthhttpserverreplyhandler.h \
private/qoauth1_p.h \
private/qabstractoauth_p.h \
private/qabstractoauth2_p.h \
private/qoauth1signature_p.h \
private/qoauth2implicitgrantflow_p.h \
private/qoauthhttpserverreplyhandler_p.h \
qoauthoobreplyhandler.h
SOURCES += qabstractoauth.cpp \
private/qoauth2authorizationcodeflow_p.h
SOURCES += \
qoauth1.cpp \
qabstractoauth.cpp \
qabstractoauth2.cpp \
qoauth1signature.cpp \
qoauthoobreplyhandler.cpp \
qoauth2implicitgrantflow.cpp \
qabstractoauthreplyhandler.cpp \
qoauth1.cpp \
qoauth2authorizationcodeflow.cpp \
qoauth2implicitgrantflow.cpp \
qoauthhttpserverreplyhandler.cpp \
qoauthoobreplyhandler.cpp
qoauthhttpserverreplyhandler.cpp
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QOAUTH1SIGNATURE_P_H
#define QOAUTH1SIGNATURE_P_H
#include <QtOAuth/qoauth1signature.h>
class QOAuth1SignaturePrivate
{
public:
QByteArray signatureBaseString(const QOAuth1Signature &instance);
QByteArray secret() const;
static QByteArray parameterString(const QVariantMap &parameters);
static QByteArray encodeHeaders(const QVariantMap &headers);
QOAuth1Signature::HttpRequestMethod method = QOAuth1Signature::HttpRequestMethod::Post;
QUrl url;
QString clientSharedKey;
QString tokenSecret;
};
#endif // QOAUTH1SIGNATURE_P_H
......@@ -42,6 +42,7 @@
#include <qoauth1.h>
#include <private/qoauth1_p.h>
#include <qoauthoobreplyhandler.h>
#include <private/qoauth1signature_p.h>
#include <qoauthhttpserverreplyhandler.h>
#include <QtCore/qmap.h>
......@@ -543,14 +544,16 @@ QByteArray QOAuth1::generateSignature(const QVariantMap &parameters,
{
Q_D(QOAuth1);
QByteArray ret;
if (signatureMethod() == SignatureMethod::Hmac_Sha1) {
ret = signature(parameters, url, operation, d->clientCredentials.second,
d->tokenCredentials.second);
} else if (signatureMethod() == SignatureMethod::PlainText) {
ret.append(d->clientCredentials.first.toUtf8());
ret.append('&');
ret.append(d->clientCredentials.second.toUtf8());
}
const QOAuth1Signature signature(url,
d->clientCredentials.second,
d->tokenCredentials.second,
static_cast<QOAuth1Signature::HttpRequestMethod>(operation),
parameters);
if (signatureMethod() == SignatureMethod::Hmac_Sha1)
ret = signature.hmacSha1().toBase64();
else if (signatureMethod() == SignatureMethod::PlainText)
ret = signature.plainText(d->clientCredentials.first);
return ret;
}
......@@ -618,23 +621,6 @@ QMap<QString, QString> QOAuth1::parseResponse(const QByteArray &response)
return ret;
}
QByteArray QOAuth1::parameterString(const QVariantMap &parameters)
{
QByteArray ret;
auto previous = parameters.end();
for (auto it = parameters.begin(), end = parameters.end(); it != end; previous = it++) {
if (previous != parameters.end()) {
if (Q_UNLIKELY(previous.key() == it.key()))
qWarning("QOAuth: duplicated key %s", qPrintable(it.key()));
ret.append("&");
}
ret.append(QUrl::toPercentEncoding(it.key()));
ret.append("=");
ret.append(QUrl::toPercentEncoding(it.value().toString()));
}
return ret;
}
QByteArray QOAuth1::nonce()
{
// https://tools.ietf.org/html/rfc5849#section-3.3
......@@ -643,48 +629,15 @@ QByteArray QOAuth1::nonce()
return u.toUtf8();
}
QByteArray QOAuth1::signatureBaseString(const QVariantMap &parameters,
const QUrl &url,
QNetworkAccessManager::Operation op)
{
// https://tools.ietf.org/html/rfc5849#section-3.4.1
QByteArray base;
base.append(QOAuth1Private::operationName(op).toUtf8() + "&");
base.append(QUrl::toPercentEncoding(url.toString(QUrl::RemoveQuery)) + "&");
QVariantMap queryParameters;
{
const auto queryItems = QUrlQuery(url.query()).queryItems();
for (auto it = queryItems.begin(), end = queryItems.end(); it != end; ++it)
queryParameters.insert(it->first, it->second);
}
base.append(encodeHeaders(QVariantMap(parameters).unite(queryParameters)));
return base;
}
QByteArray QOAuth1::encodeHeaders(const QVariantMap &headers)
{
return QUrl::toPercentEncoding(QString::fromLatin1(parameterString(headers)));
}
QByteArray QOAuth1::signature(const QVariantMap &parameters,
const QUrl &url,
QNetworkAccessManager::Operation op,
const QString &consumerSecret,
const QString &tokenSecret)
{
// https://tools.ietf.org/html/rfc5849#section-3.4
const QByteArray baseString = signatureBaseString(parameters, url, op);
QByteArray secret;
secret.append(QUrl::toPercentEncoding(consumerSecret));
secret.append('&');
secret.append(QUrl::toPercentEncoding(tokenSecret));
const QByteArray hash = QMessageAuthenticationCode::hash(baseString, secret,
QCryptographicHash::Sha1);
return hash.toBase64();
auto method = static_cast<QOAuth1Signature::HttpRequestMethod>(op);
QOAuth1Signature signature(url, consumerSecret, tokenSecret, method, parameters);
return signature.hmacSha1().toBase64();
}
QByteArray QOAuth1::generateAuthorizationHeader(const QVariantMap &oauthParams)
......
......@@ -141,15 +141,9 @@ protected:
QNetworkAccessManager::Operation operation);
static QMap<QString, QString> parseResponse(const QByteArray &response);
static QByteArray parameterString(const QVariantMap &parameters);
// Nonce: https://tools.ietf.org/html/rfc5849#section-3.3
static QByteArray nonce();
static QByteArray encodeHeaders(const QVariantMap &headers);
static QByteArray generateAuthorizationHeader(const QVariantMap &oauthParams);
// Signature Base String: https://tools.ietf.org/html/rfc5849#section-3.4.1
static QByteArray signatureBaseString(const QVariantMap &parameters,
const QUrl &url,
QNetworkAccessManager::Operation op);
// Signature: https://tools.ietf.org/html/rfc5849#section-3.4
static QByteArray signature(const QVariantMap &parameters,
const QUrl &url,
......
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qoauth1signature.h"
#include <QtCore/qdebug.h>
#include <QtCore/qurlquery.h>
#include <QtCore/qmessageauthenticationcode.h>
#include <QtNetwork/qnetworkaccessmanager.h>
#include "private/qoauth1signature_p.h"
#include <functional>
#include <type_traits>
static_assert(static_cast<int>(QOAuth1Signature::HttpRequestMethod::Head) ==
static_cast<int>(QNetworkAccessManager::HeadOperation) &&
static_cast<int>(QOAuth1Signature::HttpRequestMethod::Get) ==
static_cast<int>(QNetworkAccessManager::GetOperation) &&
static_cast<int>(QOAuth1Signature::HttpRequestMethod::Put) ==
static_cast<int>(QNetworkAccessManager::PutOperation) &&
static_cast<int>(QOAuth1Signature::HttpRequestMethod::Post) ==
static_cast<int>(QNetworkAccessManager::PostOperation) &&
static_cast<int>(QOAuth1Signature::HttpRequestMethod::Delete) ==
static_cast<int>(QNetworkAccessManager::DeleteOperation),
"Invalid QOAuth1Signature::HttpRequestMethod enumeration values");
inline static QOAuth1SignaturePrivate *d_ptr(
const QScopedPointer<QOAuth1SignaturePrivate> *instance)
{
auto casted = const_cast<QScopedPointer<QOAuth1SignaturePrivate> *>(instance);
if (casted->isNull())
casted->reset(new QOAuth1SignaturePrivate);
return casted->data();
}
QByteArray QOAuth1SignaturePrivate::signatureBaseString(const QOAuth1Signature &instance)
{
// https://tools.ietf.org/html/rfc5849#section-3.4.1
QByteArray base;
switch (method) {
case QOAuth1Signature::HttpRequestMethod::Head:
base.append("HEAD");
break;
case QOAuth1Signature::HttpRequestMethod::Get:
base.append("GET");
break;
case QOAuth1Signature::HttpRequestMethod::Put:
base.append("PUT");
break;
case QOAuth1Signature::HttpRequestMethod::Post:
base.append("POST");
break;
case QOAuth1Signature::HttpRequestMethod::Delete:
base.append("DELETE");
break;
default:
qCritical("QOAuth1Signature: HttpRequestMethod not supported");
}
base.append('&');
base.append(QUrl::toPercentEncoding(url.toString(QUrl::RemoveQuery)) + "&");
QVariantMap parameters = instance;
{
const auto queryItems = QUrlQuery(url.query()).queryItems();
for (auto it = queryItems.begin(), end = queryItems.end(); it != end; ++it)
parameters.insert(it->first, it->second);
}
base.append(encodeHeaders(parameters));
return base;
}
QByteArray QOAuth1SignaturePrivate::secret() const
{
QByteArray secret;
secret.append(QUrl::toPercentEncoding(clientSharedKey));
secret.append('&');
secret.append(QUrl::toPercentEncoding(tokenSecret));
return secret;
}
QByteArray QOAuth1SignaturePrivate::parameterString(const QVariantMap &parameters)
{
QByteArray ret;
auto previous = parameters.end();
for (auto it = parameters.begin(), end = parameters.end(); it != end; previous = it++) {
if (previous != parameters.end()) {
if (Q_UNLIKELY(previous.key() == it.key()))
qWarning("QOAuth: duplicated key %s", qPrintable(it.key()));
ret.append("&");
}
ret.append(QUrl::toPercentEncoding(it.key()));
ret.append("=");
ret.append(QUrl::toPercentEncoding(it.value().toString()));
}
return ret;
}
QByteArray QOAuth1SignaturePrivate::encodeHeaders(const QVariantMap &headers)
{
return QUrl::toPercentEncoding(QString::fromLatin1(parameterString(headers)));
}
QOAuth1Signature::QOAuth1Signature(const QUrl &url, QOAuth1Signature::HttpRequestMethod method,
const QVariantMap &parameters) : QVariantMap(parameters)
{
d_ptr(&d)->url = url;
d_ptr(&d)->method = method;
}
QOAuth1Signature::QOAuth1Signature(const QUrl &url, const QString &clientSharedKey,
const QString &tokenSecret, HttpRequestMethod method,
const QVariantMap &parameters) : QVariantMap(parameters)
{
d_ptr(&d)->url = url;
d_ptr(&d)->method = method;
d_ptr(&d)->clientSharedKey = clientSharedKey;
d_ptr(&d)->tokenSecret = tokenSecret;
}
QOAuth1Signature::~QOAuth1Signature()
{}
QOAuth1Signature::HttpRequestMethod QOAuth1Signature::httpRequestMethod() const
{
return d_ptr(&d)->method;
}
void QOAuth1Signature::setHttpRequestMethod(QOAuth1Signature::HttpRequestMethod method)
{
d_ptr(&d)->method = method;
}
QUrl QOAuth1Signature::url() const
{
return d_ptr(&d)->url;
}
void QOAuth1Signature::setUrl(const QUrl &url)
{
d_ptr(&d)->url = url;
}
QVariantMap QOAuth1Signature::parameters() const
{
return *this;
}
void QOAuth1Signature::setParameters(const QVariantMap &parameters)
{
static_cast<QVariantMap&>(*this) = parameters;
}
void QOAuth1Signature::addRequestBody(const QUrlQuery &body)
{
const auto list = body.queryItems();
for (auto it = list.begin(), end = list.end(); it != end; ++it)
insert(it->first, it->second);
}
QString QOAuth1Signature::clientSharedKey() const
{
return d_ptr(&d)->clientSharedKey;
}
void QOAuth1Signature::setClientSharedKey(const QString &secret)
{
d_ptr(&d)->clientSharedKey = secret;
}
QString QOAuth1Signature::tokenSecret() const
{
return d_ptr(&d)->tokenSecret;
}
void QOAuth1Signature::setTokenSecret(const QString &secret)
{
d_ptr(&d)->tokenSecret = secret;
}
QByteArray QOAuth1Signature::hmacSha1() const
{
const auto priv = d_ptr(&d);
QMessageAuthenticationCode code(QCryptographicHash::Sha1);
code.setKey(priv->secret());
code.addData(priv->signatureBaseString(*this));
return code.result();
}
QByteArray QOAuth1Signature::rsaSha1() const
{
qCritical("QOAuth1Signature::rsaSha1: RSA-SHA1 signing method not supported");
return QByteArray();
}
QByteArray QOAuth1Signature::plainText(const QString &clientIdentifier) const
{
QByteArray ret;
ret.append(clientIdentifier.toUtf8());
ret.append('&');
ret.append(d_ptr(&d)->clientSharedKey.toUtf8());
return ret;
}
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QOAUTH1SIGNATURE_H
#define QOAUTH1SIGNATURE_H
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>
class QOAuth1SignaturePrivate;
class QOAuth1Signature : public QVariantMap
{
public:
enum class HttpRequestMethod {
Head = 1,
Get,
Put,
Post,
Delete,
Custom,
Unknown = 0
};
using QVariantMap::QVariantMap;
explicit QOAuth1Signature(const QUrl &url, HttpRequestMethod method = HttpRequestMethod::Post,
const QVariantMap &parameters = QVariantMap());
QOAuth1Signature(const QUrl &url, const QString &clientSharedKey, const QString &tokenSecret,
HttpRequestMethod method = HttpRequestMethod::Post,
const QVariantMap &parameters = QVariantMap());
~QOAuth1Signature();
HttpRequestMethod httpRequestMethod() const;
void setHttpRequestMethod(HttpRequestMethod method);
QUrl url() const;
void setUrl(const QUrl &url);
QVariantMap parameters() const;
void setParameters(const QVariantMap &parameters);
void addRequestBody(const QUrlQuery &body);
QString clientSharedKey() const;
void setClientSharedKey(const QString &secret);
QString tokenSecret() const;
void setTokenSecret(const QString &secret);
QByteArray hmacSha1() const;
QByteArray rsaSha1() const;
QByteArray plainText(const QString &clientIdentifier) const;
private:
friend class QOAuth1SignaturePrivate;
QScopedPointer<QOAuth1SignaturePrivate> d;
};
#endif // QOAUTH1SIGNATURE_H
......@@ -32,6 +32,7 @@
#include <QtOAuth/qoauth1.h>
#include <QtOAuth/qabstractoauth.h>
#include <QtOAuth/qoauth1signature.h>
#include <QtOAuth/private/qoauth1_p.h>
#include <QtOAuth/private/qabstractoauth_p.h>
......@@ -76,7 +77,7 @@ public Q_SLOTS:
void gotError();
private Q_SLOTS:
void createSignature();
void signature();
void getToken_data();
void getToken();
......@@ -184,80 +185,32 @@ void tst_QOAuth::gotError()
disconnect(QObject::sender(), SIGNAL(finished()), this, 0);
}
void tst_QOAuth::createSignature()
void tst_QOAuth::signature()
{
// Example from https://dev.twitter.com/oauth/overview/creating-signatures
QByteArray parameterString, signatureBase, signature;
const QUrl url("https://api.twitter.com/1/statuses/update.json?include_entities=true");
QOAuth1Signature signature(url,
QStringLiteral("kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw"),
QStringLiteral("LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE"),
QOAuth1Signature::HttpRequestMethod::Post);
QString body = QUrl::fromPercentEncoding("status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20"
"signed%20OAuth%20request%21");
const QUrl url(QStringLiteral("https://api.twitter.com/1/statuses/update.json?include_entities=true"));
const QString data = QUrl::fromPercentEncoding("status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21");
const auto consumerSecret = QStringLiteral("kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw");
const auto oauthTokenSecret = QStringLiteral("LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE");
QNetworkAccessManager::Operation operation = QNetworkAccessManager::PostOperation;
QVariantMap oauthParams;
oauthParams.insert(QStringLiteral("oauth_consumer_key"),
signature.insert(QStringLiteral("oauth_consumer_key"),
QStringLiteral("xvz1evFS4wEEPTGEFPHBog"));
oauthParams.insert(QStringLiteral("oauth_nonce"),
signature.insert(QStringLiteral("oauth_nonce"),
QStringLiteral("kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg"));
oauthParams.insert(QStringLiteral("oauth_signature_method"),
signature.insert(QStringLiteral("oauth_signature_method"),
QStringLiteral("HMAC-SHA1"));
oauthParams.insert(QStringLiteral("oauth_timestamp"), QStringLiteral("1318622958"));
oauthParams.insert(QStringLiteral("oauth_token"),
signature.insert(QStringLiteral("oauth_timestamp"), QStringLiteral("1318622958"));
signature.insert(QStringLiteral("oauth_token"),
QStringLiteral("370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb"));
oauthParams.insert(QStringLiteral("oauth_version"), QStringLiteral("1.0"));
QVariantMap otherParametersFromData;
fillParameters(&otherParametersFromData, QUrlQuery(data));
// HTTP Method
QCOMPARE(QOAuth1Private::operationName(operation), QStringLiteral("POST"));
// Base URL
QCOMPARE(url.toString(QUrl::RemoveQuery),
QStringLiteral("https://api.twitter.com/1/statuses/update.json"));
struct OAuthSubClass : QOAuth1 {
using QOAuth1::parameterString;
using QOAuth1::signatureBaseString;
using QOAuth1::signature;
};
// Creating parameter string
{
QVariantMap parameters = oauthParams;
parameters.unite(otherParametersFromData);
fillParameters(&parameters, QUrlQuery(url.query()));
parameterString = OAuthSubClass::parameterString(parameters);
parameters.insertMulti(parameters.keys().first(), QString());
QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^QOAuth: duplicated key .*$"));
OAuthSubClass::parameterString(parameters);
}
signature.insert(QStringLiteral("oauth_version"), QStringLiteral("1.0"));
signature.addRequestBody(QUrlQuery(body));
QCOMPARE(parameterString, QByteArray("include_entities=true"
"&oauth_consumer_key=xvz1evFS4wEEPTGEFPHBog"
"&oauth_nonce=kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg"
"&oauth_signature_method=HMAC-SHA1"
"&oauth_timestamp=1318622958"
"&oauth_token=370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb"
"&oauth_version=1.0"
"&status=Hello%20Ladies%20%2B%20Gentlemen%2C%20a%20signed%20OAuth%20request%21"));
// Collecting parameters
oauthParams.unite(otherParametersFromData);
signatureBase = OAuthSubClass::signatureBaseString(oauthParams, url, operation);
QCOMPARE(signatureBase, QByteArray("POST&https%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.json"
"&include_entities%3Dtrue%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog"
"%26oauth_nonce%3DkYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg"
"%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1318622958"
"%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb"
"%26oauth_version%3D1.0%26status%3DHello%2520Ladies%2520%252B%2520Gentlemen%252C%2520a%2520signed%2520OAuth%2520request%2521"));
// Getting a signing key
signature = OAuthSubClass::signature(oauthParams, url, operation, consumerSecret, oauthTokenSecret);
QCOMPARE(signature, QByteArray("tnnArxj06cWHq44gCs1OSKk/jLY="));
QByteArray signatureData = signature.hmacSha1();
QCOMPARE(signatureData.toBase64(), QByteArray("tnnArxj06cWHq44gCs1OSKk/jLY="));
}
void tst_QOAuth::getToken_data()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment