Commit a7f7b8ea authored by Jesus Fernandez's avatar Jesus Fernandez

Added refresh token support

parent 46d71818
......@@ -83,6 +83,8 @@ public:
QString scope;
QString userAgent = "qoauth/0.1";
const QString bearerFormat = QStringLiteral("Bearer %1");
QDateTime expiresAt;
QString refreshToken;
struct OAuth2KeyString
{
......
......@@ -76,9 +76,7 @@ public:
QUrl accessTokenUrl;
QString tokenType;
QDateTime expiresAt;
QString refreshToken;
QPointer<QNetworkReply> accessTokenReply;
QPointer<QNetworkReply> currentReply;
};
QT_END_NAMESPACE
......
......@@ -306,6 +306,12 @@ void QAbstractOAuth2::setPort(uint port)
}
}
QDateTime QAbstractOAuth2::expirationAt() const
{
Q_D(const QAbstractOAuth2);
return d->expiresAt;
}
QT_END_NAMESPACE
#endif // QT_NO_HTTP
......@@ -84,7 +84,6 @@ public:
void setUserAgent(const QString &userAgent);
virtual QString responseType() const = 0;
virtual QString grantType() const = 0;
virtual QString clientIdentifier() const override;
void setClientIdentifier(const QString &clientIdentifier);
......@@ -97,6 +96,8 @@ public:
uint port() const;
void setPort(uint port);
QDateTime expirationAt() const;
Q_SIGNALS:
void scopeChanged(const QString &scope);
void userAgentChanged(const QString &userAgent);
......
......@@ -111,7 +111,7 @@ void QOAuth2AuthorizationCodeFlowPrivate::accessTokenRequestFinished(QNetworkRep
Q_Q(QOAuth2AuthorizationCodeFlow);
typedef QAbstractOAuth2Private::OAuth2KeyString Key;
if (reply != accessTokenReply)
if (reply != currentReply)
return;
if (reply->error() == QNetworkReply::UnknownNetworkError) {
return;
......@@ -131,9 +131,9 @@ void QOAuth2AuthorizationCodeFlowPrivate::accessTokenRequestFinished(QNetworkRep
return;
}
const auto accessToken = object.value(Key::accessToken).toString();
const QString accessToken = object.value(Key::accessToken).toString();
tokenType = object.value(Key::tokenType).toString();
const auto expiresIn = object.value(Key::expiresIn).toInt(-1);
const int expiresIn = object.value(Key::expiresIn).toInt(-1);
refreshToken = object.value(Key::refreshToken).toString();
scope = object.value(Key::scope).toString();
if (accessToken.isEmpty()) {
......@@ -149,7 +149,7 @@ void QOAuth2AuthorizationCodeFlowPrivate::accessTokenRequestFinished(QNetworkRep
void QOAuth2AuthorizationCodeFlowPrivate::authenticate(QNetworkReply *reply,
QAuthenticator *authenticator)
{
if (reply == accessTokenReply){
if (reply == currentReply){
const auto url = reply->url();
if (url == accessTokenUrl) {
authenticator->setUser(clientCredentials.first);
......@@ -212,11 +212,6 @@ QString QOAuth2AuthorizationCodeFlow::responseType() const
return QStringLiteral("code");
}
QString QOAuth2AuthorizationCodeFlow::grantType() const
{
return QStringLiteral("authorization_code");
}
QUrl QOAuth2AuthorizationCodeFlow::accessTokenUrl() const
{
Q_D(const QOAuth2AuthorizationCodeFlow);
......@@ -249,6 +244,39 @@ void QOAuth2AuthorizationCodeFlow::grant()
Q_EMIT authorizationRequested(url);
}
void QOAuth2AuthorizationCodeFlow::refreshAccessToken()
{
Q_D(QOAuth2AuthorizationCodeFlow);
if (d->refreshToken.isEmpty()) {
qWarning("QOAuth2AuthorizationCodeFlow::refreshAccessToken: Cannot refresh access token. "
"Empty refresh token");
return;
}
typedef QAbstractOAuth2Private::OAuth2KeyString Key;
QVariantMap parameters;
QNetworkRequest request(d->accessTokenUrl);
QUrlQuery query;
parameters.insert(Key::grantType, QStringLiteral("refresh_token"));
parameters.insert(Key::refreshToken, d->refreshToken);
parameters.insert(Key::redirectUri, QUrl::toPercentEncoding(callback()));
query = QAbstractOAuthPrivate::createQuery(parameters);
request.setHeader(QNetworkRequest::ContentTypeHeader,
QStringLiteral("application/x-www-form-urlencoded"));
const QString data = query.toString(QUrl::FullyEncoded);
d->currentReply = d->networkAccessManager()->post(request, data.toUtf8());
QObjectPrivate::connect(d->networkAccessManager(), &QNetworkAccessManager::finished,
d, &QOAuth2AuthorizationCodeFlowPrivate::accessTokenRequestFinished);
QObjectPrivate::connect(d->networkAccessManager(),
&QNetworkAccessManager::authenticationRequired,
d, &QOAuth2AuthorizationCodeFlowPrivate::authenticate,
Qt::UniqueConnection);
}
QUrl QOAuth2AuthorizationCodeFlow::buildAuthenticateUrl(const QVariantMap &parameters)
{
Q_D(QOAuth2AuthorizationCodeFlow);
......@@ -283,7 +311,7 @@ void QOAuth2AuthorizationCodeFlow::requestAccessToken(const QString &code)
QVariantMap parameters;
QNetworkRequest request(d->accessTokenUrl);
QUrlQuery query;
parameters.insert(Key::grantType, grantType());
parameters.insert(Key::grantType, QStringLiteral("authorization_code"));
parameters.insert(Key::code, QUrl::toPercentEncoding(code));
parameters.insert(Key::redirectUri, QUrl::toPercentEncoding(callback()));
parameters.insert(Key::clientIdentifier, QUrl::toPercentEncoding(d->clientCredentials.first));
......@@ -295,8 +323,8 @@ void QOAuth2AuthorizationCodeFlow::requestAccessToken(const QString &code)
request.setHeader(QNetworkRequest::ContentTypeHeader,
QStringLiteral("application/x-www-form-urlencoded"));
const auto data = query.toString(QUrl::FullyEncoded);
d->accessTokenReply = d->networkAccessManager()->post(request, data.toUtf8());
const QString data = query.toString(QUrl::FullyEncoded);
d->currentReply = d->networkAccessManager()->post(request, data.toUtf8());
QObjectPrivate::connect(d->networkAccessManager(), &QNetworkAccessManager::finished,
d, &QOAuth2AuthorizationCodeFlowPrivate::accessTokenRequestFinished);
QObjectPrivate::connect(d->networkAccessManager(),
......
......@@ -86,13 +86,13 @@ public:
virtual ~QOAuth2AuthorizationCodeFlow();
virtual QString responseType() const override;
virtual QString grantType() const override;
QUrl accessTokenUrl() const;
void setAccessTokenUrl(const QUrl &accessTokenUrl);
public Q_SLOTS:
virtual void grant() override;
void refreshAccessToken();
protected:
QUrl buildAuthenticateUrl(const QVariantMap &parameters = QVariantMap());
......
......@@ -86,11 +86,6 @@ QString QOAuth2ImplicitGrantFlow::responseType() const
return QStringLiteral("token");
}
QString QOAuth2ImplicitGrantFlow::grantType() const
{
return QStringLiteral("");
}
void QOAuth2ImplicitGrantFlow::grant()
{
const QString state = QAbstractOAuth2Private::generateRandomState();
......
......@@ -62,7 +62,6 @@ public:
virtual ~QOAuth2ImplicitGrantFlow();
virtual QString responseType() const override;
virtual QString grantType() const override;
virtual void grant() override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment