Merge "Add OpenID SSO support."
This commit is contained in:
@@ -88,6 +88,12 @@ The default setting. Gerrit uses any valid OpenID
|
|||||||
provider chosen by the end-user. For more information see
|
provider chosen by the end-user. For more information see
|
||||||
http://openid.net/[openid.net].
|
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`
|
* `HTTP`
|
||||||
+
|
+
|
||||||
Gerrit relies upon data presented in the HTTP request. This includes
|
Gerrit relies upon data presented in the HTTP request. This includes
|
||||||
@@ -229,6 +235,13 @@ order to validate their email address expires.
|
|||||||
+
|
+
|
||||||
Default is 12 hours.
|
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::
|
[[auth.httpHeader]]auth.httpHeader::
|
||||||
+
|
+
|
||||||
HTTP header to trust the username from, or unset to select HTTP basic
|
HTTP header to trust the username from, or unset to select HTTP basic
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import java.util.Set;
|
|||||||
public class GerritConfig implements Cloneable {
|
public class GerritConfig implements Cloneable {
|
||||||
protected String registerUrl;
|
protected String registerUrl;
|
||||||
protected String httpPasswordUrl;
|
protected String httpPasswordUrl;
|
||||||
|
protected String openIdSsoUrl;
|
||||||
protected List<OpenIdProviderPattern> allowedOpenIDs;
|
protected List<OpenIdProviderPattern> allowedOpenIDs;
|
||||||
|
|
||||||
protected GitwebConfig gitweb;
|
protected GitwebConfig gitweb;
|
||||||
@@ -72,6 +73,14 @@ public class GerritConfig implements Cloneable {
|
|||||||
httpPasswordUrl = url;
|
httpPasswordUrl = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getOpenIdSsoUrl() {
|
||||||
|
return openIdSsoUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOpenIdSsoUrl(final String u) {
|
||||||
|
openIdSsoUrl = u;
|
||||||
|
}
|
||||||
|
|
||||||
public List<OpenIdProviderPattern> getAllowedOpenIDs() {
|
public List<OpenIdProviderPattern> getAllowedOpenIDs() {
|
||||||
return allowedOpenIDs;
|
return allowedOpenIDs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import static com.google.gerrit.common.data.GlobalCapability.ADMINISTRATE_SERVER
|
|||||||
|
|
||||||
import com.google.gerrit.client.account.AccountCapabilities;
|
import com.google.gerrit.client.account.AccountCapabilities;
|
||||||
import com.google.gerrit.client.auth.openid.OpenIdSignInDialog;
|
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.auth.userpass.UserPassSignInDialog;
|
||||||
import com.google.gerrit.client.changes.ChangeConstants;
|
import com.google.gerrit.client.changes.ChangeConstants;
|
||||||
import com.google.gerrit.client.changes.ChangeListScreen;
|
import com.google.gerrit.client.changes.ChangeListScreen;
|
||||||
@@ -258,6 +259,13 @@ public class Gerrit implements EntryPoint {
|
|||||||
Location.assign(selfRedirect("/become"));
|
Location.assign(selfRedirect("/become"));
|
||||||
break;
|
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:
|
case OPENID:
|
||||||
new OpenIdSignInDialog(SignInMode.SIGN_IN, token, null).center();
|
new OpenIdSignInDialog(SignInMode.SIGN_IN, token, null).center();
|
||||||
break;
|
break;
|
||||||
@@ -627,6 +635,14 @@ public class Gerrit implements EntryPoint {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPENID_SSO:
|
||||||
|
menuRight.addItem(C.menuSignIn(), new Command() {
|
||||||
|
public void execute() {
|
||||||
|
doSignIn(History.getToken());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
case LDAP:
|
case LDAP:
|
||||||
case LDAP_BIND:
|
case LDAP_BIND:
|
||||||
case CUSTOM_EXTENSION:
|
case CUSTOM_EXTENSION:
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -90,6 +90,10 @@ class GerritConfigProvider implements Provider<GerritConfig> {
|
|||||||
config.setAllowedOpenIDs(authConfig.getAllowedOpenIDs());
|
config.setAllowedOpenIDs(authConfig.getAllowedOpenIDs());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPENID_SSO:
|
||||||
|
config.setOpenIdSsoUrl(authConfig.getOpenIdSsoUrl());
|
||||||
|
break;
|
||||||
|
|
||||||
case LDAP:
|
case LDAP:
|
||||||
case LDAP_BIND:
|
case LDAP_BIND:
|
||||||
config.setRegisterUrl(cfg.getString("auth", null, "registerurl"));
|
config.setRegisterUrl(cfg.getString("auth", null, "registerurl"));
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ public class WebModule extends FactoryModule {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OPENID:
|
case OPENID:
|
||||||
|
case OPENID_SSO:
|
||||||
// OpenID support is bound in WebAppInitializer and Daemon.
|
// OpenID support is bound in WebAppInitializer and Daemon.
|
||||||
case CUSTOM_EXTENSION:
|
case CUSTOM_EXTENSION:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -367,7 +367,8 @@ public class Daemon extends SiteProgram {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AuthConfig authConfig = cfgInjector.getInstance(AuthConfig.class);
|
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(new OpenIdModule());
|
||||||
}
|
}
|
||||||
modules.add(sysInjector.getInstance(GetUserFilter.Module.class));
|
modules.add(sysInjector.getInstance(GetUserFilter.Module.class));
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ public enum AuthType {
|
|||||||
/** Login relies upon the OpenID standard: {@link "http://openid.net/"} */
|
/** Login relies upon the OpenID standard: {@link "http://openid.net/"} */
|
||||||
OPENID,
|
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.
|
* Login relies upon the container/web server security.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public class AuthConfig {
|
|||||||
private final boolean userNameToLowerCase;
|
private final boolean userNameToLowerCase;
|
||||||
private final boolean gitBasicAuth;
|
private final boolean gitBasicAuth;
|
||||||
private final String logoutUrl;
|
private final String logoutUrl;
|
||||||
|
private final String openIdSsoUrl;
|
||||||
private final List<OpenIdProviderPattern> trustedOpenIDs;
|
private final List<OpenIdProviderPattern> trustedOpenIDs;
|
||||||
private final List<OpenIdProviderPattern> allowedOpenIDs;
|
private final List<OpenIdProviderPattern> allowedOpenIDs;
|
||||||
private final String cookiePath;
|
private final String cookiePath;
|
||||||
@@ -53,6 +54,7 @@ public class AuthConfig {
|
|||||||
authType = toType(cfg);
|
authType = toType(cfg);
|
||||||
httpHeader = cfg.getString("auth", null, "httpheader");
|
httpHeader = cfg.getString("auth", null, "httpheader");
|
||||||
logoutUrl = cfg.getString("auth", null, "logouturl");
|
logoutUrl = cfg.getString("auth", null, "logouturl");
|
||||||
|
openIdSsoUrl = cfg.getString("auth", null, "openidssourl");
|
||||||
trustedOpenIDs = toPatterns(cfg, "trustedOpenID");
|
trustedOpenIDs = toPatterns(cfg, "trustedOpenID");
|
||||||
allowedOpenIDs = toPatterns(cfg, "allowedOpenID");
|
allowedOpenIDs = toPatterns(cfg, "allowedOpenID");
|
||||||
cookiePath = cfg.getString("auth", null, "cookiepath");
|
cookiePath = cfg.getString("auth", null, "cookiepath");
|
||||||
@@ -111,6 +113,10 @@ public class AuthConfig {
|
|||||||
return logoutUrl;
|
return logoutUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getOpenIdSsoUrl() {
|
||||||
|
return openIdSsoUrl;
|
||||||
|
}
|
||||||
|
|
||||||
public String getCookiePath() {
|
public String getCookiePath() {
|
||||||
return cookiePath;
|
return cookiePath;
|
||||||
}
|
}
|
||||||
@@ -161,6 +167,10 @@ public class AuthConfig {
|
|||||||
//
|
//
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case OPENID_SSO:
|
||||||
|
// There's only one provider in SSO mode, so it must be okay.
|
||||||
|
return true;
|
||||||
|
|
||||||
case OPENID:
|
case OPENID:
|
||||||
// All identities must be trusted in order to trust the account.
|
// All identities must be trusted in order to trust the account.
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user