Add Switch Account link to the current user popdown

Permit site administrators to configure a URL for users to switch the
current user identity.  CacheBasedWebSession automatically invalidates
the old session (and the cookie and XSRF token) during the switch.

For DEVELOPMENT_BECOME_ANY_ACCOUNT this is a faster way to jump to
another test user as it avoids needing to logout first, saving one
click and a reload of the web UI.

For OPENID the user can select another OpenID user quickly using the
login dialog.  This can be useful if someone has two personas, such as
a personal identity used with open source work and another identity
used for day-job or administrative activities.

On gerrit-review the configuration setting will be set to facilitate
switching between a user's Google Accounts.

Change-Id: I8abd58c06e74f96fef5430324e1c24a787823d35
This commit is contained in:
Shawn Pearce
2013-08-29 23:28:13 -07:00
parent fc43e32efe
commit e0cafe4ecd
7 changed files with 49 additions and 17 deletions

View File

@@ -335,7 +335,17 @@ full name.
+ +
Target for the "Obtain Password" link. Used only when `auth.type` is Target for the "Obtain Password" link. Used only when `auth.type` is
`LDAP`, `LDAP_BIND` or `CUSTOM_EXTENSION`. `LDAP`, `LDAP_BIND` or `CUSTOM_EXTENSION`.
[[auth.switchAccountUrl]]auth.switchAccountUrl::
+ +
URL to switch user identities and login as a different account than
the currently active account. This is disabled by default except when
`auth.type` is `OPENID` and `DEVELOPMENT_BECOME_ANY_ACCOUNT`. If set
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.
[[auth.cookiePath]]auth.cookiePath:: [[auth.cookiePath]]auth.cookiePath::
+ +

View File

@@ -28,6 +28,7 @@ public class GerritConfig implements Cloneable {
protected String registerText; protected String registerText;
protected String loginUrl; protected String loginUrl;
protected String loginText; protected String loginText;
protected String switchAccountUrl;
protected String httpPasswordUrl; protected String httpPasswordUrl;
protected String reportBugUrl; protected String reportBugUrl;
protected boolean gitBasicAuth; protected boolean gitBasicAuth;
@@ -75,6 +76,14 @@ public class GerritConfig implements Cloneable {
registerUrl = u; registerUrl = u;
} }
public String getSwitchAccountUrl() {
return switchAccountUrl;
}
public void setSwitchAccountUrl(String u) {
switchAccountUrl = u;
}
public String getRegisterText() { public String getRegisterText() {
return registerText; return registerText;
} }

View File

