Skip to content

Commit

Permalink
[Chromoting] Add support for getUserInfo.
Browse files Browse the repository at this point in the history
getUserInfo is similar to getEmail except that it gets the user's name
in addition to email address. Since it requires a separate Google API
permission, there are separate getUserInfo vs. getEmail apis rather than
always getting (and requiring permission for) both.

The new getUserInfo apis are not currently used in CRD.

This also adds remoting.Identity.callWithNewToken, which is similar to
callWithToken except that it always uses a fresh token.

BUG=

Review URL: https://codereview.chromium.org/714433003

Cr-Commit-Position: refs/heads/master@{#303680}
  • Loading branch information
garykac authored and Commit bot committed Nov 11, 2014
1 parent 2c8b61a commit 3394d1f
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 2 deletions.
66 changes: 65 additions & 1 deletion remoting/webapp/crd/js/identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ remoting.Identity = function(consentCallback) {
this.consentCallback_ = consentCallback;
/** @type {?string} @private */
this.email_ = null;
/** @type {?string} @private */
this.fullName_ = null;
/** @type {Array.<remoting.Identity.Callbacks>} */
this.pendingCallbacks_ = [];
};
Expand All @@ -53,6 +55,31 @@ remoting.Identity.prototype.callWithToken = function(onOk, onError) {
}
};

/**
* Call a function with a fresh access token.
*
* @param {function(string):void} onOk Function to invoke with access token if
* an access token was successfully retrieved.
* @param {function(remoting.Error):void} onError Function to invoke with an
* error code on failure.
* @return {void} Nothing.
*/
remoting.Identity.prototype.callWithNewToken = function(onOk, onError) {
/** @type {remoting.Identity} */
var that = this;

/**
* @param {string} token
*/
function revokeToken(token) {
chrome.identity.removeCachedAuthToken(
{'token': token },
that.callWithToken.bind(that, onOk, onError));
};

this.callWithToken(revokeToken, onError);
};

/**
* Remove the cached auth token, if any.
*
Expand Down Expand Up @@ -86,23 +113,60 @@ remoting.Identity.prototype.getEmail = function(onOk, onError) {
/** @param {string} email */
var onResponse = function(email) {
that.email_ = email;
that.fullName_ = null;
onOk(email);
};

this.callWithToken(
remoting.OAuth2Api.getEmail.bind(null, onResponse, onError), onError);
};

/**
* Get the user's email address and full name.
*
* @param {function(string,string):void} onOk Callback invoked when the user's
* email address and full name are available.
* @param {function(remoting.Error):void} onError Callback invoked if an
* error occurs.
* @return {void} Nothing.
*/
remoting.Identity.prototype.getUserInfo = function(onOk, onError) {
/** @type {remoting.Identity} */
var that = this;
/**
* @param {string} email
* @param {string} name
*/
var onResponse = function(email, name) {
that.email_ = email;
that.fullName_ = name;
onOk(email, name);
};

this.callWithToken(
remoting.OAuth2Api.getUserInfo.bind(null, onResponse, onError), onError);
};

/**
* Get the user's email address, or null if no successful call to getEmail
* has been made.
* or getUserInfo has been made.
*
* @return {?string} The cached email address, if available.
*/
remoting.Identity.prototype.getCachedEmail = function() {
return this.email_;
};

/**
* Get the user's full name, or null if no successful call to getUserInfo
* has been made.
*
* @return {?string} The cached user's full name, if available.
*/
remoting.Identity.prototype.getCachedUserFullName = function() {
return this.fullName_;
};

/**
* Callback for the getAuthToken API.
*
Expand Down
53 changes: 52 additions & 1 deletion remoting/webapp/crd/js/oauth2.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ remoting.OAuth2.prototype.KEY_ACCESS_TOKEN_ = 'oauth2-access-token';
remoting.OAuth2.prototype.KEY_XSRF_TOKEN_ = 'oauth2-xsrf-token';
/** @private */
remoting.OAuth2.prototype.KEY_EMAIL_ = 'remoting-email';
/** @private */
remoting.OAuth2.prototype.KEY_FULLNAME_ = 'remoting-fullname';

