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

Unified Diff: appengine/config_service/ui/common/third-party/google-signin-aware.html

Issue 2962703003: config_service: Add authentication to the UI. (Closed)
Patch Set: Added TODO to handlers.py and confirmed versions in bower.json Created 3 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 side-by-side diff with in-line comments
Download patch
Index: appengine/config_service/ui/common/third-party/google-signin-aware.html
diff --git a/appengine/config_service/ui/common/third-party/google-signin-aware.html b/appengine/config_service/ui/common/third-party/google-signin-aware.html
deleted file mode 100644
index e6e731bfad1a7417e19f977e4944c011a4a2f6bd..0000000000000000000000000000000000000000
--- a/appengine/config_service/ui/common/third-party/google-signin-aware.html
+++ /dev/null
@@ -1,824 +0,0 @@
-<!--
-Copyright 2014 Google Inc
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- https://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<link rel="import" href="../polymer/polymer.html">
-<link rel="import" href="../google-apis/google-js-api.html">
-
-<script>
- (function() {
-
- /**
- * Enum of attributes to be passed through to the login API call.
- * @readonly
- * @enum {string}
- */
- var ProxyLoginAttributes = {
- 'appPackageName': 'apppackagename',
- 'clientId': 'clientid',
- 'cookiePolicy': 'cookiepolicy',
- 'hostedDomain': 'hostedDomain',
- 'openidPrompt': 'prompt',
- 'requestVisibleActions': 'requestvisibleactions'
- };
-
- /**
- * AuthEngine does all interactions with gapi.auth2
- *
- * It is tightly coupled with <google-signin-aware> element
- * The elements configure AuthEngine.
- * AuthEngine propagates all authentication events to all google-signin-aware elements
- *
- * API used: https://developers.google.com/identity/sign-in/web/reference
- *
- */
- var AuthEngine = {
-
- /**
- * oauth2 argument, set by google-signin-aware
- */
- _clientId: null,
-
- get clientId() {
- return this._clientId;
- },
-
- set clientId(val) {
- if (this._clientId && val && val != this._clientId) {
- throw new Error('clientId cannot change. Values do not match. New: ' + val + ' Old:' + this._clientId);
- }
- if (val && val != this._clientId) {
- this._clientId = val;
- this.initAuth2();
- }
- },
-
- /**
- * oauth2 argument, set by google-signin-aware
- */
- _cookiePolicy: 'single_host_origin',
-
- get cookiePolicy() {
- return this._cookiePolicy;
- },
-
- set cookiePolicy(val) {
- if (val) {
- this._cookiePolicy = val;
- }
- },
-
- /**
- * oauth2 argument, set by google-signin-aware
- */
- _appPackageName: '',
-
- get appPackageName() {
- return this._appPackageName;
- },
-
- set appPackageName(val) {
- if (this._appPackageName && val && val != this._appPackageName) {
- throw new Error('appPackageName cannot change. Values do not match. New: ' + val + ' Old: ' + this._appPackageName);
- }
- if (val) {
- this._appPackageName = val;
- }
- },
-
- /**
- * oauth2 argument, set by google-signin-aware
- */
- _requestVisibleActions: '',
-
- get requestVisibleactions() {
- return this._requestVisibleActions;
- },
-
- set requestVisibleactions(val) {
- if (this._requestVisibleActions && val && val != this._requestVisibleActions) {
- throw new Error('requestVisibleactions cannot change. Values do not match. New: ' + val + ' Old: ' + this._requestVisibleActions);
- }
- if (val)
- this._requestVisibleActions = val;
- },
-
- /**
- * oauth2 argument, set by google-signin-aware
- */
- _hostedDomain: '',
-
- get hostedDomain() {
- return this._hostedDomain;
- },
-
- set hostedDomain(val) {
- if (this._hostedDomain && val && val != this._hostedDomain) {
- throw new Error('hostedDomain cannot change. Values do not match. New: ' + val + ' Old: ' + this._hostedDomain);
- }
- if (val)
- this._hostedDomain = val;
- },
-
- /**
- * oauth2 argument, set by google-signin-aware
- */
- _openidPrompt: '',
-
- get openidPrompt() {
- return this._openidPrompt;
- },
-
- set openidPrompt(val) {
- if (typeof val !== 'string') {
- throw new Error(
- 'openidPrompt must be a string. Received ' + typeof val);
- }
- if (val) {
- var values = val.split(' ');
- values = values.map(function(v) {
- return v.trim();
- });
- values = values.filter(function(v) {
- return v;
- });
- var validValues = {none: 0, login: 0, consent: 0, select_account: 0};
- values.forEach(function(v) {
- if (v == 'none' && values.length > 1) {
- throw new Error(
- 'none cannot be combined with other openidPrompt values');
- }
- if (!(v in validValues)) {
- throw new Error(
- 'invalid openidPrompt value ' + v +
- '. Valid values: ' + Object.keys(validValues).join(', '));
- }
- });
- }
- this._openidPrompt = val;
- },
-
- /** Is offline access currently enabled in the google-signin-aware element? */
- _offline: false,
-
- get offline() {
- return this._offline;
- },
-
- set offline(val) {
- this._offline = val;
- this.updateAdditionalAuth();
- },
-
- /** Should we force a re-prompt for offline access? */
- _offlineAlwaysPrompt: false,
-
- get offlineAlwaysPrompt() {
- return this._offlineAlwaysPrompt;
- },
-
- set offlineAlwaysPrompt(val) {
- this._offlineAlwaysPrompt = val;
- this.updateAdditionalAuth();
- },
-
- /** Have we already gotten offline access from Google during this session? */
- offlineGranted: false,
-
- /** <google-js-api> */
- _apiLoader: null,
-
- /** an array of wanted scopes. oauth2 argument */
- _requestedScopeArray: [],
-
- /** _requestedScopeArray as string */
- get requestedScopes() {
- return this._requestedScopeArray.join(' ');
- },
-
- /** Is auth library initalized? */
- _initialized: false,
-
- /** Is user signed in? */
- _signedIn: false,
-
- /** Currently granted scopes */
- _grantedScopeArray: [],
-
- /** True if additional authorization is required */
- _needAdditionalAuth: true,
-
- /** True if have google+ scopes */
- _hasPlusScopes: false,
-
- /**
- * array of <google-signin-aware>
- * state changes are broadcast to them
- */
- signinAwares: [],
-
- init: function() {
- this._apiLoader = document.createElement('google-js-api');
- this._apiLoader.addEventListener('js-api-load', this.loadAuth2.bind(this));
- if (Polymer.Element) {
- document.body.appendChild(this._apiLoader);
- }
- },
-
- loadAuth2: function() {
- gapi.load('auth2', this.initAuth2.bind(this));
- },
-
- initAuth2: function() {
- if (!('gapi' in window) || !('auth2' in window.gapi) || !this.clientId) {
- return;
- }
- var auth = gapi.auth2.init({
- 'client_id': this.clientId,
- 'cookie_policy': this.cookiePolicy,
- 'scope': this.requestedScopes,
- 'hosted_domain': this.hostedDomain
- });
-
- auth['currentUser'].listen(this.handleUserUpdate.bind(this));
-
- auth.then(
- function onFulfilled() {
- // Let the current user listener trigger the changes.
- },
- function onRejected(error) {
- console.error(error);
- }
- );
- },
-
- handleUserUpdate: function(newPrimaryUser) {
- // update and broadcast currentUser
- var isSignedIn = newPrimaryUser.isSignedIn();
- if (isSignedIn != this._signedIn) {
- this._signedIn = isSignedIn;
- for (var i=0; i<this.signinAwares.length; i++) {
- this.signinAwares[i]._setSignedIn(isSignedIn);
- }
- }
- // update and broadcast initialized property the first time the isSignedIn property is set.
- if(!this._initialized) {
- for (var i=0; i<this.signinAwares.length; i++) {
- this.signinAwares[i]._setInitialized(true);
- }
- this._initialized = true;
- }
-
-
- // update granted scopes
- this._grantedScopeArray = this.strToScopeArray(
- newPrimaryUser.getGrantedScopes());
- // console.log(this._grantedScopeArray);
- this.updateAdditionalAuth();
-
- var response = newPrimaryUser.getAuthResponse();
- for (var i=0; i<this.signinAwares.length; i++) {
- this.signinAwares[i]._updateScopeStatus(response);
- }
- },
-
- setOfflineCode: function(code) {
- for (var i=0; i<this.signinAwares.length; i++) {
- this.signinAwares[i]._updateOfflineCode(code);
- }
- },
-
- /** convert scope string to scope array */
- strToScopeArray: function(str) {
- if (!str) {
- return [];
- }
- // remove extra spaces, then split
- var scopes = str.replace(/\ +/g, ' ').trim().split(' ');
- for (var i=0; i<scopes.length; i++) {
- scopes[i] = scopes[i].toLowerCase();
- // Handle scopes that will be deprecated but are still returned with their old value
- if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.profile') {
- scopes[i] = 'profile';
- }
- if (scopes[i] === 'https://www.googleapis.com/auth/userinfo.email') {
- scopes[i] = 'email';
- }
- }
- // return with duplicates filtered out
- return scopes.filter( function(value, index, self) {
- return self.indexOf(value) === index;
- });
- },
-
- /** true if scopes have google+ scopes */
- isPlusScope: function(scope) {
- return (scope.indexOf('/auth/games') > -1)
- || (scope.indexOf('auth/plus.') > -1 && scope.indexOf('auth/plus.me') < 0);
- },
-
- /** true if scopes have been granted */
- hasGrantedScopes: function(scopeStr) {
- var scopes = this.strToScopeArray(scopeStr);
- for (var i=0; i< scopes.length; i++) {
- if (this._grantedScopeArray.indexOf(scopes[i]) === -1)
- return false;
- }
- return true;
- },
-
- /** request additional scopes */
- requestScopes: function(newScopeStr) {
- var newScopes = this.strToScopeArray(newScopeStr);
- var scopesUpdated = false;
- for (var i=0; i<newScopes.length; i++) {
- if (this._requestedScopeArray.indexOf(newScopes[i]) === -1) {
- this._requestedScopeArray.push(newScopes[i]);
- scopesUpdated = true;
- }
- }
- if (scopesUpdated) {
- this.updateAdditionalAuth();
- this.updatePlusScopes();
- }
- },
-
- /** update status of _needAdditionalAuth */
- updateAdditionalAuth: function() {
- var needMoreAuth = false;
- if ((this.offlineAlwaysPrompt || this.offline ) && !this.offlineGranted) {
- needMoreAuth = true;
- } else {
- for (var i=0; i<this._requestedScopeArray.length; i++) {
- if (this._grantedScopeArray.indexOf(this._requestedScopeArray[i]) === -1) {
- needMoreAuth = true;
- break;
- }
- }
- }
- if (this._needAdditionalAuth != needMoreAuth) {
- this._needAdditionalAuth = needMoreAuth;
- // broadcast new value
- for (var i=0; i<this.signinAwares.length; i++) {
- this.signinAwares[i]._setNeedAdditionalAuth(needMoreAuth);
- }
- }
- },
-
- updatePlusScopes: function() {
- var hasPlusScopes = false;
- for (var i = 0; i < this._requestedScopeArray.length; i++) {
- if (this.isPlusScope(this._requestedScopeArray[i])) {
- hasPlusScopes = true;
- break;
- }
- }
- if (this._hasPlusScopes != hasPlusScopes) {
- this._hasPlusScopes = hasPlusScopes;
- for (var i=0; i<this.signinAwares.length; i++) {
- this.signinAwares[i]._setHasPlusScopes(hasPlusScopes);
- }
- }
- },
- /**
- * attached <google-signin-aware>
- * @param {!GoogleSigninAwareElement} aware element to add
- */
- attachSigninAware: function(aware) {
- if (this.signinAwares.indexOf(aware) == -1) {
- this.signinAwares.push(aware);
- // Initialize aware properties
- aware._setNeedAdditionalAuth(this._needAdditionalAuth);
- aware._setInitialized(this._initialized);
- aware._setSignedIn(this._signedIn);
- aware._setHasPlusScopes(this._hasPlusScopes);
- } else {
- console.warn('signinAware attached more than once', aware);
- }
- },
-
- detachSigninAware: function(aware) {
- var index = this.signinAwares.indexOf(aware);
- if (index != -1) {
- this.signinAwares.splice(index, 1);
- } else {
- console.warn('Trying to detach unattached signin-aware');
- }
- },
-
- /** returns scopes not granted */
- getMissingScopes: function() {
- return this._requestedScopeArray.filter( function(scope) {
- return this._grantedScopeArray.indexOf(scope) === -1;
- }.bind(this)).join(' ');
- },
-
- assertAuthInitialized: function() {
- if (!this.clientId) {
- throw new Error("AuthEngine not initialized. clientId has not been configured.");
- }
- if (!('gapi' in window)) {
- throw new Error("AuthEngine not initialized. gapi has not loaded.");
- }
- if (!('auth2' in window.gapi)) {
- throw new Error("AuthEngine not initialized. auth2 not loaded.");
- }
- },
-
- /** pops up sign-in dialog */
- signIn: function() {
- this.assertAuthInitialized();
- var params = {
- 'scope': this.getMissingScopes()
- };
-
- // Proxy specific attributes through to the signIn options.
- Object.keys(ProxyLoginAttributes).forEach(function(key) {
- if (this[key] && this[key] !== '') {
- params[ProxyLoginAttributes[key]] = this[key];
- }
- }, this);
-
- var promise;
- var user = gapi.auth2.getAuthInstance()['currentUser'].get();
- if (!(this.offline || this.offlineAlwaysPrompt)) {
- if (user.getGrantedScopes()) {
- // additional auth, skip multiple account dialog
- promise = user.grant(params);
- } else {
- // initial signin
- promise = gapi.auth2.getAuthInstance().signIn(params);
- }
- } else {
- params.redirect_uri = 'postmessage';
- if (this.offlineAlwaysPrompt) {
- params.approval_prompt = 'force';
- }
-
- // Despite being documented at https://goo.gl/tiO0Bk
- // It doesn't seem like user.grantOfflineAccess() actually exists in
- // the current version of the Google Sign-In JS client we're using
- // through GoogleWebComponents. So in the offline case, we will not
- // distinguish between a first auth and an additional one.
- promise = gapi.auth2.getAuthInstance().grantOfflineAccess(params);
- }
- promise.then(
- function onFulfilled(response) {
- // If login was offline, response contains one string "code"
- // Otherwise it contains the user object already
- var newUser;
- if (response.code) {
- AuthEngine.offlineGranted = true;
- newUser = gapi.auth2.getAuthInstance()['currentUser'].get();
- AuthEngine.setOfflineCode(response.code);
- } else {
- newUser = response;
- }
-
- var authResponse = newUser.getAuthResponse();
- // Let the current user listener trigger the changes.
- },
- function onRejected(error) {
- // Access denied is not an error, user hit cancel
- if ("Access denied." !== error.reason) {
- this.signinAwares.forEach(function(awareInstance) {
- awareInstance.errorNotify(error);
- });
- }
- }.bind(this)
- );
- },
-
- /** signs user out */
- signOut: function() {
- this.assertAuthInitialized();
- gapi.auth2.getAuthInstance().signOut().then(
- function onFulfilled() {
- // Let the current user listener trigger the changes.
- },
- function onRejected(error) {
- console.error(error);
- }
- );
- }
- };
-
- AuthEngine.init();
-
-/**
-`google-signin-aware` is used to enable authentication in custom elements by
-interacting with a google-signin element that needs to be present somewhere
-on the page.
-
-The `scopes` attribute allows you to specify which scope permissions are required
-(e.g do you want to allow interaction with the Google Drive API).
-
-The `google-signin-aware-success` event is triggered when a user successfully
-authenticates. If either `offline` or `offlineAlwaysPrompt` is set to true, successful
-authentication will also trigger the `google-signin-offline-success`event.
-The `google-signin-aware-signed-out` event is triggered when a user explicitly
-signs out via the google-signin element.
-
-You can bind to `isAuthorized` property to monitor authorization state.
-##### Example
-
- <google-signin-aware scopes="https://www.googleapis.com/auth/drive"></google-signin-aware>
-
-
-##### Example with offline
- <template id="awareness" is="dom-bind">
- <google-signin-aware
- scopes="https://www.googleapis.com/auth/drive"
- offline
- on-google-signin-aware-success="handleSignin"
- on-google-signin-offline-success="handleOffline"></google-signin-aware>
- <\/template>
- <script>
- var aware = document.querySelector('#awareness');
- aware.handleSignin = function(response) {
- var user = gapi.auth2.getAuthInstance()['currentUser'].get();
- console.log('User name: ' + user.getBasicProfile().getName());
- };
- aware.handleOffline = function(response) {
- console.log('Offline code received: ' + response.detail.code);
- // Here you would POST response.detail.code to your webserver, which can
- // exchange the authorization code for an access token. More info at:
- // https://developers.google.com/identity/protocols/OAuth2WebServer
- };
- <\/script>
-*/
- Polymer({
-
- is: 'google-signin-aware',
-
- /**
- * Fired when this scope has been authorized
- * @param {Object} result Authorization result.
- * @event google-signin-aware-success
- */
-
- /**
- * Fired when an offline authorization is successful.
- * @param {{code: string}} detail -
- * code: The one-time authorization code from Google.
- * Your application can exchange this for an `access_token` and `refresh_token`
- * @event google-signin-offline-success
- */
-
- /**
- * Fired when this scope is not authorized
- * @event google-signin-aware-signed-out
- */
-
- /**
- * Fired when there is an error during the signin flow.
- * @param {Object} detail The error object returned from the OAuth 2 flow.
- * @event google-signin-aware-error
- */
-
- /**
- * This block is needed so the previous @param is not assigned to the next property.
- */
-
- properties: {
- /**
- * App package name for android over-the-air installs.
- * See the relevant [docs](https://developers.google.com/+/web/signin/android-app-installs)
- */
- appPackageName: {
- type: String,
- observer: '_appPackageNameChanged'
- },
-
- /**
- * a Google Developers clientId reference
- */
- clientId: {
- type: String,
- observer: '_clientIdChanged'
- },
-
- /**
- * The cookie policy defines what URIs have access to the session cookie
- * remembering the user's sign-in state.
- * See the relevant [docs](https://developers.google.com/+/web/signin/reference#determining_a_value_for_cookie_policy) for more information.
- * @default 'single_host_origin'
- */
- cookiePolicy: {
- type: String,
- observer: '_cookiePolicyChanged'
- },
-
- /**
- * The app activity types you want to write on behalf of the user
- * (e.g http://schemas.google.com/AddActivity)
- *
- */
- requestVisibleActions: {
- type: String,
- observer: '_requestVisibleActionsChanged'
- },
-
- /**
- * The Google Apps domain to which users must belong to sign in.
- * See the relevant [docs](https://developers.google.com/identity/sign-in/web/reference) for more information.
- */
- hostedDomain: {
- type: String,
- observer: '_hostedDomainChanged'
- },
-
- /**
- * Allows for offline `access_token` retrieval during the signin process.
- * See also `offlineAlwaysPrompt`. You only need to set one of the two; if both
- * are set, the behavior of `offlineAlwaysPrompt` will override `offline`.
- */
- offline: {
- type: Boolean,
- value: false,
- observer: '_offlineChanged'
- },
-
- /**
- * Works the same as `offline` with the addition that it will always
- * force a re-prompt to the user, guaranteeing that you will get a
- * refresh_token even if the user has already granted offline access to
- * this application. You only need to set one of `offline` or
- * `offlineAlwaysPrompt`, not both.
- */
- offlineAlwaysPrompt: {
- type: Boolean,
- value: false,
- observer: '_offlineAlwaysPromptChanged'
- },
-
- /**
- * The scopes to provide access to (e.g https://www.googleapis.com/auth/drive)
- * and should be space-delimited.
- */
- scopes: {
- type: String,
- value: 'profile',
- observer: '_scopesChanged'
- },
-
- /**
- * Space-delimited, case-sensitive list of strings that
- * specifies whether the the user is prompted for reauthentication
- * and/or consent. The defined values are:
- * none: do not display authentication or consent pages.
- * This value is mutually exclusive with the rest.
- * login: always prompt the user for reauthentication.
- * consent: always show consent screen.
- * select_account: always show account selection page.
- * This enables a user who has multiple accounts to select amongst
- * the multiple accounts that they might have current sessions for.
- * For more information, see "prompt" parameter description in
- * https://openid.net/specs/openid-connect-basic-1_0.html#RequestParameters
- */
- openidPrompt: {
- type: String,
- value: '',
- observer: '_openidPromptChanged'
- },
-
- /**
- * True when the auth library has been initialized, and signedIn property value is set from the first api response.
- */
- initialized: {
- type: Boolean,
- notify: true,
- readOnly: true
- },
-
- /**
- * True if user is signed in
- */
- signedIn: {
- type: Boolean,
- notify: true,
- readOnly: true
- },
-
- /**
- * True if authorizations for *this* element have been granted
- */
- isAuthorized: {
- type: Boolean,
- notify: true,
- readOnly: true,
- value: false
- },
-
- /**
- * True if additional authorizations for *any* element are required
- */
- needAdditionalAuth: {
- type: Boolean,
- notify: true,
- readOnly: true
- },
-
- /**
- * True if *any* element has google+ scopes
- */
- hasPlusScopes: {
- type: Boolean,
- value: false,
- notify: true,
- readOnly: true
- }
- },
-
- attached: function() {
- AuthEngine.attachSigninAware(this);
- },
-
- detached: function() {
- AuthEngine.detachSigninAware(this);
- },
-
- /** pops up the authorization dialog */
- signIn: function() {
- AuthEngine.signIn();
- },
-
- /** signs user out */
- signOut: function() {
- AuthEngine.signOut();
- },
-
- errorNotify: function(error) {
- this.fire('google-signin-aware-error', error);
- },
-
- _appPackageNameChanged: function(newName, oldName) {
- AuthEngine.appPackageName = newName;
- },
-
- _clientIdChanged: function(newId, oldId) {
- AuthEngine.clientId = newId;
- },
-
- _cookiePolicyChanged: function(newPolicy, oldPolicy) {
- AuthEngine.cookiePolicy = newPolicy;
- },
-
- _requestVisibleActionsChanged: function(newVal, oldVal) {
- AuthEngine.requestVisibleActions = newVal;
- },
-
- _hostedDomainChanged: function(newVal, oldVal) {
- AuthEngine.hostedDomain = newVal;
- },
-
- _offlineChanged: function(newVal, oldVal) {
- AuthEngine.offline = newVal;
- },
-
- _offlineAlwaysPromptChanged: function(newVal, oldVal) {
- AuthEngine.offlineAlwaysPrompt = newVal;
- },
-
- _scopesChanged: function(newVal, oldVal) {
- AuthEngine.requestScopes(newVal);
- this._updateScopeStatus(undefined);
- },
-
- _openidPromptChanged: function(newVal, oldVal) {
- AuthEngine.openidPrompt = newVal;
- },
-
- _updateScopeStatus: function(user) {
- var newAuthorized = this.signedIn && AuthEngine.hasGrantedScopes(this.scopes);
- if (newAuthorized !== this.isAuthorized) {
- this._setIsAuthorized(newAuthorized);
- if (newAuthorized) {
- this.fire('google-signin-aware-success', user);
- }
- else {
- this.fire('google-signin-aware-signed-out', user);
- }
- }
- },
-
- _updateOfflineCode: function(code) {
- if (code) {
- this.fire('google-signin-offline-success', {code: code});
- }
- }
- });
- })();
-</script>

Powered by Google App Engine
This is Rietveld 408576698