1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtCore>
30#include <QtTest>
31
32#include <QtNetworkAuth/qoauth1signature.h>
33
34Q_DECLARE_METATYPE(QOAuth1Signature::HttpRequestMethod)
35
36class tst_OAuth1Signature : public QObject
37{
38 Q_OBJECT
39
40public:
41 QOAuth1Signature createTwitterSignature();
42
43private Q_SLOTS:
44 void twitterSignatureExample();
45 void copyAndModify();
46
47 void signatures_data();
48 void signatures();
49};
50
51const auto oauthVersion = QStringLiteral("oauth_version");
52const auto oauthConsumerKey = QStringLiteral("oauth_consumer_key");
53const auto oauthNonce = QStringLiteral("oauth_nonce");
54const auto oauthSignatureMethod = QStringLiteral("oauth_signature_method");
55const auto oauthTimestamp = QStringLiteral("oauth_timestamp");
56const auto oauthToken = QStringLiteral("oauth_token");
57
58QOAuth1Signature tst_OAuth1Signature::createTwitterSignature()
59{
60 // Example from https://dev.twitter.com/oauth/overview/creating-signatures
61
62 const QUrl url("https://api.twitter.com/1/statuses/update.json?include_entities=true");
63 QOAuth1Signature signature(url,
64 QStringLiteral("kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw"),
65 QStringLiteral("LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE"),
66 QOAuth1Signature::HttpRequestMethod::Post);
67 const QString body = QUrl::fromPercentEncoding("status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a"
68 "%20signed%20OAuth%20request%21");
69
70 signature.insert(key: oauthConsumerKey,
71 QStringLiteral("xvz1evFS4wEEPTGEFPHBog"));
72 signature.insert(key: oauthNonce,
73 QStringLiteral("kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg"));
74 signature.insert(key: oauthSignatureMethod,
75 QStringLiteral("HMAC-SHA1"));
76 signature.insert(key: oauthTimestamp, QStringLiteral("1318622958"));
77 signature.insert(key: oauthToken,
78 QStringLiteral("370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb"));
79 signature.insert(key: oauthVersion, QStringLiteral("1.0"));
80 signature.addRequestBody(body: QUrlQuery(body));
81 return signature;
82}
83
84void tst_OAuth1Signature::twitterSignatureExample()
85{
86 const QOAuth1Signature signature = createTwitterSignature();
87 QByteArray signatureData = signature.hmacSha1();
88 QCOMPARE(signatureData.toBase64(), QByteArray("tnnArxj06cWHq44gCs1OSKk/jLY="));
89}
90
91void tst_OAuth1Signature::copyAndModify()
92{
93 const QOAuth1Signature signature = createTwitterSignature();
94 QOAuth1Signature copy = signature;
95 QCOMPARE(signature.hmacSha1(), copy.hmacSha1());
96 copy.insert(QStringLiteral("signature"), QStringLiteral("modified"));
97 QVERIFY(signature.hmacSha1() != copy.hmacSha1());
98}
99
100void tst_OAuth1Signature::signatures_data()
101{
102 QTest::addColumn<QUrl>(name: "url");
103 QTest::addColumn<QOAuth1Signature::HttpRequestMethod>(name: "method");
104 QTest::addColumn<QByteArray>(name: "customVerb");
105 QTest::addColumn<QString>(name: "version");
106 QTest::addColumn<QString>(name: "consumerKey");
107 QTest::addColumn<QString>(name: "consumerSecret");
108 QTest::addColumn<QString>(name: "token");
109 QTest::addColumn<QString>(name: "tokenSecret");
110 QTest::addColumn<QString>(name: "nonce");
111 QTest::addColumn<QString>(name: "timestamp");
112 QTest::addColumn<QVariantMap>(name: "parameters");
113 QTest::addColumn<QString>(name: "result");
114
115 QTest::newRow(dataTag: "standard") << QUrl("http://example.net")
116 << QOAuth1Signature::HttpRequestMethod::Get
117 << QByteArray()
118 << "1.0"
119 << "key"
120 << "secret"
121 << "accesskey"
122 << "accesssecret"
123 << "468167367"
124 << "1494852816"
125 << QVariantMap()
126 << "mQaARxv7pqJyViuwNGtUfm6QSIQ=";
127 QTest::newRow(dataTag: "post") << QUrl("http://example.net")
128 << QOAuth1Signature::HttpRequestMethod::Post
129 << QByteArray()
130 << "1.0"
131 << "key"
132 << "secret"
133 << "accesskey"
134 << "accesssecret"
135 << "468167367"
136 << "1494852816"
137 << QVariantMap()
138 << "L4blJKqYMTSNUEt32rCgDLhxQxM=";
139 QTest::newRow(dataTag: "put") << QUrl("http://example.net")
140 << QOAuth1Signature::HttpRequestMethod::Put
141 << QByteArray()
142 << "1.0"
143 << "key"
144 << "secret"
145 << "accesskey"
146 << "accesssecret"
147 << "468167367"
148 << "1494852816"
149 << QVariantMap()
150 << "+eiZ+phNoYnETf6SqI+XSE43JSY=";
151 QTest::newRow(dataTag: "delete") << QUrl("http://example.net")
152 << QOAuth1Signature::HttpRequestMethod::Delete
153 << QByteArray()
154 << "1.0"
155 << "key"
156 << "secret"
157 << "accesskey"
158 << "accesssecret"
159 << "468167367"
160 << "1494852816"
161 << QVariantMap()
162 << "enbOVNG7/vGliie2/L44NdccMaw=";
163 QTest::newRow(dataTag: "head") << QUrl("http://example.net")
164 << QOAuth1Signature::HttpRequestMethod::Head
165 << QByteArray()
166 << "1.0"
167 << "key"
168 << "secret"
169 << "accesskey"
170 << "accesssecret"
171 << "468167367"
172 << "1494852816"
173 << QVariantMap()
174 << "6v74w0rRsVibJsJ796Nj8cJPqEU=";
175 QTest::newRow(dataTag: "no-hmac-key") << QUrl("http://example.net")
176 << QOAuth1Signature::HttpRequestMethod::Get
177 << QByteArray()
178 << "1.0"
179 << "key"
180 << QString()
181 << "accesskey"
182 << QString()
183 << "468167367"
184 << "1494852816"
185 << QVariantMap()
186 << "N2qP+LJdLbjalZq71M7oxPdeUjc=";
187 QTest::newRow(dataTag: "custom-values") << QUrl("http://example.net")
188 << QOAuth1Signature::HttpRequestMethod::Get
189 << QByteArray()
190 << "1.0"
191 << "key"
192 << "secret"
193 << "accesskey"
194 << "accesssecret"
195 << "468167367"
196 << "1494852816"
197 << QVariantMap {
198 { "firstKey", "firstValue" },
199 { "secondKey", "secondValue" }
200 }
201 << "xNXgQaO0LrQMbJZGSfKFUmWwGDw=";
202 QTest::newRow(dataTag: "custom-verb-get") << QUrl("http://example.net")
203 << QOAuth1Signature::HttpRequestMethod::Custom
204 << QByteArray("GET")
205 << "1.0"
206 << "key"
207 << "secret"
208 << "accesskey"
209 << "accesssecret"
210 << "468167367"
211 << "1494852816"
212 << QVariantMap()
213 << "mQaARxv7pqJyViuwNGtUfm6QSIQ=";
214 QTest::newRow(dataTag: "custom-verb-patch") << QUrl("http://example.net")
215 << QOAuth1Signature::HttpRequestMethod::Custom
216 << QByteArray("PATCH")
217 << "1.0"
218 << "key"
219 << "secret"
220 << "accesskey"
221 << "accesssecret"
222 << "468167367"
223 << "1494852816"
224 << QVariantMap()
225 << "kcRO68D7IBQWlQvUR/jkhuF8AKM=";
226}
227
228void tst_OAuth1Signature::signatures()
229{
230 // Should match the reference implementation at
231 // http://bettiolo.github.io/oauth-reference-page/
232
233 QFETCH(QUrl, url);
234 QFETCH(QOAuth1Signature::HttpRequestMethod, method);
235 QFETCH(QByteArray, customVerb);
236 QFETCH(QString, version);
237 QFETCH(QString, consumerKey);
238 QFETCH(QString, consumerSecret);
239 QFETCH(QString, token);
240 QFETCH(QString, tokenSecret);
241 QFETCH(QString, nonce);
242 QFETCH(QString, timestamp);
243 QFETCH(QVariantMap, parameters);
244 QFETCH(QString, result);
245
246 parameters.insert(akey: oauthVersion, avalue: version);
247 parameters.insert(akey: oauthConsumerKey, avalue: consumerKey);
248 parameters.insert(akey: oauthNonce, avalue: nonce);
249 parameters.insert(akey: oauthSignatureMethod, avalue: "HMAC-SHA1");
250 parameters.insert(akey: oauthTimestamp, avalue: timestamp);
251 parameters.insert(akey: oauthToken, avalue: token);
252
253 QOAuth1Signature signature(url, consumerSecret, tokenSecret, method, parameters);
254 if (method == QOAuth1Signature::HttpRequestMethod::Custom)
255 signature.setCustomMethodString(customVerb);
256 const auto signatureData = signature.hmacSha1();
257 QCOMPARE(signatureData.toBase64(), result);
258}
259
260QTEST_MAIN(tst_OAuth1Signature)
261#include "tst_oauth1signature.moc"
262

source code of qtnetworkauth/tests/auto/oauth1signature/tst_oauth1signature.cpp