Add OpenID SSO support.
Configuring OPENID_SSO in gerrit.config will allow the admin
to specify an SSO entry point URL so that users clicking on
"Sign In" are sent directly to that URL.
Change-Id: I361b7b74a6f34a199578620540be31d1df0c5fef
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 0435f4e..8c291c7 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -88,6 +88,12 @@
provider chosen by the end-user. For more information see
http://openid.net/[openid.net].
+
+* `OpenID_SSO`
++
+Supports OpenID from a single provider. There is no registration
+link, and the "Sign In" link sends the user directly to the provider's
+SSO entry point.
++
* `HTTP`
+
Gerrit relies upon data presented in the HTTP request. This includes
@@ -229,6 +235,13 @@
+
Default is 12 hours.
+[[auth.openIdSsoUrl]]auth.openIdSsoUrl::
++
+The SSO entry point URL. Only used if `auth.type` was set to
+OpenID_SSO.
++
+The "Sign In" link will send users directly to this URL.
+
[[auth.httpHeader]]auth.httpHeader::
+
HTTP header to trust the username from, or unset to select HTTP basic
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
index 07a8534..89de3b4 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
@@ -28,6 +28,7 @@
public class GerritConfig implements Cloneable {
protected String registerUrl;
protected String httpPasswordUrl;
+ protected String openIdSsoUrl;
protected List<OpenIdProviderPattern> allowedOpenIDs;
protected GitwebConfig gitweb;
@@ -72,6 +73,14 @@
httpPasswordUrl = url;
}
+ public String getOpenIdSsoUrl() {
+ return openIdSsoUrl;
+ }
+
+ public void setOpenIdSsoUrl(final String u) {
+ openIdSsoUrl = u;
+ }
+
public List<OpenIdProviderPattern> getAllowedOpenIDs() {
return allowedOpenIDs;
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
index 5c2a3190..091fbdc 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
@@ -15,6 +15,7 @@
package com.google.gerrit.client;
import com.google.gerrit.client.auth.openid.OpenIdSignInDialog;
+import com.google.gerrit.client.auth.openid.OpenIdSsoPanel;
import com.google.gerrit.client.auth.userpass.UserPassSignInDialog;
import com.google.gerrit.client.changes.ChangeConstants;
import com.google.gerrit.client.changes.ChangeListScreen;
@@ -255,6 +256,13 @@
Location.assign(selfRedirect("/become"));
break;
+ case OPENID_SSO:
+ final RootPanel gBody = RootPanel.get("gerrit_body");
+ OpenIdSsoPanel singleSignOnPanel = new OpenIdSsoPanel();
+ gBody.add(singleSignOnPanel);
+ singleSignOnPanel.authenticate(SignInMode.SIGN_IN, token);
+ break;
+
case OPENID:
new OpenIdSignInDialog(SignInMode.SIGN_IN, token, null).center();
break;
@@ -617,6 +625,14 @@
});
break;
+ case OPENID_SSO:
+ menuRight.addItem(C.menuSignIn(), new Command() {
+ public void execute() {
+ doSignIn(History.getToken());
+ }
+ });
+ break;
+
case LDAP:
case LDAP_BIND:
case CUSTOM_EXTENSION:
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/auth/openid/OpenIdSsoPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/auth/openid/OpenIdSsoPanel.java
new file mode 100644
index 0000000..3dd54a7
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/auth/openid/OpenIdSsoPanel.java
@@ -0,0 +1,70 @@
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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
+//
+// http://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.
+
+package com.google.gerrit.client.auth.openid;
+
+import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.rpc.GerritCallback;
+import com.google.gerrit.client.ui.SmallHeading;
+import com.google.gerrit.common.auth.SignInMode;
+import com.google.gerrit.common.auth.openid.DiscoveryResult;
+import com.google.gerrit.common.auth.openid.OpenIdUrls;
+import com.google.gwt.dom.client.FormElement;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.FormPanel;
+import com.google.gwt.user.client.ui.Hidden;
+
+import java.util.Map;
+
+public class OpenIdSsoPanel extends FlowPanel {
+ private final FormPanel redirectForm;
+ private final FlowPanel redirectBody;
+ private final String ssoUrl;
+
+ public OpenIdSsoPanel() {
+ super();
+ redirectBody = new FlowPanel();
+ redirectBody.setVisible(false);
+ redirectForm = new FormPanel();
+ redirectForm.add(redirectBody);
+
+ add(redirectForm);
+
+ ssoUrl = Gerrit.getConfig().getOpenIdSsoUrl();
+ }
+
+ public void authenticate(SignInMode requestedMode, final String token) {
+ OpenIdUtil.SVC.discover(ssoUrl, requestedMode, /* remember */ false, token,
+ new GerritCallback<DiscoveryResult>() {
+ public void onSuccess(final DiscoveryResult result) {
+ onDiscovery(result);
+ }
+ });
+ }
+
+ private void onDiscovery(final DiscoveryResult result) {
+ switch (result.status) {
+ case VALID:
+ redirectForm.setMethod(FormPanel.METHOD_POST);
+ redirectForm.setAction(result.providerUrl);
+ redirectBody.clear();
+ for (final Map.Entry<String, String> e : result.providerArgs.entrySet()) {
+ redirectBody.add(new Hidden(e.getKey(), e.getValue()));
+ }
+ FormElement.as(redirectForm.getElement()).setTarget("_top");
+ redirectForm.submit();
+ break;
+ }
+ }
+}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
index f92f13d..72bb0c2 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
@@ -90,6 +90,10 @@
config.setAllowedOpenIDs(authConfig.getAllowedOpenIDs());
break;
+ case OPENID_SSO:
+ config.setOpenIdSsoUrl(authConfig.getOpenIdSsoUrl());
+ break;
+
case LDAP:
case LDAP_BIND:
config.setRegisterUrl(cfg.getString("auth", null, "registerurl"));
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebModule.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebModule.java
index 0d14b79..1a48bb5 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebModule.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/WebModule.java
@@ -108,6 +108,7 @@
break;
case OPENID:
+ case OPENID_SSO:
// OpenID support is bound in WebAppInitializer and Daemon.
case CUSTOM_EXTENSION:
break;
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
index 282bbc9..02b0a1d 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
@@ -367,7 +367,8 @@
}
AuthConfig authConfig = cfgInjector.getInstance(AuthConfig.class);
- if (authConfig.getAuthType() == AuthType.OPENID) {
+ if (authConfig.getAuthType() == AuthType.OPENID ||
+ authConfig.getAuthType() == AuthType.OPENID_SSO) {
modules.add(new OpenIdModule());
}
modules.add(sysInjector.getInstance(GetUserFilter.Module.class));
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AuthType.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AuthType.java
index 962426b..b615fc5 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AuthType.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AuthType.java
@@ -18,6 +18,9 @@
/** Login relies upon the OpenID standard: {@link "http://openid.net/"} */
OPENID,
+ /** Login relies upon the OpenID standard: {@link "http://openid.net/"} in Single Sign On mode */
+ OPENID_SSO,
+
/**
* Login relies upon the container/web server security.
* <p>
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java
index a0f0d36..a37fde0 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/AuthConfig.java
@@ -37,6 +37,7 @@
private final String httpHeader;
private final boolean trustContainerAuth;
private final String logoutUrl;
+ private final String openIdSsoUrl;
private final List<OpenIdProviderPattern> trustedOpenIDs;
private final List<OpenIdProviderPattern> allowedOpenIDs;
private final String cookiePath;
@@ -51,6 +52,7 @@
authType = toType(cfg);
httpHeader = cfg.getString("auth", null, "httpheader");
logoutUrl = cfg.getString("auth", null, "logouturl");
+ openIdSsoUrl = cfg.getString("auth", null, "openidssourl");
trustedOpenIDs = toPatterns(cfg, "trustedOpenID");
allowedOpenIDs = toPatterns(cfg, "allowedOpenID");
cookiePath = cfg.getString("auth", null, "cookiepath");
@@ -106,6 +108,10 @@
return logoutUrl;
}
+ public String getOpenIdSsoUrl() {
+ return openIdSsoUrl;
+ }
+
public String getCookiePath() {
return cookiePath;
}
@@ -146,6 +152,10 @@
//
return true;
+ case OPENID_SSO:
+ // There's only one provider in SSO mode, so it must be okay.
+ return true;
+
case OPENID:
// All identities must be trusted in order to trust the account.
//