From 0b97b8c74ba8297d04fb15277ff058a1f5d31c6d Mon Sep 17 00:00:00 2001 From: John Maguire Date: Fri, 17 Aug 2012 14:44:28 +0200 Subject: [PATCH] Re-authenticate to Drive when token expires. --- src/internet/googledriveclient.cpp | 6 ++++++ src/internet/googledriveclient.h | 5 +++-- src/internet/oauthenticator.cpp | 11 ++++++++++- src/internet/oauthenticator.h | 5 +++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/internet/googledriveclient.cpp b/src/internet/googledriveclient.cpp index b907a2b97..1a9c9b268 100644 --- a/src/internet/googledriveclient.cpp +++ b/src/internet/googledriveclient.cpp @@ -89,6 +89,7 @@ ConnectResponse* Client::Connect(const QString& refresh_token) { void Client::ConnectFinished(ConnectResponse* response, OAuthenticator* oauth) { oauth->deleteLater(); access_token_ = oauth->access_token(); + expiry_time_ = oauth->expiry_time(); response->refresh_token_ = oauth->refresh_token(); emit response->Finished(); @@ -186,3 +187,8 @@ void Client::GetFileFinished(GetFileResponse* response, QNetworkReply* reply) { response->file_ = File(result); emit response->Finished(); } + +bool Client::is_authenticated() const { + return !access_token_.isEmpty() && + QDateTime::currentDateTime().secsTo(expiry_time_) > 0; +} diff --git a/src/internet/googledriveclient.h b/src/internet/googledriveclient.h index 6944a373a..a67968202 100644 --- a/src/internet/googledriveclient.h +++ b/src/internet/googledriveclient.h @@ -135,7 +135,7 @@ class Client : public QObject { public: Client(QObject* parent = 0); - bool is_authenticated() const { return !access_token_.isEmpty(); } + bool is_authenticated() const; const QString& access_token() const { return access_token_; } ConnectResponse* Connect(const QString& refresh_token = QString()); @@ -154,11 +154,12 @@ private: void AddAuthorizationHeader(QNetworkRequest* request) const; void MakeListFilesRequest(ListFilesResponse* response, const QString& page_token = QString()); - + private: QNetworkAccessManager* network_; QString access_token_; + QDateTime expiry_time_; }; } // namespace diff --git a/src/internet/oauthenticator.cpp b/src/internet/oauthenticator.cpp index b2cf31e75..3fcddcaf4 100644 --- a/src/internet/oauthenticator.cpp +++ b/src/internet/oauthenticator.cpp @@ -18,6 +18,7 @@ namespace { const char* kGoogleOAuthEndpoint = "https://accounts.google.com/o/oauth2/auth"; const char* kGoogleOAuthTokenEndpoint = "https://accounts.google.com/o/oauth2/token"; +const char* kGoogleOAuthScope = "https://www.googleapis.com/auth/drive.readonly"; const char* kClientId = "679260893280.apps.googleusercontent.com"; const char* kClientSecret = "l3cWb8efUZsrBI4wmY3uKl6i"; @@ -38,7 +39,7 @@ void OAuthenticator::StartAuthorisation() { url.addQueryItem("response_type", "code"); url.addQueryItem("client_id", kClientId); url.addQueryItem("redirect_uri", QString("http://localhost:%1").arg(port)); - url.addQueryItem("scope", "https://www.googleapis.com/auth/drive.readonly"); + url.addQueryItem("scope", kGoogleOAuthScope); QDesktopServices::openUrl(url); } @@ -157,6 +158,7 @@ void OAuthenticator::FetchAccessTokenFinished(QNetworkReply* reply) { access_token_ = result["access_token"].toString(); refresh_token_ = result["refresh_token"].toString(); + SetExpiryTime(result["expires_in"].toInt()); emit Finished(); } @@ -187,6 +189,12 @@ void OAuthenticator::RefreshAuthorisation(const QString& refresh_token) { SLOT(RefreshAccessTokenFinished(QNetworkReply*)), reply); } +void OAuthenticator::SetExpiryTime(int expires_in_seconds) { + // Set the expiry time with two minutes' grace. + expiry_time_ = QDateTime::currentDateTime().addSecs(expires_in_seconds - 120); + qLog(Debug) << "Current Google Drive token expires at:" << expiry_time_; +} + void OAuthenticator::RefreshAccessTokenFinished(QNetworkReply* reply) { reply->deleteLater(); QJson::Parser parser; @@ -194,5 +202,6 @@ void OAuthenticator::RefreshAccessTokenFinished(QNetworkReply* reply) { QVariantMap result = parser.parse(reply, &ok).toMap(); access_token_ = result["access_token"].toString(); + SetExpiryTime(result["expires_in"].toInt()); emit Finished(); } diff --git a/src/internet/oauthenticator.h b/src/internet/oauthenticator.h index a073fb186..791c7f383 100644 --- a/src/internet/oauthenticator.h +++ b/src/internet/oauthenticator.h @@ -1,6 +1,7 @@ #ifndef OAUTHENTICATOR_H #define OAUTHENTICATOR_H +#include #include #include @@ -21,6 +22,8 @@ class OAuthenticator : public QObject { // Token to use to get a new access token when it expires. const QString& refresh_token() const { return refresh_token_; } + const QDateTime& expiry_time() const { return expiry_time_; } + signals: void Finished(); @@ -33,12 +36,14 @@ class OAuthenticator : public QObject { private: QByteArray ParseHttpRequest(const QByteArray& request) const; void RequestAccessToken(const QByteArray& code, quint16 port); + void SetExpiryTime(int expires_in_seconds); QTcpServer server_; NetworkAccessManager network_; QString access_token_; QString refresh_token_; + QDateTime expiry_time_; }; #endif