Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(301)

Side by Side Diff: polymer_1.0.4/bower_components/google-signin/google-signin-aware.html

Issue 1205703007: Add polymer 1.0 to npm_modules (Closed) Base URL: https://chromium.googlesource.com/infra/third_party/npm_modules.git@master
Patch Set: Renamed folder to 1.0.4 Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <link rel="import" href="../polymer/polymer.html">
2 <link rel="import" href="../google-apis/google-js-api.html">
3
4 <script>
5 (function() {
6
7 /**
8 * Enum of attributes to be passed through to the login API call.
9 * @readonly
10 * @enum {string}
11 */
12 var ProxyLoginAttributes = {
13 'appPackageName': 'apppackagename',
14 'clientId': 'clientid',
15 'cookiePolicy': 'cookiepolicy',
16 'requestVisibleActions': 'requestvisibleactions'
17 };
18
19 /**
20 * AuthEngine does all interactions with gapi.auth2
21 *
22 * It is tightly coupled with <google-signin-aware> element
23 * The elements configure AuthEngine.
24 * AuthEngine propagates all authentication events to all google-signin-awar e elements
25 *
26 * API used: https://developers.google.com/identity/sign-in/web/reference
27 *
28 */
29 var AuthEngine = {
30
31 /**
32 * oauth2 argument, set by google-signin-aware
33 */
34 _clientId: null,
35
36 get clientId() {
37 return this._clientId;
38 },
39
40 set clientId(val) {
41 if (this._clientId && val && val != this._clientId) {
42 throw new Error('clientId cannot change. Values do not match. New: ' + val + ' Old:' + this._clientId);
43 }
44 if (val) {
45 this._clientId = val;
46 this.initAuth2();
47 }
48 },
49
50 /**
51 * oauth2 argument, set by google-signin-aware
52 */
53 _cookiePolicy: 'single_host_origin',
54
55 get cookiePolicy() {
56 return this._cookiePolicy;
57 },
58
59 set cookiePolicy(val) {
60 if (val) {
61 this._cookiePolicy = val;
62 }
63 },
64
65 /**
66 * oauth2 argument, set by google-signin-aware
67 */
68 _appPackageName: '',
69
70 get appPackageName() {
71 return this._appPackageName;
72 },
73
74 set appPackageName(val) {
75 if (this._appPackageName && val && val != this._appPackageName) {
76 throw new Error('appPackageName cannot change. Values do not match. Ne w: ' + val + ' Old: ' + this._appPackageName);
77 }
78 if (val) {
79 this._appPackageName = val;
80 }
81 },
82
83 /**
84 * oauth2 argument, set by google-signin-aware
85 */
86 _requestVisibleActions: '',
87
88 get requestVisibleactions() {
89 return this._requestVisibleActions;
90 },
91
92 set requestVisibleactions(val) {
93 if (this._requestVisibleActions && val && val != this._requestVisibleAct ions) {
94 throw new Error('requestVisibleactions cannot change. Values do not ma tch. New: ' + val + ' Old: ' + this._requestVisibleActions);
95 }
96 if (val)
97 this._requestVisibleActions = val;
98 },
99
100 /** <google-js-api> */
101 _apiLoader: null,
102
103 /** an array of wanted scopes. oauth2 argument */
104 _requestedScopeArray: [],
105
106 /** _requestedScopeArray as string */
107 get requestedScopes() {
108 return this._requestedScopeArray.join(' ');
109 },
110
111 /** Is user signed in? */
112 _signedIn: false,
113
114 /** Currently granted scopes */
115 _grantedScopeArray: [],
116
117 /** True if additional authorization is required */
118 _needAdditionalAuth: true,
119
120 /** True if have google+ scopes */
121 _hasPlusScopes: false,
122
123 /**
124 * array of <google-signin-aware>
125 * state changes are broadcast to them
126 */
127 signinAwares: [],
128
129 init: function() {
130 this._apiLoader = document.createElement('google-js-api');
131 this._apiLoader.addEventListener('js-api-load', this.loadAuth2.bind(this ));
132 },
133
134 loadAuth2: function() {
135 gapi.load('auth2', this.initAuth2.bind(this));
136 },
137
138 initAuth2: function() {
139 if (!('gapi' in window) || !('auth2' in window.gapi) || !this.clientId) {
140 return;
141 }
142 var auth = gapi.auth2.init({
143 'client_id': this.clientId,
144 'cookie_policy': this.cookiePolicy,
145 'scope': this.requestedScopes
146 });
147
148 auth.currentUser.listen(this.handleUserUpdate.bind(this));
149
150 auth.then(
151 function success() {
152 // Let the current user listener trigger the changes.
153 },
154 function error(error) {
155 console.error(error);
156 }
157 );
158 },
159
160 handleUserUpdate: function(newPrimaryUser) {
161 // update and broadcast currentUser
162 var isSignedIn = newPrimaryUser.isSignedIn();
163 if (isSignedIn != this._signedIn) {
164 this._signedIn = isSignedIn;
165 for (var i=0; i<this.signinAwares.length; i++) {
166 this.signinAwares[i]._setSignedIn(isSignedIn);
167 }
168 }
169
170 // update granted scopes
171 this._grantedScopeArray = this.strToScopeArray(
172 newPrimaryUser.getGrantedScopes());
173 // console.log(this._grantedScopeArray);
174 this.updateAdditionalAuth();
175
176 var response = newPrimaryUser.getAuthResponse();
177 for (var i=0; i<this.signinAwares.length; i++) {
178 this.signinAwares[i]._updateScopeStatus(response);
179 }
180 },
181
182 /** convert scope string to scope array */
183 strToScopeArray: function(str) {
184 if (!str) {
185 return [];
186 }
187 // remove extra spaces, then split
188 var scopes = str.replace(/\ +/g, ' ').trim().split(' ');
189 for (var i=0; i<scopes.length; i++) {
190 scopes[i] = scopes[i].toLowerCase();
191 // Handle scopes that will be deprecated but are still returned with their old value
192 if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.profile') {
193 scopes[i] = 'profile';
194 }
195 if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.email') {
196 scopes[i] = 'email';
197 }
198 }
199 // return with duplicates filtered out
200 return scopes.filter( function(value, index, self) {
201 return self.indexOf(value) === index;
202 });
203 },
204
205 /** true if scopes have google+ scopes */
206 isPlusScope: function(scope) {
207 return (scope.indexOf('/auth/games') > -1)
208 || (scope.indexOf('auth/plus.') > -1 && scope.indexOf('auth/plus.me' ) < 0);
209 },
210
211 /** true if scopes have been granted */
212 hasGrantedScopes: function(scopeStr) {
213 var scopes = this.strToScopeArray(scopeStr);
214 for (var i=0; i< scopes.length; i++) {
215 if (this._grantedScopeArray.indexOf(scopes[i]) === -1)
216 return false;
217 }
218 return true;
219 },
220
221 /** request additional scopes */
222 requestScopes: function(newScopeStr) {
223 var newScopes = this.strToScopeArray(newScopeStr);
224 var scopesUpdated = false;
225 for (var i=0; i<newScopes.length; i++) {
226 if (this._requestedScopeArray.indexOf(newScopes[i]) === -1) {
227 this._requestedScopeArray.push(newScopes[i]);
228 scopesUpdated = true;
229 }
230 }
231 if (scopesUpdated) {
232 this.updateAdditionalAuth();
233 this.updatePlusScopes();
234 }
235 },
236
237 /** update status of _needAdditionalAuth */
238 updateAdditionalAuth: function() {
239 var needMoreAuth = false;
240 for (var i=0; i<this._requestedScopeArray.length; i++) {
241 if (this._grantedScopeArray.indexOf(this._requestedScopeArray[i]) === -1) {
242 needMoreAuth = true;
243 break;
244 }
245 }
246 if (this._needAdditionalAuth != needMoreAuth) {
247 this._needAdditionalAuth = needMoreAuth;
248 // broadcast new value
249 for (var i=0; i<this.signinAwares.length; i++) {
250 this.signinAwares[i]._setNeedAdditionalAuth(needMoreAuth);
251 }
252 }
253 },
254
255 updatePlusScopes: function() {
256 var hasPlusScopes = false;
257 for (var i = 0; i < this._requestedScopeArray.length; i++) {
258 if (this.isPlusScope(this._requestedScopeArray[i])) {
259 hasPlusScopes = true;
260 break;
261 }
262 }
263 if (this._hasPlusScopes != hasPlusScopes) {
264 this._hasPlusScopes = hasPlusScopes;
265 for (var i=0; i<this.signinAwares.length; i++) {
266 this.signinAwares[i]._setHasPlusScopes(hasPlusScopes);
267 }
268 }
269 },
270 /**
271 * attached <google-signin-aware>
272 * @param {<google-signin-aware>} aware element to add
273 */
274 attachSigninAware: function(aware) {
275 if (this.signinAwares.indexOf(aware) == -1) {
276 this.signinAwares.push(aware);
277 // Initialize aware properties
278 aware._setNeedAdditionalAuth(this._needAdditionalAuth);
279 aware._setSignedIn(this._signedIn);
280 aware._setHasPlusScopes(this._hasPlusScopes);
281 } else {
282 console.warn('signinAware attached more than once', aware);
283 }
284 },
285
286 detachSigninAware: function(aware) {
287 var index = this.signinAwares.indexOf(aware);
288 if (index != -1) {
289 this.signinAwares.splice(index, 1);
290 } else {
291 console.warn('Trying to detach unattached signin-aware');
292 }
293 },
294
295 /** returns scopes not granted */
296 getMissingScopes: function() {
297 return this._requestedScopeArray.filter( function(scope) {
298 return this._grantedScopeArray.indexOf(scope) === -1;
299 }.bind(this)).join(' ');
300 },
301
302 assertAuthInitialized: function() {
303 if (!this.clientId) {
304 throw new Error("AuthEngine not initialized. clientId has not been con figured.");
305 }
306 if (!('gapi' in window)) {
307 throw new Error("AuthEngine not initialized. gapi has not loaded.");
308 }
309 if (!('auth2' in window.gapi)) {
310 throw new Error("AuthEngine not initialized. auth2 not loaded.");
311 }
312 },
313
314 /** pops up sign-in dialog */
315 signIn: function() {
316 this.assertAuthInitialized();
317 var params = {
318 'scope': this.getMissingScopes()
319 };
320
321 // Proxy specific attributes through to the signIn options.
322 Object.keys(ProxyLoginAttributes).forEach(function(key) {
323 if (this[key] && this[key] !== '') {
324 params[ProxyLoginAttributes[key]] = this[key];
325 }
326 }, this);
327
328 var promise;
329 var user = gapi.auth2.getAuthInstance().currentUser.get();
330 if (user.getGrantedScopes()) {
331 // additional auth, skip multiple account dialog
332 promise = user.grant(params);
333 } else {
334 // initial signin
335 promise = gapi.auth2.getAuthInstance().signIn(params);
336 }
337 promise.then(
338 function success(newUser) {
339 var authResponse = newUser.getAuthResponse();
340 // Let the current user listener trigger the changes.
341 },
342 function error(error) {
343 if ("Access denied." == error.reason) {
344 // Access denied is not an error, user hit cancel
345 return;
346 } else {
347 console.error(error);
348 }
349 }
350 );
351 },
352
353 /** signs user out */
354 signOut: function() {
355 this.assertAuthInitialized();
356 gapi.auth2.getAuthInstance().signOut().then(
357 function success() {
358 // Let the current user listener trigger the changes.
359 },
360 function error(error) {
361 console.error(error);
362 }
363 );
364 }
365 };
366
367 AuthEngine.init();
368
369 /**
370 `google-signin-aware` is used to enable authentication in custom elements by
371 interacting with a google-signin element that needs to be present somewhere
372 on the page.
373
374 The `scopes` attribute allows you to specify which scope permissions are require d
375 (e.g do you want to allow interaction with the Google Drive API).
376
377 The `google-signin-aware-success` event is triggered when a user successfully
378 authenticates. The `google-signin-aware-signed-out` event is triggered
379 when a user explicitely signs out via the google-signin element.
380
381 You can bind to `isAuthorized` property to monitor authorization state.
382 ##### Example
383
384 <google-signin-aware scopes="https://www.googleapis.com/auth/drive"></google -signin-aware>
385 */
386 Polymer({
387
388 is: 'google-signin-aware',
389
390 /**
391 * Fired when this scope has been authorized
392 * @param {Object} result Authorization result.
393 * @event google-signin-aware-success
394 */
395 /**
396 * Fired when this scope is not authorized
397 * @event google-signin-aware-signed-out
398 */
399 properties: {
400 /**
401 * App package name for android over-the-air installs.
402 * See the relevant [docs](https://developers.google.com/+/web/signin/an droid-app-installs)
403 */
404 appPackageName: {
405 type: String,
406 observer: '_appPackageNameChanged'
407 },
408 /**
409 * a Google Developers clientId reference
410 */
411 clientId: {
412 type: String,
413 observer: '_clientIdChanged'
414 },
415
416 /**
417 * The cookie policy defines what URIs have access to the session cookie
418 * remembering the user's sign-in state.
419 * See the relevant [docs](https://developers.google.com/+/web/signin/re ference#determining_a_value_for_cookie_policy) for more information.
420 * @default 'single_host_origin'
421 */
422 cookiePolicy: {
423 type: String,
424 observer: '_cookiePolicyChanged'
425 },
426
427 /**
428 * The app activity types you want to write on behalf of the user
429 * (e.g http://schemas.google.com/AddActivity)
430 *
431 */
432 requestVisibleActions: {
433 type: String,
434 observer: '_requestVisibleActionsChanged'
435 },
436
437 /**
438 * The scopes to provide access to (e.g https://www.googleapis.com/auth/ drive)
439 * and should be space-delimited.
440 */
441 scopes: {
442 type: String,
443 value: 'profile',
444 observer: '_scopesChanged'
445 },
446
447 /**
448 * True if user is signed in
449 */
450 signedIn: {
451 type: Boolean,
452 notify: true,
453 readOnly: true
454 },
455
456 /**
457 * True if authorizations for *this* element have been granted
458 */
459 isAuthorized: {
460 type: Boolean,
461 notify: true,
462 readOnly: true,
463 value: false
464 },
465
466 /**
467 * True if additional authorizations for *any* element are required
468 */
469 needAdditionalAuth: {
470 type: Boolean,
471 notify: true,
472 readOnly: true
473 },
474
475 /**
476 * True if *any* element has google+ scopes
477 */
478 hasPlusScopes: {
479 type: Boolean,
480 value: false,
481 notify: true,
482 readOnly: true
483 }
484 },
485
486 attached: function() {
487 AuthEngine.attachSigninAware(this);
488 },
489
490 detached: function() {
491 AuthEngine.detachSigninAware(this);
492 },
493
494 /** pops up the authorization dialog */
495 signIn: function() {
496 AuthEngine.signIn();
497 },
498
499 /** signs user out */
500 signOut: function() {
501 AuthEngine.signOut();
502 },
503
504 _appPackageNameChanged: function(newName, oldName) {
505 AuthEngine.appPackageName = newName;
506 },
507
508 _clientIdChanged: function(newId, oldId) {
509 AuthEngine.clientId = newId;
510 },
511
512 _cookiePolicyChanged: function(newPolicy, oldPolicy) {
513 AuthEngine.cookiePolicy = newPolicy;
514 },
515
516 _requestVisibleActionsChanged: function(newVal, oldVal) {
517 AuthEngine.requestVisibleActions = newVal;
518 },
519
520 _scopesChanged: function(newVal, oldVal) {
521 AuthEngine.requestScopes(newVal);
522 this._updateScopeStatus();
523 },
524
525 _updateScopeStatus: function(user) {
526 var newAuthorized = this.signedIn && AuthEngine.hasGrantedScopes(this.sc opes);
527 if (newAuthorized !== this.isAuthorized) {
528 this._setIsAuthorized(newAuthorized);
529 if (newAuthorized) {
530 this.fire('google-signin-aware-success', user);
531 }
532 else {
533 this.fire('google-signin-aware-signed-out', user);
534 }
535 }
536 }
537 });
538 })();
539 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698