mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-29 20:28:57 +03:00
OAuth: Use redirectable jobs for oauth token management
This commit is contained in:
parent
0e8ce9c3db
commit
ce51ea34b9
8 changed files with 84 additions and 12 deletions
|
@ -20,6 +20,7 @@
|
|||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include "theme.h"
|
||||
#include "networkjobs.h"
|
||||
|
||||
namespace OCC {
|
||||
|
||||
|
@ -82,9 +83,8 @@ void OAuth::start()
|
|||
requestToken.setPassword(Theme::instance()->oauthClientSecret());
|
||||
QNetworkRequest req;
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
auto reply = _account->sendRequest("POST", requestToken, req);
|
||||
QTimer::singleShot(30 * 1000, reply, &QNetworkReply::abort);
|
||||
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply, socket] {
|
||||
auto job = _account->sendRequest("POST", requestToken, req);
|
||||
QObject::connect(job, &SimpleNetworkJob::finishedSignal, this, [this, socket](QNetworkReply *reply) {
|
||||
auto jsonData = reply->readAll();
|
||||
QJsonParseError jsonParseError;
|
||||
QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object();
|
||||
|
|
|
@ -120,15 +120,20 @@ QNetworkReply *AbstractNetworkJob::addTimer(QNetworkReply *reply)
|
|||
QNetworkReply *AbstractNetworkJob::sendRequest(const QByteArray &verb, const QUrl &url,
|
||||
QNetworkRequest req, QIODevice *requestBody)
|
||||
{
|
||||
auto reply = _account->sendRequest(verb, url, req, requestBody);
|
||||
auto reply = _account->sendRawRequest(verb, url, req, requestBody);
|
||||
_requestBody = requestBody;
|
||||
if (_requestBody) {
|
||||
_requestBody->setParent(reply);
|
||||
}
|
||||
adoptRequest(reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
void AbstractNetworkJob::adoptRequest(QNetworkReply *reply)
|
||||
{
|
||||
addTimer(reply);
|
||||
setReply(reply);
|
||||
setupConnections(reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
QUrl AbstractNetworkJob::makeAccountUrl(const QString &relativePath) const
|
||||
|
|
|
@ -126,6 +126,13 @@ protected:
|
|||
QNetworkRequest req = QNetworkRequest(),
|
||||
QIODevice *requestBody = 0);
|
||||
|
||||
/** Makes this job drive a pre-made QNetworkReply
|
||||
*
|
||||
* This reply cannot have a QIODevice request body because we can't get
|
||||
* at it and thus not resend it in case of redirects.
|
||||
*/
|
||||
void adoptRequest(QNetworkReply *reply);
|
||||
|
||||
/// Creates a url for the account from a relative path
|
||||
QUrl makeAccountUrl(const QString &relativePath) const;
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ QSharedPointer<QNetworkAccessManager> Account::sharedNetworkAccessManager()
|
|||
return _am;
|
||||
}
|
||||
|
||||
QNetworkReply *Account::sendRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
|
||||
QNetworkReply *Account::sendRawRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
|
||||
{
|
||||
req.setUrl(url);
|
||||
req.setSslConfiguration(this->getOrCreateSslConfig());
|
||||
|
@ -244,6 +244,13 @@ QNetworkReply *Account::sendRequest(const QByteArray &verb, const QUrl &url, QNe
|
|||
return _am->sendCustomRequest(req, verb, data);
|
||||
}
|
||||
|
||||
SimpleNetworkJob *Account::sendRequest(const QByteArray &verb, const QUrl &url, QNetworkRequest req, QIODevice *data)
|
||||
{
|
||||
auto job = new SimpleNetworkJob(sharedFromThis(), this);
|
||||
job->startRequest(verb, url, req, data);
|
||||
return job;
|
||||
}
|
||||
|
||||
void Account::setSslConfiguration(const QSslConfiguration &config)
|
||||
{
|
||||
_sslConfiguration = config;
|
||||
|
|
|
@ -44,6 +44,7 @@ class Account;
|
|||
typedef QSharedPointer<Account> AccountPtr;
|
||||
class QuotaInfo;
|
||||
class AccessManager;
|
||||
class SimpleNetworkJob;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -114,9 +115,22 @@ public:
|
|||
AbstractCredentials *credentials() const;
|
||||
void setCredentials(AbstractCredentials *cred);
|
||||
|
||||
/** Create a network request on the account's QNAM.
|
||||
*
|
||||
* Network requests in AbstractNetworkJobs are created through
|
||||
* this function. Other places should prefer to use jobs or
|
||||
* sendRequest().
|
||||
*/
|
||||
QNetworkReply *sendRawRequest(const QByteArray &verb,
|
||||
const QUrl &url,
|
||||
QNetworkRequest req = QNetworkRequest(),
|
||||
QIODevice *data = 0);
|
||||
|
||||
// For creating various network requests
|
||||
QNetworkReply *sendRequest(const QByteArray &verb,
|
||||
/** Create and start network job for a simple one-off request.
|
||||
*
|
||||
* More complicated requests typically create their own job types.
|
||||
*/
|
||||
SimpleNetworkJob *sendRequest(const QByteArray &verb,
|
||||
const QUrl &url,
|
||||
QNetworkRequest req = QNetworkRequest(),
|
||||
QIODevice *data = 0);
|
||||
|
|
|
@ -303,10 +303,8 @@ bool HttpCredentials::refreshAccessToken()
|
|||
requestToken.setPassword(Theme::instance()->oauthClientSecret());
|
||||
QNetworkRequest req;
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||
auto reply = _account->sendRequest("POST", requestToken, req);
|
||||
QTimer::singleShot(30 * 1000, reply, &QNetworkReply::abort);
|
||||
QObject::connect(reply, &QNetworkReply::finished, this, [this, reply] {
|
||||
reply->deleteLater();
|
||||
auto job = _account->sendRequest("POST", requestToken, req);
|
||||
QObject::connect(job, &SimpleNetworkJob::finishedSignal, this, [this](QNetworkReply *reply) {
|
||||
auto jsonData = reply->readAll();
|
||||
QJsonParseError jsonParseError;
|
||||
QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object();
|
||||
|
|
|
@ -886,4 +886,23 @@ void DetermineAuthTypeJob::send(const QUrl &url)
|
|||
sendRequest("GET", url, req);
|
||||
}
|
||||
|
||||
SimpleNetworkJob::SimpleNetworkJob(AccountPtr account, QObject *parent)
|
||||
: AbstractNetworkJob(account, QString(), parent)
|
||||
{
|
||||
}
|
||||
|
||||
QNetworkReply *SimpleNetworkJob::startRequest(const QByteArray &verb, const QUrl &url,
|
||||
QNetworkRequest req, QIODevice *requestBody)
|
||||
{
|
||||
auto reply = sendRequest(verb, url, req, requestBody);
|
||||
start();
|
||||
return reply;
|
||||
}
|
||||
|
||||
bool SimpleNetworkJob::finished()
|
||||
{
|
||||
emit finishedSignal(reply());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
|
|
@ -377,6 +377,28 @@ private:
|
|||
int _redirects;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A basic job around a network request without extra funtionality
|
||||
* @ingroup libsync
|
||||
*
|
||||
* Primarily adds timeout and redirection handling.
|
||||
*/
|
||||
class OWNCLOUDSYNC_EXPORT SimpleNetworkJob : public AbstractNetworkJob
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SimpleNetworkJob(AccountPtr account, QObject *parent = 0);
|
||||
|
||||
QNetworkReply *startRequest(const QByteArray &verb, const QUrl &url,
|
||||
QNetworkRequest req = QNetworkRequest(),
|
||||
QIODevice *requestBody = 0);
|
||||
|
||||
signals:
|
||||
void finishedSignal(QNetworkReply *reply);
|
||||
private slots:
|
||||
bool finished() Q_DECL_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
#endif // NETWORKJOBS_H
|
||||
|
|
Loading…
Reference in a new issue