// Constants for parameters used in retrieving the OAuth2 credentials.
/** @private */
Expand Down Expand Up @@ -88,6 +90,7 @@ remoting.OAuth2.prototype.isAuthenticated = function() {
*/
remoting.OAuth2.prototype.clear = function() {
window.localStorage.removeItem(this.KEY_EMAIL_);
window.localStorage.removeItem(this.KEY_FULLNAME_);
this.clearAccessToken_();
this.clearRefreshToken_();
};
Expand All @@ -102,6 +105,7 @@ remoting.OAuth2.prototype.clear = function() {
remoting.OAuth2.prototype.setRefreshToken_ = function(token) {
window.localStorage.setItem(this.KEY_REFRESH_TOKEN_, escape(token));
window.localStorage.removeItem(this.KEY_EMAIL_);
window.localStorage.removeItem(this.KEY_FULLNAME_);
this.clearAccessToken_();
};

Expand Down Expand Up @@ -354,18 +358,51 @@ remoting.OAuth2.prototype.getEmail = function(onOk, onError) {
/** @param {string} email */
var onResponse = function(email) {
window.localStorage.setItem(that.KEY_EMAIL_, email);
window.localStorage.setItem(that.KEY_FULLNAME_, '');
onOk(email);
};

this.callWithToken(
remoting.OAuth2Api.getEmail.bind(null, onResponse, onError), onError);
};

/**
* Get the user's email address and full name.
*
* @param {function(string,string):void} onOk Callback invoked when the user's
* email address and full name are available.
* @param {function(remoting.Error):void} onError Callback invoked if an
* error occurs.
* @return {void} Nothing.
*/
remoting.OAuth2.prototype.getUserInfo = function(onOk, onError) {
var cachedEmail = window.localStorage.getItem(this.KEY_EMAIL_);
var cachedName = window.localStorage.getItem(this.KEY_FULLNAME_);
if (typeof cachedEmail == 'string' && typeof cachedName == 'string') {
onOk(cachedEmail, cachedName);
return;
}
/** @type {remoting.OAuth2} */
var that = this;
/**
* @param {string} email
* @param {string} name
*/
var onResponse = function(email, name) {
window.localStorage.setItem(that.KEY_EMAIL_, email);
window.localStorage.setItem(that.KEY_FULLNAME_, name);
onOk(email, name);
};

this.callWithToken(
remoting.OAuth2Api.getUserInfo.bind(null, onResponse, onError), onError);
};

/**
* If the user's email address is cached, return it, otherwise return null.
*
* @return {?string} The email address, if it has been cached by a previous call
* to getEmail, otherwise null.
* to getEmail or getUserInfo, otherwise null.
*/
remoting.OAuth2.prototype.getCachedEmail = function() {
var value = window.localStorage.getItem(this.KEY_EMAIL_);
Expand All @@ -374,3 +411,17 @@ remoting.OAuth2.prototype.getCachedEmail = function() {
}
return null;
};

/**
* If the user's full name is cached, return it, otherwise return null.
*
* @return {?string} The user's full name, if it has been cached by a previous
* call to getUserInfo, otherwise null.
*/
remoting.OAuth2.prototype.getCachedUserFullName = function() {
var value = window.localStorage.getItem(this.KEY_FULLNAME_);
if (typeof value == 'string') {
return value;
}
return null;
};
33 changes: 33 additions & 0 deletions remoting/webapp/crd/js/oauth2_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,36 @@ remoting.OAuth2Api.getEmail = function(onDone, onError, token) {
remoting.xhr.get(remoting.OAuth2Api.getOAuth2ApiUserInfoEndpoint_(),
onResponse, '', headers);
};

/**
* Get the user's email address and full name.
*
* @param {function(string, string):void} onDone Callback invoked when the email
* address and full name are available.
* @param {function(remoting.Error):void} onError Callback invoked if an
* error occurs.
* @param {string} token Access token.
* @return {void} Nothing.
*/
remoting.OAuth2Api.getUserInfo = function(onDone, onError, token) {
/** @param {XMLHttpRequest} xhr */
var onResponse = function(xhr) {
if (xhr.status == 200) {
try {
var result = JSON.parse(xhr.responseText);
onDone(result['email'], result['name']);
} catch (err) {
console.error('Invalid "userinfo" response from server:',
/** @type {*} */ (err));
onError(remoting.Error.UNEXPECTED);
}
} else {
console.error('Failed to get user info. Status: ' + xhr.status +
' response: ' + xhr.responseText);
onError(remoting.OAuth2Api.interpretXhrStatus_(xhr.status));
}
};
var headers = { 'Authorization': 'OAuth ' + token };
remoting.xhr.get(remoting.OAuth2Api.getOAuth2ApiUserInfoEndpoint_(),
onResponse, '', headers);
};

0 comments on commit 3394d1f

Please sign in to comment.