summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2011-12-13 15:50:59 +0000
committerQt by Nokia <qt-info@nokia.com>2011-12-22 06:02:32 +0100
commit4be2430925e04db1a998a11c1c281ae578feca4b (patch)
tree9ccfd6c8f5ac8be2a49867774640497ef44f38f3
parentd62228a77e3f4990623636519836874a66baffbb (diff)
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>
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp189
1 files changed, 188 insertions, 1 deletions
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index e900a25264..cc520a620a 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -73,7 +73,9 @@
#include <QtNetwork/qnetworkconfiguration.h>
#include <QtNetwork/qnetworksession.h>
#endif
-
+#ifdef QT_BUILD_INTERNAL
+#include <QtNetwork/private/qnetworkaccessmanager_p.h>
+#endif
#include <time.h>
#include "../../../network-settings.h"
@@ -378,6 +380,8 @@ private Q_SLOTS:
void dontInsertPartialContentIntoTheCache();
void httpUserAgent();
+ void authenticationCacheAfterCancel_data();
+ void authenticationCacheAfterCancel();
void synchronousAuthenticationCache();
// NOTE: This test must be last!
@@ -6025,6 +6029,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: