diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2011-12-13 15:50:59 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@accenture.com> | 2012-01-04 17:24:52 (GMT) |
commit | b6b862050039c53e5f9bb25b86047dd0335c0d81 (patch) | |
tree | 10f53844802933ef5763ef1d742d84943070bcf5 /tests | |
parent | 2997b89e6480abfed356fbd6fe248bc6d2accbe2 (diff) | |
download | Qt-b6b862050039c53e5f9bb25b86047dd0335c0d81.zip Qt-b6b862050039c53e5f9bb25b86047dd0335c0d81.tar.gz Qt-b6b862050039c53e5f9bb25b86047dd0335c0d81.tar.bz2 |
Test case for QTBUG-22875
Test the authentication cache works properly with "cancelled dialogs"
or if the user enters username/password incorrectly.
Expected behaviour is based on web browsers:
If cancelled, current request fails, and prompt again the next time.
If wrong password is given, prompt again and retry the current request.
If bad credentials are in the cache, prompt again
Task-number: QTBUG-22875
Change-Id: Ic02ccac8dbeb3f2580ca4ffe47d0773982c4ab25
Reviewed-by: Peter Hartmann <peter.hartmann@nokia.com>
(cherry picked from 4be2430)
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 371ac57..929917b 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -380,6 +380,8 @@ private Q_SLOTS: void httpAbort(); void dontInsertPartialContentIntoTheCache(); + void authenticationCacheAfterCancel_data(); + void authenticationCacheAfterCancel(); void synchronousAuthenticationCache(); void pipelining(); @@ -6026,6 +6028,189 @@ void tst_QNetworkReply::qtbug4121unknownAuthentication() QCOMPARE(reply->error(), QNetworkReply::AuthenticationRequiredError); } +void tst_QNetworkReply::authenticationCacheAfterCancel_data() +{ + QTest::addColumn<QNetworkProxy>("proxy"); + QTest::addColumn<bool>("proxyAuth"); + QTest::addColumn<QUrl>("url"); + for (int i = 0; i < proxies.count(); ++i) { + QTest::newRow("http" + proxies.at(i).tag) << proxies.at(i).proxy << proxies.at(i).requiresAuthentication << QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt"); +#ifndef QT_NO_OPENSSL + QTest::newRow("https" + proxies.at(i).tag) << proxies.at(i).proxy << proxies.at(i).requiresAuthentication << QUrl("https://" + QtNetworkSettings::serverName() + "/qtest/rfcs-auth/rfc3252.txt"); +#endif + } +} + +class AuthenticationCacheHelper : public QObject +{ + Q_OBJECT +public: + AuthenticationCacheHelper() + {} +public slots: + void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth) + { + if (!proxyPassword.isNull()) { + auth->setUser(proxyUserName); + auth->setPassword(proxyPassword); + //clear credentials, if they are asked again, they were bad + proxyUserName.clear(); + proxyPassword.clear(); + } + } + void authenticationRequired(QNetworkReply*,QAuthenticator *auth) + { + if (!httpPassword.isNull()) { + auth->setUser(httpUserName); + auth->setPassword(httpPassword); + //clear credentials, if they are asked again, they were bad + httpUserName.clear(); + httpPassword.clear(); + } + } +public: + QString httpUserName; + QString httpPassword; + QString proxyUserName; + QString proxyPassword; +}; + +/* Purpose of this test is to check credentials are cached correctly. + - If user cancels authentication dialog (i.e. nothing is set to the QAuthenticator by the callback) then this is not cached + - if user supplies a wrong password, then this is not cached + - if user supplies a correct user/password combination then this is cached + + Test is checking both the proxyAuthenticationRequired and authenticationRequired signals. + */ +void tst_QNetworkReply::authenticationCacheAfterCancel() +{ + QFETCH(QNetworkProxy, proxy); + QFETCH(bool, proxyAuth); + QFETCH(QUrl, url); + QNetworkAccessManager manager; +#ifndef QT_NO_OPENSSL + connect(&manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), + SLOT(sslErrors(QNetworkReply*,QList<QSslError>))); +#endif + manager.setProxy(proxy); + QSignalSpy authSpy(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*))); + QSignalSpy proxyAuthSpy(&manager, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *))); + + AuthenticationCacheHelper helper; + connect(&manager, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *)), &helper, SLOT(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *))); + connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), &helper, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); + + QNetworkRequest request(url); + QNetworkReplyPtr reply; + if (proxyAuth) { + //should fail due to no credentials + reply = manager.get(request); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->error(), QNetworkReply::ProxyAuthenticationRequiredError); + QCOMPARE(authSpy.count(), 0); + QCOMPARE(proxyAuthSpy.count(), 1); + proxyAuthSpy.clear(); + + //should fail due to bad credentials + helper.proxyUserName = "qsockstest"; + helper.proxyPassword = "badpassword"; + reply = manager.get(request); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QEXPECT_FAIL("http+socksauth", "QTBUG-23136 - danted accepts bad authentication but blocks the connection", Continue); + QEXPECT_FAIL("https+socksauth", "QTBUG-23136 - danted accepts bad authentication but blocks the connection", Continue); + + QCOMPARE(reply->error(), QNetworkReply::ProxyAuthenticationRequiredError); + QCOMPARE(authSpy.count(), 0); + QVERIFY(proxyAuthSpy.count() > 0); + proxyAuthSpy.clear(); + + //QTBUG-23136 workaround + if (proxy.port() == 1081) { +#ifdef QT_BUILD_INTERNAL + QNetworkAccessManagerPrivate::clearCache(&manager); +#else + return; //XFAIL result above +#endif + } + + //next proxy auth should succeed, due to correct credentials + helper.proxyUserName = "qsockstest"; + helper.proxyPassword = "password"; + } + + //should fail due to no credentials + reply = manager.get(request); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->error(), QNetworkReply::AuthenticationRequiredError); + QVERIFY(authSpy.count() > 0); + authSpy.clear(); + if (proxyAuth) { + QVERIFY(proxyAuthSpy.count() > 0); + proxyAuthSpy.clear(); + } + + //should fail due to bad credentials + helper.httpUserName = "baduser"; + helper.httpPassword = "badpassword"; + reply = manager.get(request); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->error(), QNetworkReply::AuthenticationRequiredError); + QVERIFY(authSpy.count() > 0); + authSpy.clear(); + if (proxyAuth) { + //should be supplied from cache + QCOMPARE(proxyAuthSpy.count(), 0); + proxyAuthSpy.clear(); + } + + //next auth should succeed, due to correct credentials + helper.httpUserName = "httptest"; + helper.httpPassword = "httptest"; + + reply = manager.get(request); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->error(), QNetworkReply::NoError); + QVERIFY(authSpy.count() > 0); + authSpy.clear(); + if (proxyAuth) { + //should be supplied from cache + QCOMPARE(proxyAuthSpy.count(), 0); + proxyAuthSpy.clear(); + } + + //next auth should use cached credentials + reply = manager.get(request); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(reply->error(), QNetworkReply::NoError); + //should be supplied from cache + QCOMPARE(authSpy.count(), 0); + authSpy.clear(); + if (proxyAuth) { + //should be supplied from cache + QCOMPARE(proxyAuthSpy.count(), 0); + proxyAuthSpy.clear(); + } + +} + class QtBug13431Helper : public QObject { Q_OBJECT public: |