diff options
author | simonmorris@chromium.org <simonmorris@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-17 00:34:37 +0000 |
---|---|---|
committer | simonmorris@chromium.org <simonmorris@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-17 00:34:37 +0000 |
commit | 68c60879d27398b82448f94a385718b2297bebca (patch) | |
tree | b6424ed731b0c7f848064505b5ed675e4bf76958 /remoting/webapp | |
parent | a47c03d61f79089a5d39b22fe8a1477258f21532 (diff) | |
download | chromium_src-68c60879d27398b82448f94a385718b2297bebca.zip chromium_src-68c60879d27398b82448f94a385718b2297bebca.tar.gz chromium_src-68c60879d27398b82448f94a385718b2297bebca.tar.bz2 |
[Chromoting] The webapp revokes OAuth refresh tokens when they will no longer be used.
BUG=123018
Review URL: https://chromiumcodereview.appspot.com/10080010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132494 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/webapp')
-rw-r--r-- | remoting/webapp/host_controller.js | 2 | ||||
-rw-r--r-- | remoting/webapp/oauth2.js | 80 |
2 files changed, 75 insertions, 7 deletions
diff --git a/remoting/webapp/host_controller.js b/remoting/webapp/host_controller.js index e139575..74aeacf 100644 --- a/remoting/webapp/host_controller.js +++ b/remoting/webapp/host_controller.js @@ -156,7 +156,7 @@ remoting.HostController.prototype.start = function(hostPin, callback) { 'hmac:' + that.plugin_.getPinHash(newHostId, hostPin); var hostConfig = JSON.stringify({ xmpp_login: remoting.oauth2.getCachedEmail(), - oauth_refresh_token: remoting.oauth2.getRefreshToken(), + oauth_refresh_token: remoting.oauth2.exportRefreshToken(), host_id: newHostId, host_name: hostName, host_secret_hash: hostSecretHash, diff --git a/remoting/webapp/oauth2.js b/remoting/webapp/oauth2.js index a6c2452c..e2dc933 100644 --- a/remoting/webapp/oauth2.js +++ b/remoting/webapp/oauth2.js @@ -28,6 +28,9 @@ remoting.OAuth2 = function() { /** @private */ remoting.OAuth2.prototype.KEY_REFRESH_TOKEN_ = 'oauth2-refresh-token'; /** @private */ +remoting.OAuth2.prototype.KEY_REFRESH_TOKEN_REVOKABLE_ = + 'oauth2-refresh-token-revokable'; +/** @private */ remoting.OAuth2.prototype.KEY_ACCESS_TOKEN_ = 'oauth2-access-token'; /** @private */ remoting.OAuth2.prototype.KEY_EMAIL_ = 'remoting-email'; @@ -41,10 +44,12 @@ remoting.OAuth2.prototype.SCOPE_ = /** @private */ remoting.OAuth2.prototype.OAUTH2_TOKEN_ENDPOINT_ = 'https://accounts.google.com/o/oauth2/token'; - +/** @private */ +remoting.OAuth2.prototype.OAUTH2_REVOKE_TOKEN_ENDPOINT_ = + 'https://accounts.google.com/o/oauth2/revoke'; /** @return {boolean} True if the app is already authenticated. */ remoting.OAuth2.prototype.isAuthenticated = function() { - if (this.getRefreshToken()) { + if (this.getRefreshToken_()) { return true; } return false; @@ -56,22 +61,46 @@ remoting.OAuth2.prototype.isAuthenticated = function() { * @return {void} Nothing. */ remoting.OAuth2.prototype.clear = function() { - window.localStorage.removeItem(this.KEY_REFRESH_TOKEN_); window.localStorage.removeItem(this.KEY_EMAIL_); this.clearAccessToken(); + this.clearRefreshToken_(); }; /** + * Sets the refresh token. + * + * This method also marks the token as revokable, so that this object will + * revoke the token when it no longer needs it. + * * @param {string} token The new refresh token. * @return {void} Nothing. */ remoting.OAuth2.prototype.setRefreshToken = function(token) { window.localStorage.setItem(this.KEY_REFRESH_TOKEN_, escape(token)); + window.localStorage.setItem(this.KEY_REFRESH_TOKEN_REVOKABLE_, true); this.clearAccessToken(); }; -/** @return {?string} The refresh token, if authenticated, or NULL. */ -remoting.OAuth2.prototype.getRefreshToken = function() { +/** + * Gets the refresh token. + * + * This method also marks the refresh token as not revokable, so that this + * object will not revoke the token when it no longer needs it. After this + * object has exported the token, it cannot know whether it is still in use + * when this object no longer needs it. + * + * @return {?string} The refresh token, if authenticated, or NULL. + */ +remoting.OAuth2.prototype.exportRefreshToken = function() { + window.localStorage.removeItem(this.KEY_REFRESH_TOKEN_REVOKABLE_); + return this.getRefreshToken_(); +}; + +/** + * @return {?string} The refresh token, if authenticated, or NULL. + * @private + */ +remoting.OAuth2.prototype.getRefreshToken_ = function() { var value = window.localStorage.getItem(this.KEY_REFRESH_TOKEN_); if (typeof value == 'string') { return unescape(value); @@ -80,6 +109,20 @@ remoting.OAuth2.prototype.getRefreshToken = function() { }; /** + * Clears the refresh token. + * + * @return {void} Nothing. + * @private + */ +remoting.OAuth2.prototype.clearRefreshToken_ = function() { + if (window.localStorage.getItem(this.KEY_REFRESH_TOKEN_REVOKABLE_)) { + this.revokeToken_(this.getRefreshToken_()); + } + window.localStorage.removeItem(this.KEY_REFRESH_TOKEN_); + window.localStorage.removeItem(this.KEY_REFRESH_TOKEN_REVOKABLE_); +}; + +/** * @param {string} token The new access token. * @param {number} expiration Expiration time in milliseconds since epoch. * @return {void} Nothing. @@ -200,7 +243,7 @@ remoting.OAuth2.prototype.refreshAccessToken = function(onDone) { var parameters = { 'client_id': this.CLIENT_ID_, 'client_secret': this.CLIENT_SECRET_, - 'refresh_token': this.getRefreshToken(), + 'refresh_token': this.getRefreshToken_(), 'grant_type': 'refresh_token' }; @@ -264,6 +307,31 @@ remoting.OAuth2.prototype.exchangeCodeForToken = function(code, onDone) { }; /** + * Revokes a refresh or an access token. + * + * @param {string?} token An access or refresh token. + * @return {void} Nothing. + * @private + */ +remoting.OAuth2.prototype.revokeToken_ = function(token) { + if (!token || (token.length == 0)) { + return; + } + var parameters = { 'token': token }; + + /** @param {XMLHttpRequest} xhr The XHR reply. */ + var processResponse = function(xhr) { + if (xhr.status != 200) { + console.log('Failed to revoke token. Status: ' + xhr.status + + ' ; response: ' + xhr.responseText + ' ; xhr: ', xhr); + } + }; + remoting.xhr.post(this.OAUTH2_REVOKE_TOKEN_ENDPOINT_, + processResponse, + parameters); +}; + +/** * Call myfunc with an access token as the only parameter. * * This will refresh the access token if necessary. If the access token |