@@ -18,9 +18,7 @@ import com.google.gwt.i18n.client.Constants;
public interface GerritConstants extends Constants { public interface GerritConstants extends Constants {
String menuSignIn(); String menuSignIn();
String menuSignOut();
String menuRegister(); String menuRegister();
String menuSettings();
String reportBug(); String reportBug();
String signInDialogTitle(); String signInDialogTitle();

View File

@@ -1,7 +1,5 @@
menuSignIn = Sign In menuSignIn = Sign In
menuSignOut = Sign Out
menuRegister = Register menuRegister = Register
menuSettings = Settings
reportBug = Report Bug reportBug = Report Bug
signInDialogTitle = Code Review - Sign In signInDialogTitle = Code Review - Sign In

View File

@@ -16,11 +16,12 @@ package com.google.gerrit.client;
import com.google.gerrit.client.account.AccountInfo; import com.google.gerrit.client.account.AccountInfo;
import com.google.gerrit.client.ui.InlineHyperlink; import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gerrit.reviewdb.client.AuthType;
import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Element;
import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.Widget;
import com.google.gwtexpui.user.client.PluginSafePopupPanel; import com.google.gwtexpui.user.client.PluginSafePopupPanel;
@@ -33,7 +34,8 @@ public class UserPopupPanel extends PluginSafePopupPanel {
@UiField Label userName; @UiField Label userName;
@UiField Label userEmail; @UiField Label userEmail;
@UiField Element userLinks; @UiField Element userLinks;
@UiField Anchor logout; @UiField AnchorElement switchAccount;
@UiField AnchorElement logout;
@UiField InlineHyperlink settings; @UiField InlineHyperlink settings;
public UserPopupPanel(AccountInfo account, boolean canLogOut, public UserPopupPanel(AccountInfo account, boolean canLogOut,
@@ -49,11 +51,22 @@ public class UserPopupPanel extends PluginSafePopupPanel {
userEmail.setText(account.email()); userEmail.setText(account.email());
} }
if (showSettingsLink) { if (showSettingsLink) {
if (Gerrit.getConfig().getSwitchAccountUrl() != null) {
switchAccount.setHref(Gerrit.getConfig().getSwitchAccountUrl());
} else if (Gerrit.getConfig().getAuthType() == AuthType.DEVELOPMENT_BECOME_ANY_ACCOUNT
|| Gerrit.getConfig().getAuthType() == AuthType.OPENID) {
switchAccount.setHref(Gerrit.selfRedirect("/login/"));
} else {
switchAccount.removeFromParent();
switchAccount = null;
}
if (canLogOut) { if (canLogOut) {
logout.setHref(Gerrit.selfRedirect("/logout")); logout.setHref(Gerrit.selfRedirect("/logout"));
} else { } else {
logout.setVisible(false); logout.removeFromParent();
logout = null;
} }
} else { } else {
settings.removeFromParent(); settings.removeFromParent();
settings = null; settings = null;

View File

@@ -19,8 +19,6 @@ limitations under the License.
xmlns:g='urn:import:com.google.gwt.user.client.ui' xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:gerrit='urn:import:com.google.gerrit.client' xmlns:gerrit='urn:import:com.google.gerrit.client'
xmlns:u='urn:import:com.google.gerrit.client.ui'> xmlns:u='urn:import:com.google.gerrit.client.ui'>
<ui:with field='constants' type='com.google.gerrit.client.GerritConstants'/>
<ui:style> <ui:style>
.panel { .panel {
padding: 8px; padding: 8px;
@@ -36,16 +34,20 @@ limitations under the License.
.userName { .userName {
font-weight: bold; font-weight: bold;
} }
.userLinks {
min-width: 175px;
}
.email { .email {
padding-bottom: 6px; padding-bottom: 6px;
} }
.logout { .userLinks {
padding-left: 16px; min-width: 250px;
}
.userLinksRight {
float: right; float: right;
} }
.switchAccount {
border-right: 1px solid black;
padding-right: 0.5em;
margin-right: 0.5em;
}
</ui:style> </ui:style>
<g:HTMLPanel styleName='{style.panel}'> <g:HTMLPanel styleName='{style.panel}'>
@@ -59,9 +61,10 @@ limitations under the License.
<u:InlineHyperlink ui:field='settings' targetHistoryToken='/settings/'> <u:InlineHyperlink ui:field='settings' targetHistoryToken='/settings/'>
<ui:msg>Settings</ui:msg> <ui:msg>Settings</ui:msg>
</u:InlineHyperlink> </u:InlineHyperlink>
<g:Anchor ui:field='logout' styleName="{style.logout}"> <span class='{style.userLinksRight}'>
<ui:text from='{constants.menuSignOut}' /> <a ui:field='switchAccount' class='{style.switchAccount}'><ui:msg>Switch Account</ui:msg></a
</g:Anchor> ><a ui:field='logout'><ui:msg>Sign Out</ui:msg></a>
</span>
</div> </div>
</g:HTMLPanel> </g:HTMLPanel>
</ui:UiBinder> </ui:UiBinder>

View File

@@ -106,6 +106,7 @@ class GerritConfigProvider implements Provider<GerritConfig> {
case OPENID_SSO: case OPENID_SSO:
break; break;
} }
config.setSwitchAccountUrl(cfg.getString("auth", null, "switchAccountUrl"));
config.setUseContributorAgreements(cfg.getBoolean("auth", config.setUseContributorAgreements(cfg.getBoolean("auth",
"contributoragreements", false)); "contributoragreements", false));
config.setGitDaemonUrl(cfg.getString("gerrit", null, "canonicalgiturl")); config.setGitDaemonUrl(cfg.getString("gerrit", null, "canonicalgiturl"));