Skip to content

Commit 815a59a

Browse files
authored
Merge pull request #9247 from nextcloud/bugfix/noid/qt6-redirects
fix(accessmanager): manually handle redirects
2 parents 24cacda + 585b6ca commit 815a59a

11 files changed

+168
-12
lines changed

src/gui/creds/webflowcredentials.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class WebFlowCredentialsAccessManager : public AccessManager
5252
QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) override
5353
{
5454
QNetworkRequest req(request);
55-
if (!req.attribute(WebFlowCredentials::DontAddCredentialsAttribute).toBool()) {
55+
if (!req.attribute(AbstractCredentials::DontAddCredentialsAttribute).toBool()) {
5656
if (_cred && !_cred->password().isEmpty()) {
5757
QByteArray credHash = QByteArray(_cred->user().toUtf8() + ":" + _cred->password().toUtf8()).toBase64();
5858
req.setRawHeader("Authorization", "Basic " + credHash);

src/gui/creds/webflowcredentials.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ class WebFlowCredentials : public AbstractCredentials
3737
friend class WebFlowCredentialsAccessManager;
3838

3939
public:
40-
/// Don't add credentials if this is set on a QNetworkRequest
41-
static constexpr QNetworkRequest::Attribute DontAddCredentialsAttribute = QNetworkRequest::User;
42-
4340
explicit WebFlowCredentials();
4441
WebFlowCredentials(
4542
const QString &user,

src/libsync/abstractnetworkjob.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,24 @@ void AbstractNetworkJob::slotFinished()
273273
}
274274
_requestBody->seek(0);
275275
}
276+
277+
auto request = reply()->request();
278+
279+
if (!(requestedUrl.host() == redirectUrl.host() && requestedUrl.port() == redirectUrl.port())) {
280+
qCWarning(lcNetworkJob).nospace() << "redirect target mismatches origin, removing credentials"
281+
<< " origin=" << requestedUrl.host() << ":" << requestedUrl.port()
282+
<< " target=" << redirectUrl.host() << ":" << redirectUrl.port();
283+
284+
auto headers = request.headers();
285+
headers.removeAll(QHttpHeaders::WellKnownHeader::Authorization);
286+
request.setHeaders(headers);
287+
request.setAttribute(AbstractCredentials::DontAddCredentialsAttribute, true);
288+
}
289+
276290
sendRequest(
277291
verb,
278292
redirectUrl,
279-
reply()->request(),
293+
request,
280294
_requestBody);
281295
return;
282296
}

src/libsync/accessmanager.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ QNetworkReply *AccessManager::createRequest(QNetworkAccessManager::Operation op,
8282
}
8383
#endif
8484

85+
// We handle redirects ourselves in AbstractNetworkJob::slotFinished
86+
// Qt's automatic handling of redirects will transmit all set headers from the original
87+
// request again, including e.g. `Authorization`.
88+
newRequest.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy);
89+
8590
const auto reply = QNetworkAccessManager::createRequest(op, newRequest, outgoingData);
8691
HttpLogger::logRequest(reply, op, outgoingData);
8792
return reply;

src/libsync/creds/abstractcredentials.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#define MIRALL_CREDS_ABSTRACT_CREDENTIALS_H
1010

1111
#include <QObject>
12+
#include <QNetworkRequest>
1213

1314
#include <csync.h>
1415
#include "owncloudlib.h"
@@ -25,6 +26,9 @@ class OWNCLOUDSYNC_EXPORT AbstractCredentials : public QObject
2526
Q_OBJECT
2627

2728
public:
29+
/// Don't add credentials if this is set on a QNetworkRequest
30+
static constexpr QNetworkRequest::Attribute DontAddCredentialsAttribute = QNetworkRequest::User;
31+
2832
AbstractCredentials();
2933
// No need for virtual destructor - QObject already has one.
3034

src/libsync/creds/httpcredentials.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class HttpCredentialsAccessManager : public AccessManager
5151
QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) override
5252
{
5353
QNetworkRequest req(request);
54-
if (!req.attribute(HttpCredentials::DontAddCredentialsAttribute).toBool()) {
54+
if (!req.attribute(AbstractCredentials::DontAddCredentialsAttribute).toBool()) {
5555
if (_cred && !_cred->password().isEmpty()) {
5656
QByteArray credHash = QByteArray(_cred->user().toUtf8() + ":" + _cred->password().toUtf8()).toBase64();
5757
req.setRawHeader("Authorization", "Basic " + credHash);

src/libsync/creds/httpcredentials.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,6 @@ class OWNCLOUDSYNC_EXPORT HttpCredentials : public AbstractCredentials
6767
friend class HttpCredentialsAccessManager;
6868

6969
public:
70-
/// Don't add credentials if this is set on a QNetworkRequest
71-
static constexpr QNetworkRequest::Attribute DontAddCredentialsAttribute = QNetworkRequest::User;
72-
7370
HttpCredentials();
7471
explicit HttpCredentials(const QString &user, const QString &password,
7572
const QByteArray &clientCertBundle = QByteArray(), const QByteArray &clientCertPassword = QByteArray());

src/libsync/creds/tokencredentials.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ class TokenCredentialsAccessManager : public AccessManager
4747

4848
QNetworkRequest req(request);
4949

50-
QByteArray credHash = QByteArray(_cred->user().toUtf8() + ":" + _cred->password().toUtf8()).toBase64();
51-
req.setRawHeader(QByteArray("Authorization"), QByteArray("Basic ") + credHash);
50+
if (!req.attribute(AbstractCredentials::DontAddCredentialsAttribute).toBool()) {
51+
QByteArray credHash = QByteArray(_cred->user().toUtf8() + ":" + _cred->password().toUtf8()).toBase64();
52+
req.setRawHeader(QByteArray("Authorization"), QByteArray("Basic ") + credHash);
53+
}
5254

5355
// A pre-authenticated cookie
5456
QByteArray token = _cred->_token.toUtf8();

src/libsync/networkjobs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ void DetermineAuthTypeJob::start()
11811181

11821182
QNetworkRequest req;
11831183
// Prevent HttpCredentialsAccessManager from setting an Authorization header.
1184-
req.setAttribute(HttpCredentials::DontAddCredentialsAttribute, true);
1184+
req.setAttribute(AbstractCredentials::DontAddCredentialsAttribute, true);
11851185
// Don't reuse previous auth credentials
11861186
req.setAttribute(QNetworkRequest::AuthenticationReuseAttribute, QNetworkRequest::Manual);
11871187

src/libsync/propagatedownload.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
#include "config.h"
8+
#include "libsync/creds/abstractcredentials.h"
89
#include "owncloudpropagator_p.h"
910
#include "propagatedownload.h"
1011
#include "networkjobs.h"
@@ -122,6 +123,7 @@ void GETFileJob::start()
122123
sendRequest("GET", makeDavUrl(path()), req);
123124
} else {
124125
// Use direct URL
126+
req.setAttribute(AbstractCredentials::DontAddCredentialsAttribute, true);
125127
sendRequest("GET", _directDownloadUrl, req);
126128
}
127129

0 commit comments

Comments
 (0)