From d9ea6936ab83b88f4bd3f93734119fdeb6018725 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 9 Apr 2015 13:38:52 +0200 Subject: [PATCH] Handle redirect of auth request. #3082 --- src/gui/owncloudsetupwizard.cpp | 54 ++++++++++++++++++++++++++++++--- src/gui/owncloudsetupwizard.h | 5 +-- src/libsync/networkjobs.h | 3 ++ 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/gui/owncloudsetupwizard.cpp b/src/gui/owncloudsetupwizard.cpp index 509b26293..4b06f2f1f 100644 --- a/src/gui/owncloudsetupwizard.cpp +++ b/src/gui/owncloudsetupwizard.cpp @@ -217,11 +217,53 @@ void OwncloudSetupWizard::testOwnCloudConnect() auto *job = new PropfindJob(account, "/", this); job->setIgnoreCredentialFailure(true); job->setProperties(QList() << "getlastmodified"); - connect(job, SIGNAL(result(QVariantMap)), _ocWizard, SLOT(successfulStep())); - connect(job, SIGNAL(networkError(QNetworkReply*)), this, SLOT(slotConnectionCheck(QNetworkReply*))); + connect(job, SIGNAL(result(QVariantMap)), _ocWizard, SLOT(successfulStep())); + connect(job, SIGNAL(finishedWithError()), this, SLOT(slotAuthError())); + connect(job, SIGNAL(networkError(QNetworkReply*)), this, SLOT(slotAuthNetworkError(QNetworkReply*))); job->start(); } +void OwncloudSetupWizard::slotAuthError() +{ + QString errorMsg; + + PropfindJob* job = qobject_cast(sender()); + if (!job) { + qWarning() << "Can't check for authed redirects. This slot should be invoked from PropfindJob!"; + return; + } + + // If there were redirects on the *authed* requests, also store + // the updated server URL, similar to redirects on status.php. + QUrl redirectUrl = job->reply()->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + if (!redirectUrl.isEmpty()) { + qDebug() << "authed request was redirected to" << redirectUrl.toString(); + + // strip the expected path + QString path = redirectUrl.path(); + static QString expectedPath = "/remote.php/webdav/"; + if (path.endsWith(expectedPath)) { + path.chop(expectedPath.size()); + redirectUrl.setPath(path); + + qDebug() << "setting account url to" << redirectUrl.toString(); + _ocWizard->account()->setUrl(redirectUrl); + testOwnCloudConnect(); + return; + } else { + errorMsg = tr("The authenticated request to the server was redirected to " + "'%1'. The URL is bad, the server is misconfigured.") + .arg(redirectUrl.toString()); + } + } + + if (errorMsg.isEmpty()) { + errorMsg = tr("There was an invalid response to an authenticated webdav request"); + } + _ocWizard->displayError(errorMsg, false); + _ocWizard->show(); +} + bool OwncloudSetupWizard::checkDowngradeAdvised(QNetworkReply* reply) { if(reply->url().scheme() != QLatin1String("https")) { @@ -245,7 +287,7 @@ bool OwncloudSetupWizard::checkDowngradeAdvised(QNetworkReply* reply) return true; } -void OwncloudSetupWizard::slotConnectionCheck(QNetworkReply* reply) +void OwncloudSetupWizard::slotAuthNetworkError(QNetworkReply* reply) { QString msg = reply->errorString(); switch (reply->error()) { @@ -294,7 +336,7 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFo } if (nextStep) { EntityExistsJob *job = new EntityExistsJob(_ocWizard->account(), _ocWizard->account()->davPath() + remoteFolder, this); - connect(job, SIGNAL(exists(QNetworkReply*)), SLOT(slotAuthCheckReply(QNetworkReply*))); + connect(job, SIGNAL(exists(QNetworkReply*)), SLOT(slotRemoteFolderExists(QNetworkReply*))); job->start(); } else { finalizeSetup( false ); @@ -302,7 +344,7 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString& localFo } // ### TODO move into EntityExistsJob once we decide if/how to return gui strings from jobs -void OwncloudSetupWizard::slotAuthCheckReply(QNetworkReply *reply) +void OwncloudSetupWizard::slotRemoteFolderExists(QNetworkReply *reply) { bool ok = true; QString error; @@ -522,8 +564,10 @@ bool DetermineAuthTypeJob::finished() } else if (redirection.toString().endsWith(account()->davPath())) { // do a new run _redirects++; + resetTimeout(); setReply(getRequest(redirection)); setupConnections(reply()); + return false; // don't discard } else { QRegExp shibbolethyWords("SAML|wayf"); diff --git a/src/gui/owncloudsetupwizard.h b/src/gui/owncloudsetupwizard.h index 961d63f00..9bbb69ddc 100644 --- a/src/gui/owncloudsetupwizard.h +++ b/src/gui/owncloudsetupwizard.h @@ -62,10 +62,11 @@ private slots: void slotNoOwnCloudFoundAuthTimeout(const QUrl&url); void slotConnectToOCUrl(const QString&); - void slotConnectionCheck(QNetworkReply*); + void slotAuthNetworkError(QNetworkReply*); + void slotAuthError(); void slotCreateLocalAndRemoteFolders(const QString&, const QString&); - void slotAuthCheckReply(QNetworkReply*); + void slotRemoteFolderExists(QNetworkReply*); void slotCreateRemoteFolderFinished(QNetworkReply::NetworkError); void slotAssistantFinished( int ); void slotSkipFolderConfiguration(); diff --git a/src/libsync/networkjobs.h b/src/libsync/networkjobs.h index 155e5195a..13f966516 100644 --- a/src/libsync/networkjobs.h +++ b/src/libsync/networkjobs.h @@ -94,6 +94,9 @@ protected: QElapsedTimer _durationTimer; quint64 _duration; bool _timedout; // set to true when the timeout slot is recieved + + // Automatically follows redirects. Note that this only works for + // GET requests that don't set up any HTTP body or other flags. bool _followRedirects; private slots: -- 2.30.2