OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview | 6 * @fileoverview |
7 * OAuth2 API flow implementations. | 7 * OAuth2 API flow implementations. |
8 */ | 8 */ |
9 | 9 |
10 'use strict'; | 10 'use strict'; |
11 | 11 |
12 /** @suppress {duplicate} */ | 12 /** @suppress {duplicate} */ |
13 var remoting = remoting || {}; | 13 var remoting = remoting || {}; |
14 | 14 |
15 /** @constructor */ | 15 /** |
16 remoting.OAuth2Api = function() { | 16 * @constructor |
| 17 * @implements {remoting.OAuth2Api} |
| 18 */ |
| 19 remoting.OAuth2ApiImpl = function() { |
17 }; | 20 }; |
18 | 21 |
19 /** @private | 22 /** @private |
20 * @return {string} OAuth2 token URL. | 23 * @return {string} OAuth2 token URL. |
21 */ | 24 */ |
22 remoting.OAuth2Api.prototype.getOAuth2TokenEndpoint_ = function() { | 25 remoting.OAuth2ApiImpl.prototype.getOAuth2TokenEndpoint_ = function() { |
23 return remoting.settings.OAUTH2_BASE_URL + '/token'; | 26 return remoting.settings.OAUTH2_BASE_URL + '/token'; |
24 }; | 27 }; |
25 | 28 |
26 /** @private | 29 /** @private |
27 * @return {string} OAuth2 userinfo API URL. | 30 * @return {string} OAuth2 userinfo API URL. |
28 */ | 31 */ |
29 remoting.OAuth2Api.prototype.getOAuth2ApiUserInfoEndpoint_ = function() { | 32 remoting.OAuth2ApiImpl.prototype.getOAuth2ApiUserInfoEndpoint_ = function() { |
30 return remoting.settings.OAUTH2_API_BASE_URL + '/v1/userinfo'; | 33 return remoting.settings.OAUTH2_API_BASE_URL + '/v1/userinfo'; |
31 }; | 34 }; |
32 | 35 |
33 | 36 |
34 /** | 37 /** |
35 * Interprets HTTP error responses in authentication XMLHttpRequests. | 38 * Interprets HTTP error responses in authentication XMLHttpRequests. |
36 * | 39 * |
37 * @private | 40 * @private |
38 * @param {number} xhrStatus Status (HTTP response code) of the XMLHttpRequest. | 41 * @param {number} xhrStatus Status (HTTP response code) of the XMLHttpRequest. |
39 * @return {remoting.Error} An error code to be raised. | 42 * @return {remoting.Error} An error code to be raised. |
40 */ | 43 */ |
41 remoting.OAuth2Api.prototype.interpretXhrStatus_ = | 44 remoting.OAuth2ApiImpl.prototype.interpretXhrStatus_ = |
42 function(xhrStatus) { | 45 function(xhrStatus) { |
43 // Return AUTHENTICATION_FAILED by default, so that the user can try to | 46 // Return AUTHENTICATION_FAILED by default, so that the user can try to |
44 // recover from an unexpected failure by signing in again. | 47 // recover from an unexpected failure by signing in again. |
45 /** @type {remoting.Error} */ | 48 /** @type {remoting.Error} */ |
46 var error = remoting.Error.AUTHENTICATION_FAILED; | 49 var error = remoting.Error.AUTHENTICATION_FAILED; |
47 if (xhrStatus == 400 || xhrStatus == 401 || xhrStatus == 403) { | 50 if (xhrStatus == 400 || xhrStatus == 401 || xhrStatus == 403) { |
48 error = remoting.Error.AUTHENTICATION_FAILED; | 51 error = remoting.Error.AUTHENTICATION_FAILED; |
49 } else if (xhrStatus == 502 || xhrStatus == 503) { | 52 } else if (xhrStatus == 502 || xhrStatus == 503) { |
50 error = remoting.Error.SERVICE_UNAVAILABLE; | 53 error = remoting.Error.SERVICE_UNAVAILABLE; |
51 } else if (xhrStatus == 0) { | 54 } else if (xhrStatus == 0) { |
52 error = remoting.Error.NETWORK_FAILURE; | 55 error = remoting.Error.NETWORK_FAILURE; |
53 } else { | 56 } else { |
54 console.warn('Unexpected authentication response code: ' + xhrStatus); | 57 console.warn('Unexpected authentication response code: ' + xhrStatus); |
55 } | 58 } |
56 return error; | 59 return error; |
57 }; | 60 }; |
58 | 61 |
59 /** | 62 /** |
60 * Asynchronously retrieves a new access token from the server. | 63 * Asynchronously retrieves a new access token from the server. |
61 * | 64 * |
62 * @param {function(string, number): void} onDone Callback to invoke when | 65 * @param {function(string, number): void} onDone Callback to invoke when |
63 * the access token and expiration time are successfully fetched. | 66 * the access token and expiration time are successfully fetched. |
64 * @param {function(remoting.Error):void} onError Callback invoked if an | 67 * @param {function(remoting.Error):void} onError Callback invoked if an |
65 * error occurs. | 68 * error occurs. |
66 * @param {string} clientId OAuth2 client ID. | 69 * @param {string} clientId OAuth2 client ID. |
67 * @param {string} clientSecret OAuth2 client secret. | 70 * @param {string} clientSecret OAuth2 client secret. |
68 * @param {string} refreshToken OAuth2 refresh token to be redeemed. | 71 * @param {string} refreshToken OAuth2 refresh token to be redeemed. |
69 * @return {void} Nothing. | 72 * @return {void} Nothing. |
70 */ | 73 */ |
71 remoting.OAuth2Api.prototype.refreshAccessToken = function( | 74 remoting.OAuth2ApiImpl.prototype.refreshAccessToken = function( |
72 onDone, onError, clientId, clientSecret, refreshToken) { | 75 onDone, onError, clientId, clientSecret, refreshToken) { |
73 /** @param {XMLHttpRequest} xhr */ | 76 /** @param {XMLHttpRequest} xhr */ |
74 var onResponse = function(xhr) { | 77 var onResponse = function(xhr) { |
75 if (xhr.status == 200) { | 78 if (xhr.status == 200) { |
76 try { | 79 try { |
77 // Don't use base.jsonParseSafe here unless you also include base.js, | 80 // Don't use base.jsonParseSafe here unless you also include base.js, |
78 // otherwise this won't work from the OAuth trampoline. | 81 // otherwise this won't work from the OAuth trampoline. |
79 // TODO(jamiewalch): Fix this once we're no longer using the trampoline. | 82 // TODO(jamiewalch): Fix this once we're no longer using the trampoline. |
80 var tokens = JSON.parse(xhr.responseText); | 83 var tokens = JSON.parse(xhr.responseText); |
81 onDone(tokens['access_token'], tokens['expires_in']); | 84 onDone(tokens['access_token'], tokens['expires_in']); |
(...skipping 26 matching lines...) Expand all Loading... |
108 * invoke when the refresh token, access token and access token expiration | 111 * invoke when the refresh token, access token and access token expiration |
109 * time are successfully fetched. | 112 * time are successfully fetched. |
110 * @param {function(remoting.Error):void} onError Callback invoked if an | 113 * @param {function(remoting.Error):void} onError Callback invoked if an |
111 * error occurs. | 114 * error occurs. |
112 * @param {string} clientId OAuth2 client ID. | 115 * @param {string} clientId OAuth2 client ID. |
113 * @param {string} clientSecret OAuth2 client secret. | 116 * @param {string} clientSecret OAuth2 client secret. |
114 * @param {string} code OAuth2 authorization code. | 117 * @param {string} code OAuth2 authorization code. |
115 * @param {string} redirectUri Redirect URI used to obtain this code. | 118 * @param {string} redirectUri Redirect URI used to obtain this code. |
116 * @return {void} Nothing. | 119 * @return {void} Nothing. |
117 */ | 120 */ |
118 remoting.OAuth2Api.prototype.exchangeCodeForTokens = function( | 121 remoting.OAuth2ApiImpl.prototype.exchangeCodeForTokens = function( |
119 onDone, onError, clientId, clientSecret, code, redirectUri) { | 122 onDone, onError, clientId, clientSecret, code, redirectUri) { |
120 /** @param {XMLHttpRequest} xhr */ | 123 /** @param {XMLHttpRequest} xhr */ |
121 var onResponse = function(xhr) { | 124 var onResponse = function(xhr) { |
122 if (xhr.status == 200) { | 125 if (xhr.status == 200) { |
123 try { | 126 try { |
124 // Don't use base.jsonParseSafe here unless you also include base.js, | 127 // Don't use base.jsonParseSafe here unless you also include base.js, |
125 // otherwise this won't work from the OAuth trampoline. | 128 // otherwise this won't work from the OAuth trampoline. |
126 // TODO(jamiewalch): Fix this once we're no longer using the trampoline. | 129 // TODO(jamiewalch): Fix this once we're no longer using the trampoline. |
127 var tokens = JSON.parse(xhr.responseText); | 130 var tokens = JSON.parse(xhr.responseText); |
128 onDone(tokens['refresh_token'], | 131 onDone(tokens['refresh_token'], |
(...skipping 23 matching lines...) Expand all Loading... |
152 /** | 155 /** |
153 * Get the user's email address. | 156 * Get the user's email address. |
154 * | 157 * |
155 * @param {function(string):void} onDone Callback invoked when the email | 158 * @param {function(string):void} onDone Callback invoked when the email |
156 * address is available. | 159 * address is available. |
157 * @param {function(remoting.Error):void} onError Callback invoked if an | 160 * @param {function(remoting.Error):void} onError Callback invoked if an |
158 * error occurs. | 161 * error occurs. |
159 * @param {string} token Access token. | 162 * @param {string} token Access token. |
160 * @return {void} Nothing. | 163 * @return {void} Nothing. |
161 */ | 164 */ |
162 remoting.OAuth2Api.prototype.getEmail = function(onDone, onError, token) { | 165 remoting.OAuth2ApiImpl.prototype.getEmail = function(onDone, onError, token) { |
163 /** @param {XMLHttpRequest} xhr */ | 166 /** @param {XMLHttpRequest} xhr */ |
164 var onResponse = function(xhr) { | 167 var onResponse = function(xhr) { |
165 if (xhr.status == 200) { | 168 if (xhr.status == 200) { |
166 try { | 169 try { |
167 var result = JSON.parse(xhr.responseText); | 170 var result = JSON.parse(xhr.responseText); |
168 onDone(result['email']); | 171 onDone(result['email']); |
169 } catch (err) { | 172 } catch (err) { |
170 console.error('Invalid "userinfo" response from server:', | 173 console.error('Invalid "userinfo" response from server:', |
171 /** @type {*} */ (err)); | 174 /** @type {*} */ (err)); |
172 onError(remoting.Error.UNEXPECTED); | 175 onError(remoting.Error.UNEXPECTED); |
(...skipping 12 matching lines...) Expand all Loading... |
185 /** | 188 /** |
186 * Get the user's email address and full name. | 189 * Get the user's email address and full name. |
187 * | 190 * |
188 * @param {function(string, string):void} onDone Callback invoked when the email | 191 * @param {function(string, string):void} onDone Callback invoked when the email |
189 * address and full name are available. | 192 * address and full name are available. |
190 * @param {function(remoting.Error):void} onError Callback invoked if an | 193 * @param {function(remoting.Error):void} onError Callback invoked if an |
191 * error occurs. | 194 * error occurs. |
192 * @param {string} token Access token. | 195 * @param {string} token Access token. |
193 * @return {void} Nothing. | 196 * @return {void} Nothing. |
194 */ | 197 */ |
195 remoting.OAuth2Api.prototype.getUserInfo = function(onDone, onError, token) { | 198 remoting.OAuth2ApiImpl.prototype.getUserInfo = |
| 199 function(onDone, onError, token) { |
196 /** @param {XMLHttpRequest} xhr */ | 200 /** @param {XMLHttpRequest} xhr */ |
197 var onResponse = function(xhr) { | 201 var onResponse = function(xhr) { |
198 if (xhr.status == 200) { | 202 if (xhr.status == 200) { |
199 try { | 203 try { |
200 var result = JSON.parse(xhr.responseText); | 204 var result = JSON.parse(xhr.responseText); |
201 onDone(result['email'], result['name']); | 205 onDone(result['email'], result['name']); |
202 } catch (err) { | 206 } catch (err) { |
203 console.error('Invalid "userinfo" response from server:', | 207 console.error('Invalid "userinfo" response from server:', |
204 /** @type {*} */ (err)); | 208 /** @type {*} */ (err)); |
205 onError(remoting.Error.UNEXPECTED); | 209 onError(remoting.Error.UNEXPECTED); |
206 } | 210 } |
207 } else { | 211 } else { |
208 console.error('Failed to get user info. Status: ' + xhr.status + | 212 console.error('Failed to get user info. Status: ' + xhr.status + |
209 ' response: ' + xhr.responseText); | 213 ' response: ' + xhr.responseText); |
210 onError(remoting.Error.fromHttpError(xhr.status)); | 214 onError(remoting.Error.fromHttpError(xhr.status)); |
211 } | 215 } |
212 }; | 216 }; |
213 var headers = { 'Authorization': 'OAuth ' + token }; | 217 var headers = { 'Authorization': 'OAuth ' + token }; |
214 remoting.xhr.get(this.getOAuth2ApiUserInfoEndpoint_(), | 218 remoting.xhr.get(this.getOAuth2ApiUserInfoEndpoint_(), |
215 onResponse, '', headers); | 219 onResponse, '', headers); |
216 }; | 220 }; |
217 | 221 |
218 /** @type {remoting.OAuth2Api} */ | 222 /** @type {remoting.OAuth2Api} */ |
219 remoting.oauth2Api = new remoting.OAuth2Api(); | 223 remoting.oauth2Api = new remoting.OAuth2ApiImpl(); |
OLD | NEW |