#include <QDesktopServices>
#include <QNetworkReply>
#include <QTimer>
+#include <QBuffer>
#include "account.h"
#include "creds/oauth.h"
#include <QJsonObject>
QString code = rx.cap(1); // The 'code' is the first capture of the regexp
- QUrl requestToken(_account->url().toString()
- + QLatin1String("/index.php/apps/oauth2/api/v1/token?grant_type=authorization_code&code=")
- + code
- + QLatin1String("&redirect_uri=http://localhost:") + QString::number(_server.serverPort()));
+ QUrl requestToken(_account->url().toString() + QLatin1String("/index.php/apps/oauth2/api/v1/token"));
QNetworkRequest req;
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
+
QString basicAuth = QString("%1:%2").arg(
Theme::instance()->oauthClientId(), Theme::instance()->oauthClientSecret());
req.setRawHeader("Authorization", "Basic " + basicAuth.toUtf8().toBase64());
- auto job = _account->sendRequest("POST", requestToken, req);
+
+ auto requestBody = new QBuffer;
+ QUrlQuery arguments(QString(
+ "grant_type=authorization_code&code=%1&redirect_uri=http://localhost:%2")
+ .arg(code, QString::number(_server.serverPort())));
+ requestBody->setData(arguments.query(QUrl::FullyEncoded).toLatin1());
+
+ auto job = _account->sendRequest("POST", requestToken, req, requestBody);
QObject::connect(job, &SimpleNetworkJob::finishedSignal, this, [this, socket](QNetworkReply *reply) {
auto jsonData = reply->readAll();
QJsonParseError jsonParseError;
if (_followRedirects && !redirectUrl.isEmpty()) {
_redirectCount++;
+ // For POST requests where the target url has query arguments, Qt automatically
+ // moves these arguments to the body if no explicit body is specified.
+ // This can cause problems with redirected requests, because the redirect url
+ // will no longer contain these query arguments.
+ if (reply()->operation() == QNetworkAccessManager::PostOperation
+ && requestedUrl.hasQuery()
+ && !redirectUrl.hasQuery()
+ && !_requestBody) {
+ qCWarning(lcNetworkJob) << "Redirecting a POST request with an implicit body loses that body";
+ }
+
// ### some of the qWarnings here should be exported via displayErrors() so they
// ### can be presented to the user if the job executor has a GUI
QByteArray verb = requestVerb(*reply());
#include <QSslKey>
#include <QJsonObject>
#include <QJsonDocument>
+#include <QBuffer>
#include <keychain.h>
if (_refreshToken.isEmpty())
return false;
- QUrl requestToken(_account->url().toString()
- + QLatin1String("/index.php/apps/oauth2/api/v1/token?grant_type=refresh_token&refresh_token=")
- + _refreshToken);
- requestToken.setUserName(Theme::instance()->oauthClientId());
- requestToken.setPassword(Theme::instance()->oauthClientSecret());
+ QUrl requestToken(_account->url().toString() + QLatin1String("/index.php/apps/oauth2/api/v1/token"));
QNetworkRequest req;
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
- auto job = _account->sendRequest("POST", requestToken, req);
+
+ QString basicAuth = QString("%1:%2").arg(
+ Theme::instance()->oauthClientId(), Theme::instance()->oauthClientSecret());
+ req.setRawHeader("Authorization", "Basic " + basicAuth.toUtf8().toBase64());
+
+ auto requestBody = new QBuffer;
+ QUrlQuery arguments(QString("grant_type=refresh_token&refresh_token=%1").arg(_refreshToken));
+ requestBody->setData(arguments.query(QUrl::FullyEncoded).toLatin1());
+
+ auto job = _account->sendRequest("POST", requestToken, req, requestBody);
QObject::connect(job, &SimpleNetworkJob::finishedSignal, this, [this](QNetworkReply *reply) {
auto jsonData = reply->readAll();
QJsonParseError jsonParseError;