diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt index a60cb4aaef..e6ad3dbae8 100644 --- a/Documentation/config-gerrit.txt +++ b/Documentation/config-gerrit.txt @@ -397,8 +397,14 @@ the currently active account. This is disabled by default except when the "Switch Account" link is displayed next to "Sign Out". + When `auth.type` does not normally enable this URL administrators may -set this to `login/` or `$canonicalWebUrl/login`, allowing users to -begin a new web session. +set this to `login/`, allowing users to begin a new web session. This value +is used as an href in PolyGerrit and the GWT UI, so absolute URLs like +`https://someotherhost/login` work as well. ++ +If a ${path} parameter is included, then PolyGerrit will substitute the +currently viewed path in the link. Be aware that this path will include +a leading slash, so a value like this might be appropriate: `/login${path}`. +Note: in the GWT UI this substitution for ${path} is *always* `/`. [[auth.cookiePath]]auth.cookiePath:: + diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.java index 40116af9d3..cb529f4518 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.java @@ -52,8 +52,9 @@ public class UserPopupPanel extends PopupPanel { userEmail.setText(account.email()); } if (showSettingsLink) { - if (Gerrit.info().auth().switchAccountUrl() != null) { - switchAccount.setHref(Gerrit.info().auth().switchAccountUrl()); + String switchAccountUrl = Gerrit.info().auth().switchAccountUrl(); + if (switchAccountUrl != null) { + switchAccount.setHref(switchAccountUrl.replace("${path}", "/")); } else if (Gerrit.info().auth().isDev() || Gerrit.info().auth().isOpenId()) { switchAccount.setHref(Gerrit.selfRedirect("/login")); } else { diff --git a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.js b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.js index 4011135202..8a8ceafdb1 100644 --- a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.js +++ b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.js @@ -14,37 +14,75 @@ (function() { 'use strict'; + var INTERPOLATE_URL_PATTERN = /\$\{([\w]+)\}/g; + Polymer({ is: 'gr-account-dropdown', properties: { account: Object, - _hasAvatars: Boolean, links: { type: Array, - value: [ - {name: 'Settings', url: '/settings'}, - {name: 'Switch account', url: '/switch-account'}, - {name: 'Sign out', url: '/logout'}, - ], + computed: '_getLinks(_switchAccountUrl)', }, topContent: { type: Array, computed: '_getTopContent(account)', }, + _path: { + type: String, + value: '/', + }, + _hasAvatars: Boolean, + _switchAccountUrl: String, }, attached: function() { + this._handleLocationChange(); + this.listen(window, 'location-change', '_handleLocationChange'); this.$.restAPI.getConfig().then(function(cfg) { + if (cfg && cfg.auth && cfg.auth.switch_account_url) { + this._switchAccountUrl = cfg.auth.switch_account_url; + } else { + this._switchAccountUrl = null; + } this._hasAvatars = !!(cfg && cfg.plugin && cfg.plugin.has_avatars); }.bind(this)); }, + detached: function() { + this.unlisten(window, 'location-change', '_handleLocationChange'); + }, + + _getLinks: function(switchAccountUrl) { + var links = [{name: 'Settings', url: '/settings'}]; + if (switchAccountUrl) { + var replacements = {path: this._path}; + var url = this._interpolateUrl(switchAccountUrl, replacements); + links.push({name: 'Switch account', url: url}); + } + links.push({name: 'Sign out', url: '/logout'}); + return links; + }, + _getTopContent: function(account) { return [ {text: account.name, bold: true}, {text: account.email}, ]; }, + + _handleLocationChange: function() { + this._path = + window.location.pathname + + window.location.search + + window.location.hash; + }, + + _interpolateUrl: function(url, replacements) { + return url.replace(INTERPOLATE_URL_PATTERN, function(match, p1) { + return replacements[p1] || ''; + }); + }, }); })(); diff --git a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.html b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.html index ec9141ff76..8ea4701d72 100644 --- a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.html +++ b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.html @@ -46,5 +46,39 @@ limitations under the License. assert.deepEqual(element.topContent, [{text: 'John Doe', bold: true}, {text: 'john@doe.com'}]); }); + + test('switch account', function() { + // No switch account link. + assert.equal(element._getLinks(null).length, 2); + + // Unparameterized switch account link. + var links = element._getLinks('/switch-account'); + assert.equal(links.length, 3); + assert.deepEqual(links[1], + {name: 'Switch account', url: '/switch-account'}); + + // Parameterized switch account link. + element._path = '/c/123'; + links = element._getLinks('/switch-account${path}'); + assert.equal(links.length, 3); + assert.deepEqual(links[1], + {name: 'Switch account', url: '/switch-account/c/123'}); + }); + + test('_interpolateUrl', function() { + var replacements = { + 'foo': 'bar', + 'test': 'TEST', + }; + var interpolate = function(url) { + return element._interpolateUrl(url, replacements); + }; + + assert.equal(interpolate('test'), 'test'); + assert.equal(interpolate('${test}'), 'TEST'); + assert.equal( + interpolate('${}, ${test}, ${TEST}, ${foo}'), + '${}, TEST, , bar'); + }); });