Merge branch 'stable-2.6'
* stable-2.6: Allow logging in at /login Remove login dialogs and replace with /login/ URLs Change-Id: Id51c94f8bcdfa8927c568d06a5fd0d07a743d1cc
This commit is contained in:
@@ -1,30 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.common.auth.openid;
|
|
||||||
|
|
||||||
import com.google.gerrit.common.auth.SignInMode;
|
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
|
||||||
import com.google.gwtjsonrpc.common.AllowCrossSiteRequest;
|
|
||||||
import com.google.gwtjsonrpc.common.RemoteJsonService;
|
|
||||||
import com.google.gwtjsonrpc.common.RpcImpl;
|
|
||||||
import com.google.gwtjsonrpc.common.RpcImpl.Version;
|
|
||||||
|
|
||||||
@RpcImpl(version = Version.V2_0)
|
|
||||||
public interface OpenIdService extends RemoteJsonService {
|
|
||||||
@AllowCrossSiteRequest
|
|
||||||
void discover(String openidIdentifier, SignInMode mode,
|
|
||||||
boolean remember, String returnToken,
|
|
||||||
AsyncCallback<DiscoveryResult> callback);
|
|
||||||
}
|
|
@@ -1,53 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.common.auth.userpass;
|
|
||||||
|
|
||||||
import com.google.gerrit.reviewdb.client.AuthType;
|
|
||||||
|
|
||||||
public class LoginResult {
|
|
||||||
public boolean success;
|
|
||||||
public boolean isNew;
|
|
||||||
|
|
||||||
protected AuthType authType;
|
|
||||||
protected Error error;
|
|
||||||
|
|
||||||
protected LoginResult() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoginResult(final AuthType authType) {
|
|
||||||
this.authType = authType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthType getAuthType() {
|
|
||||||
return authType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setError(final Error error) {
|
|
||||||
this.error = error;
|
|
||||||
success = error == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Error getError() {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static enum Error {
|
|
||||||
/** Username or password are invalid */
|
|
||||||
INVALID_LOGIN,
|
|
||||||
|
|
||||||
/** The authentication server is unavailable or the query to it timed out */
|
|
||||||
AUTHENTICATION_UNAVAILABLE
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,30 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.common.auth.userpass;
|
|
||||||
|
|
||||||
import com.google.gerrit.common.audit.Audit;
|
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
|
||||||
import com.google.gwtjsonrpc.common.AllowCrossSiteRequest;
|
|
||||||
import com.google.gwtjsonrpc.common.RemoteJsonService;
|
|
||||||
import com.google.gwtjsonrpc.common.RpcImpl;
|
|
||||||
import com.google.gwtjsonrpc.common.RpcImpl.Version;
|
|
||||||
|
|
||||||
@RpcImpl(version = Version.V2_0)
|
|
||||||
public interface UserPassAuthService extends RemoteJsonService {
|
|
||||||
@Audit(action = "sign in", obfuscate={1})
|
|
||||||
@AllowCrossSiteRequest
|
|
||||||
void authenticate(String username, String password,
|
|
||||||
AsyncCallback<LoginResult> callback);
|
|
||||||
}
|
|
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
package com.google.gerrit.common.data;
|
package com.google.gerrit.common.data;
|
||||||
|
|
||||||
import com.google.gerrit.common.auth.openid.OpenIdProviderPattern;
|
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.Account.FieldName;
|
import com.google.gerrit.reviewdb.client.Account.FieldName;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand;
|
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand;
|
||||||
@@ -31,8 +30,6 @@ public class GerritConfig implements Cloneable {
|
|||||||
protected String registerText;
|
protected String registerText;
|
||||||
protected String httpPasswordUrl;
|
protected String httpPasswordUrl;
|
||||||
protected String reportBugUrl;
|
protected String reportBugUrl;
|
||||||
protected String openIdSsoUrl;
|
|
||||||
protected List<OpenIdProviderPattern> allowedOpenIDs;
|
|
||||||
|
|
||||||
protected GitwebConfig gitweb;
|
protected GitwebConfig gitweb;
|
||||||
protected boolean useContributorAgreements;
|
protected boolean useContributorAgreements;
|
||||||
@@ -93,22 +90,6 @@ 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() {
|
|
||||||
return allowedOpenIDs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAllowedOpenIDs(List<OpenIdProviderPattern> l) {
|
|
||||||
allowedOpenIDs = l;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthType getAuthType() {
|
public AuthType getAuthType() {
|
||||||
return authType;
|
return authType;
|
||||||
}
|
}
|
||||||
|
@@ -60,8 +60,6 @@ import com.google.gerrit.client.admin.ProjectDashboardsScreen;
|
|||||||
import com.google.gerrit.client.admin.ProjectInfoScreen;
|
import com.google.gerrit.client.admin.ProjectInfoScreen;
|
||||||
import com.google.gerrit.client.admin.ProjectListScreen;
|
import com.google.gerrit.client.admin.ProjectListScreen;
|
||||||
import com.google.gerrit.client.admin.ProjectScreen;
|
import com.google.gerrit.client.admin.ProjectScreen;
|
||||||
import com.google.gerrit.client.auth.openid.OpenIdSignInDialog;
|
|
||||||
import com.google.gerrit.client.auth.userpass.UserPassSignInDialog;
|
|
||||||
import com.google.gerrit.client.changes.AccountDashboardScreen;
|
import com.google.gerrit.client.changes.AccountDashboardScreen;
|
||||||
import com.google.gerrit.client.changes.ChangeScreen;
|
import com.google.gerrit.client.changes.ChangeScreen;
|
||||||
import com.google.gerrit.client.changes.CustomDashboardScreen;
|
import com.google.gerrit.client.changes.CustomDashboardScreen;
|
||||||
@@ -78,7 +76,6 @@ import com.google.gerrit.client.rpc.GerritCallback;
|
|||||||
import com.google.gerrit.client.rpc.RestApi;
|
import com.google.gerrit.client.rpc.RestApi;
|
||||||
import com.google.gerrit.client.ui.Screen;
|
import com.google.gerrit.client.ui.Screen;
|
||||||
import com.google.gerrit.common.PageLinks;
|
import com.google.gerrit.common.PageLinks;
|
||||||
import com.google.gerrit.common.auth.SignInMode;
|
|
||||||
import com.google.gerrit.common.data.PatchSetDetail;
|
import com.google.gerrit.common.data.PatchSetDetail;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
@@ -633,32 +630,6 @@ public class Dispatcher {
|
|||||||
if (matchPrefix("/VE/", token) || matchPrefix("VE,", token))
|
if (matchPrefix("/VE/", token) || matchPrefix("VE,", token))
|
||||||
return new ValidateEmailScreen(skip(token));
|
return new ValidateEmailScreen(skip(token));
|
||||||
|
|
||||||
if (matchPrefix("/SignInFailure,", token)) {
|
|
||||||
final String[] args = skip(token).split(",");
|
|
||||||
final SignInMode mode = SignInMode.valueOf(args[0]);
|
|
||||||
final String msg = KeyUtil.decode(args[1]);
|
|
||||||
final String to = MINE;
|
|
||||||
switch (Gerrit.getConfig().getAuthType()) {
|
|
||||||
case OPENID:
|
|
||||||
new OpenIdSignInDialog(mode, to, msg).center();
|
|
||||||
break;
|
|
||||||
case LDAP:
|
|
||||||
case LDAP_BIND:
|
|
||||||
new UserPassSignInDialog(to, msg).center();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
switch (mode) {
|
|
||||||
case SIGN_IN:
|
|
||||||
return QueryScreen.forQuery("status:open");
|
|
||||||
case LINK_IDENTIY:
|
|
||||||
return new MyIdentitiesScreen();
|
|
||||||
case REGISTER:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matchExact(SETTINGS_NEW_AGREEMENT, token))
|
if (matchExact(SETTINGS_NEW_AGREEMENT, token))
|
||||||
return new NewAgreementScreen();
|
return new NewAgreementScreen();
|
||||||
|
|
||||||
|
@@ -15,14 +15,11 @@
|
|||||||
package com.google.gerrit.client;
|
package com.google.gerrit.client;
|
||||||
|
|
||||||
import static com.google.gerrit.common.data.GlobalCapability.ADMINISTRATE_SERVER;
|
import static com.google.gerrit.common.data.GlobalCapability.ADMINISTRATE_SERVER;
|
||||||
import static com.google.gerrit.common.data.GlobalCapability.CREATE_PROJECT;
|
|
||||||
import static com.google.gerrit.common.data.GlobalCapability.CREATE_GROUP;
|
import static com.google.gerrit.common.data.GlobalCapability.CREATE_GROUP;
|
||||||
|
import static com.google.gerrit.common.data.GlobalCapability.CREATE_PROJECT;
|
||||||
|
|
||||||
import com.google.gerrit.client.account.AccountCapabilities;
|
import com.google.gerrit.client.account.AccountCapabilities;
|
||||||
import com.google.gerrit.client.admin.ProjectScreen;
|
import com.google.gerrit.client.admin.ProjectScreen;
|
||||||
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.ChangeConstants;
|
||||||
import com.google.gerrit.client.changes.ChangeListScreen;
|
import com.google.gerrit.client.changes.ChangeListScreen;
|
||||||
import com.google.gerrit.client.patches.PatchScreen;
|
import com.google.gerrit.client.patches.PatchScreen;
|
||||||
@@ -35,7 +32,6 @@ import com.google.gerrit.client.ui.Screen;
|
|||||||
import com.google.gerrit.client.ui.ScreenLoadEvent;
|
import com.google.gerrit.client.ui.ScreenLoadEvent;
|
||||||
import com.google.gerrit.common.ClientVersion;
|
import com.google.gerrit.common.ClientVersion;
|
||||||
import com.google.gerrit.common.PageLinks;
|
import com.google.gerrit.common.PageLinks;
|
||||||
import com.google.gerrit.common.auth.SignInMode;
|
|
||||||
import com.google.gerrit.common.data.GerritConfig;
|
import com.google.gerrit.common.data.GerritConfig;
|
||||||
import com.google.gerrit.common.data.GitwebConfig;
|
import com.google.gerrit.common.data.GitwebConfig;
|
||||||
import com.google.gerrit.common.data.HostPageData;
|
import com.google.gerrit.common.data.HostPageData;
|
||||||
@@ -71,9 +67,9 @@ import com.google.gwt.user.client.Window;
|
|||||||
import com.google.gwt.user.client.Window.Location;
|
import com.google.gwt.user.client.Window.Location;
|
||||||
import com.google.gwt.user.client.ui.Anchor;
|
import com.google.gwt.user.client.ui.Anchor;
|
||||||
import com.google.gwt.user.client.ui.FlowPanel;
|
import com.google.gwt.user.client.ui.FlowPanel;
|
||||||
|
import com.google.gwt.user.client.ui.FocusPanel;
|
||||||
import com.google.gwt.user.client.ui.Grid;
|
import com.google.gwt.user.client.ui.Grid;
|
||||||
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
|
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
|
||||||
import com.google.gwt.user.client.ui.FocusPanel;
|
|
||||||
import com.google.gwt.user.client.ui.InlineHTML;
|
import com.google.gwt.user.client.ui.InlineHTML;
|
||||||
import com.google.gwt.user.client.ui.InlineLabel;
|
import com.google.gwt.user.client.ui.InlineLabel;
|
||||||
import com.google.gwt.user.client.ui.Label;
|
import com.google.gwt.user.client.ui.Label;
|
||||||
@@ -273,34 +269,7 @@ public class Gerrit implements EntryPoint {
|
|||||||
|
|
||||||
/** Sign the user into the application. */
|
/** Sign the user into the application. */
|
||||||
public static void doSignIn(String token) {
|
public static void doSignIn(String token) {
|
||||||
switch (myConfig.getAuthType()) {
|
Location.assign(loginRedirect(token));
|
||||||
case HTTP:
|
|
||||||
case HTTP_LDAP:
|
|
||||||
case CLIENT_SSL_CERT_LDAP:
|
|
||||||
case CUSTOM_EXTENSION:
|
|
||||||
Location.assign(loginRedirect(token));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEVELOPMENT_BECOME_ANY_ACCOUNT:
|
|
||||||
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;
|
|
||||||
|
|
||||||
case LDAP:
|
|
||||||
case LDAP_BIND:
|
|
||||||
new UserPassSignInDialog(token, null).center();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String loginRedirect(String token) {
|
public static String loginRedirect(String token) {
|
||||||
@@ -726,8 +695,11 @@ public class Gerrit implements EntryPoint {
|
|||||||
case OPENID:
|
case OPENID:
|
||||||
menuRight.addItem(C.menuRegister(), new Command() {
|
menuRight.addItem(C.menuRegister(), new Command() {
|
||||||
public void execute() {
|
public void execute() {
|
||||||
final String to = History.getToken();
|
String t = History.getToken();
|
||||||
new OpenIdSignInDialog(SignInMode.REGISTER, to, null).center();
|
if (t == null) {
|
||||||
|
t = "";
|
||||||
|
}
|
||||||
|
doSignIn(PageLinks.REGISTER + t);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
menuRight.addItem(C.menuSignIn(), new Command() {
|
menuRight.addItem(C.menuSignIn(), new Command() {
|
||||||
@@ -760,7 +732,7 @@ public class Gerrit implements EntryPoint {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DEVELOPMENT_BECOME_ANY_ACCOUNT:
|
case DEVELOPMENT_BECOME_ANY_ACCOUNT:
|
||||||
menuRight.add(anchor("Become", selfRedirect("/become")));
|
menuRight.add(anchor("Become", loginRedirect("")));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,57 +0,0 @@
|
|||||||
// Copyright (C) 2008 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;
|
|
||||||
|
|
||||||
import com.google.gerrit.common.auth.SignInMode;
|
|
||||||
import com.google.gwtexpui.globalkey.client.GlobalKey;
|
|
||||||
import com.google.gwtexpui.user.client.AutoCenterDialogBox;
|
|
||||||
|
|
||||||
/** Prompts the user to sign in to their account. */
|
|
||||||
public abstract class SignInDialog extends AutoCenterDialogBox {
|
|
||||||
protected final SignInMode mode;
|
|
||||||
protected final String token;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new dialog to handle user sign in.
|
|
||||||
*
|
|
||||||
* @param signInMode type of mode the login will perform.
|
|
||||||
* @param token the token to jump to after sign-in is complete.
|
|
||||||
*/
|
|
||||||
protected SignInDialog(final SignInMode signInMode, final String token) {
|
|
||||||
super(/* auto hide */true, /* modal */true);
|
|
||||||
setGlassEnabled(true);
|
|
||||||
|
|
||||||
this.mode = signInMode;
|
|
||||||
this.token = token;
|
|
||||||
|
|
||||||
switch (signInMode) {
|
|
||||||
case LINK_IDENTIY:
|
|
||||||
setText(Gerrit.C.linkIdentityDialogTitle());
|
|
||||||
break;
|
|
||||||
case REGISTER:
|
|
||||||
setText(Gerrit.C.registerDialogTitle());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setText(Gerrit.C.signInDialogTitle());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void show() {
|
|
||||||
super.show();
|
|
||||||
GlobalKey.dialog(this);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -15,19 +15,19 @@
|
|||||||
package com.google.gerrit.client.account;
|
package com.google.gerrit.client.account;
|
||||||
|
|
||||||
import com.google.gerrit.client.Gerrit;
|
import com.google.gerrit.client.Gerrit;
|
||||||
import com.google.gerrit.client.auth.openid.OpenIdSignInDialog;
|
|
||||||
import com.google.gerrit.client.auth.openid.OpenIdUtil;
|
import com.google.gerrit.client.auth.openid.OpenIdUtil;
|
||||||
import com.google.gerrit.client.rpc.GerritCallback;
|
import com.google.gerrit.client.rpc.GerritCallback;
|
||||||
import com.google.gerrit.client.rpc.ScreenLoadCallback;
|
import com.google.gerrit.client.rpc.ScreenLoadCallback;
|
||||||
import com.google.gerrit.client.ui.FancyFlexTable;
|
import com.google.gerrit.client.ui.FancyFlexTable;
|
||||||
import com.google.gerrit.common.auth.SignInMode;
|
|
||||||
import com.google.gerrit.common.auth.openid.OpenIdUrls;
|
import com.google.gerrit.common.auth.openid.OpenIdUrls;
|
||||||
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
||||||
|
import com.google.gerrit.reviewdb.client.AuthType;
|
||||||
import com.google.gwt.event.dom.client.ClickEvent;
|
import com.google.gwt.event.dom.client.ClickEvent;
|
||||||
import com.google.gwt.event.dom.client.ClickHandler;
|
import com.google.gwt.event.dom.client.ClickHandler;
|
||||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||||
import com.google.gwt.user.client.History;
|
import com.google.gwt.user.client.History;
|
||||||
|
import com.google.gwt.user.client.Window.Location;
|
||||||
import com.google.gwt.user.client.ui.Button;
|
import com.google.gwt.user.client.ui.Button;
|
||||||
import com.google.gwt.user.client.ui.CheckBox;
|
import com.google.gwt.user.client.ui.CheckBox;
|
||||||
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
|
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
|
||||||
@@ -59,29 +59,15 @@ public class MyIdentitiesScreen extends SettingsScreen {
|
|||||||
});
|
});
|
||||||
add(deleteIdentity);
|
add(deleteIdentity);
|
||||||
|
|
||||||
switch (Gerrit.getConfig().getAuthType()) {
|
if (Gerrit.getConfig().getAuthType() == AuthType.OPENID) {
|
||||||
case OPENID: {
|
Button linkIdentity = new Button(Util.C.buttonLinkIdentity());
|
||||||
final Button linkIdentity = new Button(Util.C.buttonLinkIdentity());
|
linkIdentity.addClickHandler(new ClickHandler() {
|
||||||
linkIdentity.addClickHandler(new ClickHandler() {
|
@Override
|
||||||
@Override
|
public void onClick(final ClickEvent event) {
|
||||||
public void onClick(final ClickEvent event) {
|
Location.assign(Gerrit.loginRedirect(History.getToken()) + "?link");
|
||||||
final String to = History.getToken();
|
}
|
||||||
new OpenIdSignInDialog(SignInMode.LINK_IDENTIY, to, null).center();
|
});
|
||||||
}
|
add(linkIdentity);
|
||||||
});
|
|
||||||
add(linkIdentity);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CLIENT_SSL_CERT_LDAP:
|
|
||||||
case CUSTOM_EXTENSION:
|
|
||||||
case DEVELOPMENT_BECOME_ANY_ACCOUNT:
|
|
||||||
case HTTP:
|
|
||||||
case HTTP_LDAP:
|
|
||||||
case LDAP:
|
|
||||||
case LDAP_BIND:
|
|
||||||
case OPENID_SSO:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,18 +17,6 @@ package com.google.gerrit.client.auth.openid;
|
|||||||
import com.google.gwt.i18n.client.Constants;
|
import com.google.gwt.i18n.client.Constants;
|
||||||
|
|
||||||
public interface OpenIdConstants extends Constants {
|
public interface OpenIdConstants extends Constants {
|
||||||
String buttonSignIn();
|
|
||||||
String buttonRegister();
|
|
||||||
String buttonLinkId();
|
|
||||||
|
|
||||||
String rememberMe();
|
|
||||||
|
|
||||||
String notAllowed();
|
|
||||||
String noProvider();
|
|
||||||
String error();
|
|
||||||
|
|
||||||
String nameGoogle();
|
String nameGoogle();
|
||||||
String nameYahoo();
|
String nameYahoo();
|
||||||
|
|
||||||
String whatIsOpenIDHtml();
|
|
||||||
}
|
}
|
||||||
|
@@ -1,20 +1,2 @@
|
|||||||
buttonSignIn = Sign In
|
|
||||||
buttonRegister = Register
|
|
||||||
buttonLinkId = Link Identity
|
|
||||||
|
|
||||||
rememberMe = Remember Me
|
|
||||||
|
|
||||||
notAllowed = Provider is not allowed.
|
|
||||||
noProvider = Provider is not supported, or was incorrectly entered.
|
|
||||||
error = Unable to connect with OpenID provider.
|
|
||||||
|
|
||||||
nameGoogle = Google Account
|
nameGoogle = Google Account
|
||||||
nameYahoo = Yahoo! ID
|
nameYahoo = Yahoo! ID
|
||||||
|
|
||||||
whatIsOpenIDHtml = \
|
|
||||||
<h2 class="smallHeading" style="margin-top: 25px;">What is OpenID?</h2>\
|
|
||||||
<p>OpenID provides secure single-sign-on, without \
|
|
||||||
revealing your passwords to this website.</p>\
|
|
||||||
<p>There are many OpenID providers available. You may already \
|
|
||||||
be member of one!</p>\
|
|
||||||
<p><a href="http://openid.net/get/" target="_blank">Get OpenID</a></p>\
|
|
||||||
|
@@ -1,27 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.gwt.i18n.client.Messages;
|
|
||||||
|
|
||||||
public interface OpenIdMessages extends Messages {
|
|
||||||
String signInAt(String hostname);
|
|
||||||
String registerAt(String hostname);
|
|
||||||
String linkAt(String hostname);
|
|
||||||
|
|
||||||
String signInWith(String who);
|
|
||||||
String registerWith(String who);
|
|
||||||
String linkWith(String who);
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
signInAt = Sign In to Gerrit Code Review at {0}
|
|
||||||
registerAt = Register with Gerrit Code Review at {0}
|
|
||||||
linkAt = Link Another Identity to Gerrit Code Review at {0}
|
|
||||||
|
|
||||||
signInWith = Sign in with a {0}
|
|
||||||
registerWith = Register with a {0}
|
|
||||||
linkWith = Link a {0}
|
|
@@ -1,39 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.gwt.core.client.GWT;
|
|
||||||
import com.google.gwt.resources.client.ClientBundle;
|
|
||||||
import com.google.gwt.resources.client.DataResource;
|
|
||||||
import com.google.gwt.resources.client.ImageResource;
|
|
||||||
|
|
||||||
interface OpenIdResources extends ClientBundle {
|
|
||||||
static final OpenIdResources I = GWT.create(OpenIdResources.class);
|
|
||||||
|
|
||||||
@Source("openid.css")
|
|
||||||
OpenIdCss css();
|
|
||||||
|
|
||||||
@Source("identifierBackground.gif")
|
|
||||||
DataResource identifierBackground();
|
|
||||||
|
|
||||||
@Source("openidLogo.png")
|
|
||||||
ImageResource openidLogo();
|
|
||||||
|
|
||||||
@Source("iconGoogle.gif")
|
|
||||||
ImageResource iconGoogle();
|
|
||||||
|
|
||||||
@Source("iconYahoo.gif")
|
|
||||||
ImageResource iconYahoo();
|
|
||||||
}
|
|
@@ -1,388 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.SignInDialog;
|
|
||||||
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.OpenIdProviderPattern;
|
|
||||||
import com.google.gerrit.common.auth.openid.OpenIdUrls;
|
|
||||||
import com.google.gwt.core.client.Scheduler;
|
|
||||||
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
|
||||||
import com.google.gwt.dom.client.FormElement;
|
|
||||||
import com.google.gwt.event.dom.client.ClickEvent;
|
|
||||||
import com.google.gwt.event.dom.client.ClickHandler;
|
|
||||||
import com.google.gwt.event.dom.client.KeyCodes;
|
|
||||||
import com.google.gwt.event.dom.client.KeyPressEvent;
|
|
||||||
import com.google.gwt.event.dom.client.KeyPressHandler;
|
|
||||||
import com.google.gwt.resources.client.ImageResource;
|
|
||||||
import com.google.gwt.user.client.Cookies;
|
|
||||||
import com.google.gwt.user.client.DOM;
|
|
||||||
import com.google.gwt.user.client.Window;
|
|
||||||
import com.google.gwt.user.client.ui.Anchor;
|
|
||||||
import com.google.gwt.user.client.ui.Button;
|
|
||||||
import com.google.gwt.user.client.ui.CheckBox;
|
|
||||||
import com.google.gwt.user.client.ui.FlowPanel;
|
|
||||||
import com.google.gwt.user.client.ui.FormPanel;
|
|
||||||
import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
|
|
||||||
import com.google.gwt.user.client.ui.FormSubmitCompleteEvent;
|
|
||||||
import com.google.gwt.user.client.ui.HTML;
|
|
||||||
import com.google.gwt.user.client.ui.Hidden;
|
|
||||||
import com.google.gwt.user.client.ui.Image;
|
|
||||||
import com.google.gwt.user.client.ui.InlineLabel;
|
|
||||||
import com.google.gwtexpui.globalkey.client.NpTextBox;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class OpenIdSignInDialog extends SignInDialog implements
|
|
||||||
FormPanel.SubmitHandler {
|
|
||||||
static {
|
|
||||||
OpenIdResources.I.css().ensureInjected();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final FlowPanel panelWidget;
|
|
||||||
private final FormPanel form;
|
|
||||||
private final FlowPanel formBody;
|
|
||||||
private final FormPanel redirectForm;
|
|
||||||
private final FlowPanel redirectBody;
|
|
||||||
|
|
||||||
private FlowPanel errorLine;
|
|
||||||
private InlineLabel errorMsg;
|
|
||||||
|
|
||||||
private Button login;
|
|
||||||
private NpTextBox providerId;
|
|
||||||
private CheckBox rememberId;
|
|
||||||
private boolean discovering;
|
|
||||||
|
|
||||||
public OpenIdSignInDialog(final SignInMode requestedMode, final String token,
|
|
||||||
final String initialErrorMsg) {
|
|
||||||
super(requestedMode, token);
|
|
||||||
|
|
||||||
formBody = new FlowPanel();
|
|
||||||
formBody.setStyleName(OpenIdResources.I.css().loginForm());
|
|
||||||
|
|
||||||
form = new FormPanel();
|
|
||||||
form.setMethod(FormPanel.METHOD_GET);
|
|
||||||
form.addSubmitHandler(this);
|
|
||||||
form.add(formBody);
|
|
||||||
|
|
||||||
redirectBody = new FlowPanel();
|
|
||||||
redirectBody.setVisible(false);
|
|
||||||
redirectForm = new FormPanel();
|
|
||||||
redirectForm.add(redirectBody);
|
|
||||||
|
|
||||||
panelWidget = new FlowPanel();
|
|
||||||
panelWidget.add(form);
|
|
||||||
panelWidget.add(redirectForm);
|
|
||||||
add(panelWidget);
|
|
||||||
|
|
||||||
createHeaderLogo();
|
|
||||||
createHeaderText();
|
|
||||||
createErrorBox();
|
|
||||||
createIdentBox();
|
|
||||||
|
|
||||||
link(OpenIdUrls.URL_GOOGLE, OpenIdUtil.C.nameGoogle(), OpenIdResources.I
|
|
||||||
.iconGoogle());
|
|
||||||
link(OpenIdUrls.URL_YAHOO, OpenIdUtil.C.nameYahoo(), OpenIdResources.I
|
|
||||||
.iconYahoo());
|
|
||||||
|
|
||||||
if (initialErrorMsg != null) {
|
|
||||||
showError(initialErrorMsg);
|
|
||||||
}
|
|
||||||
formBody.add(new HTML(OpenIdUtil.C.whatIsOpenIDHtml()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void show() {
|
|
||||||
super.show();
|
|
||||||
providerId.selectAll();
|
|
||||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
|
||||||
@Override
|
|
||||||
public void execute() {
|
|
||||||
providerId.setFocus(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createHeaderLogo() {
|
|
||||||
final FlowPanel headerLogo = new FlowPanel();
|
|
||||||
headerLogo.setStyleName(OpenIdResources.I.css().logo());
|
|
||||||
headerLogo.add(new Image(OpenIdResources.I.openidLogo()));
|
|
||||||
formBody.add(headerLogo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createHeaderText() {
|
|
||||||
final FlowPanel headerText = new FlowPanel();
|
|
||||||
final String me = Window.Location.getHostName();
|
|
||||||
final SmallHeading headerLabel = new SmallHeading();
|
|
||||||
switch (mode) {
|
|
||||||
case LINK_IDENTIY:
|
|
||||||
headerLabel.setText(OpenIdUtil.M.linkAt(me));
|
|
||||||
break;
|
|
||||||
case REGISTER:
|
|
||||||
headerLabel.setText(OpenIdUtil.M.registerAt(me));
|
|
||||||
break;
|
|
||||||
case SIGN_IN:
|
|
||||||
default:
|
|
||||||
headerLabel.setText(OpenIdUtil.M.signInAt(me));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
headerText.add(headerLabel);
|
|
||||||
formBody.add(headerText);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createErrorBox() {
|
|
||||||
errorLine = new FlowPanel();
|
|
||||||
DOM.setStyleAttribute(errorLine.getElement(), "visibility", "hidden");
|
|
||||||
errorLine.setStyleName(OpenIdResources.I.css().error());
|
|
||||||
|
|
||||||
errorMsg = new InlineLabel();
|
|
||||||
errorLine.add(errorMsg);
|
|
||||||
formBody.add(errorLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showError(final String msgText) {
|
|
||||||
errorMsg.setText(msgText);
|
|
||||||
DOM.setStyleAttribute(errorLine.getElement(), "visibility", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hideError() {
|
|
||||||
DOM.setStyleAttribute(errorLine.getElement(), "visibility", "hidden");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createIdentBox() {
|
|
||||||
boolean remember = mode == SignInMode.SIGN_IN || mode == SignInMode.REGISTER;
|
|
||||||
|
|
||||||
final FlowPanel group = new FlowPanel();
|
|
||||||
group.setStyleName(OpenIdResources.I.css().loginLine());
|
|
||||||
|
|
||||||
final FlowPanel line1 = new FlowPanel();
|
|
||||||
group.add(line1);
|
|
||||||
|
|
||||||
providerId = new NpTextBox();
|
|
||||||
providerId.setVisibleLength(60);
|
|
||||||
providerId.setStyleName(OpenIdResources.I.css().identifier());
|
|
||||||
providerId.setTabIndex(0);
|
|
||||||
providerId.addKeyPressHandler(new KeyPressHandler() {
|
|
||||||
@Override
|
|
||||||
public void onKeyPress(final KeyPressEvent event) {
|
|
||||||
if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
|
|
||||||
event.preventDefault();
|
|
||||||
form.submit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
line1.add(providerId);
|
|
||||||
|
|
||||||
login = new Button();
|
|
||||||
switch (mode) {
|
|
||||||
case LINK_IDENTIY:
|
|
||||||
login.setText(OpenIdUtil.C.buttonLinkId());
|
|
||||||
break;
|
|
||||||
case REGISTER:
|
|
||||||
login.setText(OpenIdUtil.C.buttonRegister());
|
|
||||||
break;
|
|
||||||
case SIGN_IN:
|
|
||||||
default:
|
|
||||||
login.setText(OpenIdUtil.C.buttonSignIn());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
login.addClickHandler(new ClickHandler() {
|
|
||||||
@Override
|
|
||||||
public void onClick(final ClickEvent event) {
|
|
||||||
form.submit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
login.setTabIndex(remember ? 2 : 1);
|
|
||||||
line1.add(login);
|
|
||||||
|
|
||||||
Button close = new Button(Gerrit.C.signInDialogClose());
|
|
||||||
close.addClickHandler(new ClickHandler() {
|
|
||||||
@Override
|
|
||||||
public void onClick(ClickEvent event) {
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
close.setTabIndex(remember ? 3 : 2);
|
|
||||||
line1.add(close);
|
|
||||||
|
|
||||||
if (remember) {
|
|
||||||
rememberId = new CheckBox(OpenIdUtil.C.rememberMe());
|
|
||||||
rememberId.setTabIndex(1);
|
|
||||||
group.add(rememberId);
|
|
||||||
|
|
||||||
String last = Cookies.getCookie(OpenIdUrls.LASTID_COOKIE);
|
|
||||||
if (last != null && !"".equals(last)) {
|
|
||||||
if (last.startsWith("\"") && last.endsWith("\"")) {
|
|
||||||
// Dequote the value. We shouldn't have to do this, but
|
|
||||||
// something is causing some Google Account tokens to get
|
|
||||||
// wrapped up in double quotes when obtained from the cookie.
|
|
||||||
//
|
|
||||||
last = last.substring(1, last.length() - 2);
|
|
||||||
}
|
|
||||||
providerId.setText(last);
|
|
||||||
rememberId.setValue(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
formBody.add(group);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void link(final String identUrl, final String who,
|
|
||||||
final ImageResource icon) {
|
|
||||||
if (!isAllowedProvider(identUrl)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final ClickHandler i = new ClickHandler() {
|
|
||||||
@Override
|
|
||||||
public void onClick(final ClickEvent event) {
|
|
||||||
event.preventDefault();
|
|
||||||
if (!discovering) {
|
|
||||||
providerId.setText(identUrl);
|
|
||||||
form.submit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
final FlowPanel line = new FlowPanel();
|
|
||||||
line.addStyleName(OpenIdResources.I.css().directLink());
|
|
||||||
|
|
||||||
final Image img = new Image(icon);
|
|
||||||
img.addClickHandler(i);
|
|
||||||
line.add(img);
|
|
||||||
|
|
||||||
final Anchor text = new Anchor();
|
|
||||||
switch (mode) {
|
|
||||||
case LINK_IDENTIY:
|
|
||||||
text.setText(OpenIdUtil.M.linkWith(who));
|
|
||||||
break;
|
|
||||||
case REGISTER:
|
|
||||||
text.setText(OpenIdUtil.M.registerWith(who));
|
|
||||||
break;
|
|
||||||
case SIGN_IN:
|
|
||||||
default:
|
|
||||||
text.setText(OpenIdUtil.M.signInWith(who));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
text.setHref(identUrl);
|
|
||||||
text.addClickHandler(i);
|
|
||||||
line.add(text);
|
|
||||||
|
|
||||||
formBody.add(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isAllowedProvider(final String identUrl) {
|
|
||||||
for (OpenIdProviderPattern p : Gerrit.getConfig().getAllowedOpenIDs()) {
|
|
||||||
if (p.matches(identUrl)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enable(final boolean on) {
|
|
||||||
providerId.setEnabled(on);
|
|
||||||
login.setEnabled(on);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onDiscovery(final DiscoveryResult result) {
|
|
||||||
discovering = false;
|
|
||||||
|
|
||||||
switch (result.status) {
|
|
||||||
case VALID:
|
|
||||||
// The provider won't support operation inside an IFRAME,
|
|
||||||
// so we replace our entire application.
|
|
||||||
//
|
|
||||||
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;
|
|
||||||
|
|
||||||
case NOT_ALLOWED:
|
|
||||||
showError(OpenIdUtil.C.notAllowed());
|
|
||||||
enableRetryDiscovery();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NO_PROVIDER:
|
|
||||||
showError(OpenIdUtil.C.noProvider());
|
|
||||||
enableRetryDiscovery();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ERROR:
|
|
||||||
default:
|
|
||||||
showError(OpenIdUtil.C.error());
|
|
||||||
enableRetryDiscovery();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enableRetryDiscovery() {
|
|
||||||
enable(true);
|
|
||||||
providerId.selectAll();
|
|
||||||
providerId.setFocus(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSubmit(final SubmitEvent event) {
|
|
||||||
event.cancel();
|
|
||||||
|
|
||||||
String openidIdentifier = providerId.getText();
|
|
||||||
if (openidIdentifier == null || openidIdentifier.equals("")) {
|
|
||||||
enable(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!openidIdentifier.startsWith("http://")
|
|
||||||
&& !openidIdentifier.startsWith("https://")) {
|
|
||||||
openidIdentifier = "http://" + openidIdentifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isAllowedProvider(openidIdentifier)) {
|
|
||||||
showError(OpenIdUtil.C.notAllowed());
|
|
||||||
enableRetryDiscovery();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
discovering = true;
|
|
||||||
enable(false);
|
|
||||||
hideError();
|
|
||||||
|
|
||||||
final boolean remember = rememberId != null && rememberId.getValue();
|
|
||||||
OpenIdUtil.SVC.discover(openidIdentifier, mode, remember, token,
|
|
||||||
new GerritCallback<DiscoveryResult>() {
|
|
||||||
public void onSuccess(final DiscoveryResult result) {
|
|
||||||
onDiscovery(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(final Throwable caught) {
|
|
||||||
super.onFailure(caught);
|
|
||||||
enableRetryDiscovery();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onSubmitComplete(final FormSubmitCompleteEvent event) {
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,72 +0,0 @@
|
|||||||
// 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.common.auth.SignInMode;
|
|
||||||
import com.google.gerrit.common.auth.openid.DiscoveryResult;
|
|
||||||
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;
|
|
||||||
case ERROR:
|
|
||||||
case NO_PROVIDER:
|
|
||||||
case NOT_ALLOWED:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,19 +14,12 @@
|
|||||||
|
|
||||||
package com.google.gerrit.client.auth.openid;
|
package com.google.gerrit.client.auth.openid;
|
||||||
|
|
||||||
import com.google.gerrit.common.auth.openid.OpenIdService;
|
|
||||||
import com.google.gwt.core.client.GWT;
|
import com.google.gwt.core.client.GWT;
|
||||||
import com.google.gwtjsonrpc.client.JsonUtil;
|
|
||||||
|
|
||||||
public class OpenIdUtil {
|
public class OpenIdUtil {
|
||||||
public static final OpenIdConstants C;
|
public static final OpenIdConstants C;
|
||||||
public static final OpenIdMessages M;
|
|
||||||
public static final OpenIdService SVC;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
C = GWT.create(OpenIdConstants.class);
|
C = GWT.create(OpenIdConstants.class);
|
||||||
M = GWT.create(OpenIdMessages.class);
|
|
||||||
SVC = GWT.create(OpenIdService.class);
|
|
||||||
JsonUtil.bind(SVC, "rpc/OpenIdService");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 559 B |
Binary file not shown.
Before Width: | Height: | Size: 89 B |
Binary file not shown.
Before Width: | Height: | Size: 237 B |
@@ -1,69 +0,0 @@
|
|||||||
/* Copyright (C) 2009 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@external .gwt-Button;
|
|
||||||
|
|
||||||
@url identifierBackground identifierBackground;
|
|
||||||
|
|
||||||
.loginForm {
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loginLine {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.loginLine div {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.loginLine .gwt-Button {
|
|
||||||
margin-left: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.identifier {
|
|
||||||
background: #ffffff identifierBackground no-repeat scroll 5px 50%;
|
|
||||||
padding-left: 25px;
|
|
||||||
border: 1px solid #999999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.directLink {
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-right: 5px;
|
|
||||||
color: blue;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.directLink:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.directLink img {
|
|
||||||
margin-right: 3px;
|
|
||||||
border: 0 none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
padding-top: 5px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
.error span {
|
|
||||||
padding-top: 4px;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
padding-left: 10px;
|
|
||||||
padding-right: 10px;
|
|
||||||
background: #fff1a8;
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 3.4 KiB |
@@ -1,26 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.userpass;
|
|
||||||
|
|
||||||
import com.google.gwt.i18n.client.Constants;
|
|
||||||
|
|
||||||
public interface UserPassConstants extends Constants {
|
|
||||||
String buttonSignIn();
|
|
||||||
String username();
|
|
||||||
String password();
|
|
||||||
String invalidLogin();
|
|
||||||
String usernameRequired();
|
|
||||||
String passwordRequired();
|
|
||||||
}
|
|
@@ -1,6 +0,0 @@
|
|||||||
buttonSignIn = Sign In
|
|
||||||
username = Username
|
|
||||||
password = Password
|
|
||||||
invalidLogin = Incorrect username or password.
|
|
||||||
usernameRequired = Please enter a username.
|
|
||||||
passwordRequired = Please enter a password.
|
|
@@ -1,22 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.userpass;
|
|
||||||
|
|
||||||
import com.google.gwt.resources.client.CssResource;
|
|
||||||
|
|
||||||
public interface UserPassCss extends CssResource {
|
|
||||||
String loginForm();
|
|
||||||
String error();
|
|
||||||
}
|
|
@@ -1,23 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.userpass;
|
|
||||||
|
|
||||||
import com.google.gerrit.reviewdb.client.AuthType;
|
|
||||||
import com.google.gwt.i18n.client.Messages;
|
|
||||||
|
|
||||||
public interface UserPassMessages extends Messages {
|
|
||||||
String signInAt(String hostname);
|
|
||||||
String authenticationUnavailable(AuthType authType);
|
|
||||||
}
|
|
@@ -1,2 +0,0 @@
|
|||||||
signInAt = Sign In to Gerrit Code Review at {0}
|
|
||||||
authenticationUnavailable = {0} authentication unavailable
|
|
@@ -1,25 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.userpass;
|
|
||||||
|
|
||||||
import com.google.gwt.core.client.GWT;
|
|
||||||
import com.google.gwt.resources.client.ClientBundle;
|
|
||||||
|
|
||||||
interface UserPassResources extends ClientBundle {
|
|
||||||
static final UserPassResources I = GWT.create(UserPassResources.class);
|
|
||||||
|
|
||||||
@Source("userpass.css")
|
|
||||||
UserPassCss css();
|
|
||||||
}
|
|
@@ -1,240 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.userpass;
|
|
||||||
|
|
||||||
import com.google.gerrit.client.Gerrit;
|
|
||||||
import com.google.gerrit.client.SignInDialog;
|
|
||||||
import com.google.gerrit.client.rpc.GerritCallback;
|
|
||||||
import com.google.gerrit.client.ui.SmallHeading;
|
|
||||||
import com.google.gerrit.common.PageLinks;
|
|
||||||
import com.google.gerrit.common.auth.SignInMode;
|
|
||||||
import com.google.gerrit.common.auth.userpass.LoginResult;
|
|
||||||
import com.google.gwt.core.client.Scheduler;
|
|
||||||
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
|
||||||
import com.google.gwt.event.dom.client.ClickEvent;
|
|
||||||
import com.google.gwt.event.dom.client.ClickHandler;
|
|
||||||
import com.google.gwt.event.dom.client.KeyCodes;
|
|
||||||
import com.google.gwt.event.dom.client.KeyPressEvent;
|
|
||||||
import com.google.gwt.event.dom.client.KeyPressHandler;
|
|
||||||
import com.google.gwt.user.client.DOM;
|
|
||||||
import com.google.gwt.user.client.Window.Location;
|
|
||||||
import com.google.gwt.user.client.ui.Button;
|
|
||||||
import com.google.gwt.user.client.ui.FlowPanel;
|
|
||||||
import com.google.gwt.user.client.ui.Grid;
|
|
||||||
import com.google.gwt.user.client.ui.InlineLabel;
|
|
||||||
import com.google.gwt.user.client.ui.PasswordTextBox;
|
|
||||||
import com.google.gwt.user.client.ui.TextBox;
|
|
||||||
import com.google.gwtexpui.globalkey.client.GlobalKey;
|
|
||||||
import com.google.gwtexpui.globalkey.client.NpTextBox;
|
|
||||||
|
|
||||||
public class UserPassSignInDialog extends SignInDialog {
|
|
||||||
static {
|
|
||||||
UserPassResources.I.css().ensureInjected();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final FlowPanel formBody;
|
|
||||||
|
|
||||||
private FlowPanel errorLine;
|
|
||||||
private InlineLabel errorMsg;
|
|
||||||
|
|
||||||
private Button login;
|
|
||||||
private Button close;
|
|
||||||
private TextBox username;
|
|
||||||
private TextBox password;
|
|
||||||
|
|
||||||
public UserPassSignInDialog(final String token, final String initialErrorMsg) {
|
|
||||||
super(SignInMode.SIGN_IN, token);
|
|
||||||
setAutoHideEnabled(false);
|
|
||||||
|
|
||||||
formBody = new FlowPanel();
|
|
||||||
formBody.setStyleName(UserPassResources.I.css().loginForm());
|
|
||||||
add(formBody);
|
|
||||||
|
|
||||||
createHeaderText();
|
|
||||||
createErrorBox();
|
|
||||||
createUsernameBox();
|
|
||||||
if (initialErrorMsg != null) {
|
|
||||||
showError(initialErrorMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void show() {
|
|
||||||
super.show();
|
|
||||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
|
||||||
@Override
|
|
||||||
public void execute() {
|
|
||||||
username.setFocus(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createHeaderText() {
|
|
||||||
final FlowPanel headerText = new FlowPanel();
|
|
||||||
final SmallHeading headerLabel = new SmallHeading();
|
|
||||||
headerLabel.setText(Util.M.signInAt(Location.getHostName()));
|
|
||||||
headerText.add(headerLabel);
|
|
||||||
formBody.add(headerText);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createErrorBox() {
|
|
||||||
errorLine = new FlowPanel();
|
|
||||||
DOM.setStyleAttribute(errorLine.getElement(), "visibility", "hidden");
|
|
||||||
errorLine.setStyleName(UserPassResources.I.css().error());
|
|
||||||
|
|
||||||
errorMsg = new InlineLabel();
|
|
||||||
errorLine.add(errorMsg);
|
|
||||||
formBody.add(errorLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showError(final String msgText) {
|
|
||||||
errorMsg.setText(msgText);
|
|
||||||
DOM.setStyleAttribute(errorLine.getElement(), "visibility", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hideError() {
|
|
||||||
DOM.setStyleAttribute(errorLine.getElement(), "visibility", "hidden");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createUsernameBox() {
|
|
||||||
username = new NpTextBox();
|
|
||||||
username.setVisibleLength(25);
|
|
||||||
username.addKeyPressHandler(new KeyPressHandler() {
|
|
||||||
@Override
|
|
||||||
public void onKeyPress(final KeyPressEvent event) {
|
|
||||||
if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
|
|
||||||
event.preventDefault();
|
|
||||||
password.selectAll();
|
|
||||||
password.setFocus(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
password = new PasswordTextBox();
|
|
||||||
password.setVisibleLength(25);
|
|
||||||
password.addKeyPressHandler(GlobalKey.STOP_PROPAGATION);
|
|
||||||
password.addKeyPressHandler(new KeyPressHandler() {
|
|
||||||
@Override
|
|
||||||
public void onKeyPress(final KeyPressEvent event) {
|
|
||||||
if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
|
|
||||||
event.preventDefault();
|
|
||||||
onLogin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final FlowPanel buttons = new FlowPanel();
|
|
||||||
buttons.setStyleName(Gerrit.RESOURCES.css().errorDialogButtons());
|
|
||||||
|
|
||||||
login = new Button();
|
|
||||||
login.setText(Util.C.buttonSignIn());
|
|
||||||
login.addClickHandler(new ClickHandler() {
|
|
||||||
@Override
|
|
||||||
public void onClick(final ClickEvent event) {
|
|
||||||
onLogin();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
buttons.add(login);
|
|
||||||
|
|
||||||
close = new Button();
|
|
||||||
DOM.setStyleAttribute(close.getElement(), "marginLeft", "45px");
|
|
||||||
close.setText(Gerrit.C.signInDialogClose());
|
|
||||||
close.addClickHandler(new ClickHandler() {
|
|
||||||
@Override
|
|
||||||
public void onClick(ClickEvent event) {
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
buttons.add(close);
|
|
||||||
|
|
||||||
final Grid formGrid = new Grid(3, 2);
|
|
||||||
formGrid.setText(0, 0, Util.C.username());
|
|
||||||
formGrid.setText(1, 0, Util.C.password());
|
|
||||||
formGrid.setWidget(0, 1, username);
|
|
||||||
formGrid.setWidget(1, 1, password);
|
|
||||||
formGrid.setWidget(2, 1, buttons);
|
|
||||||
formBody.add(formGrid);
|
|
||||||
|
|
||||||
username.setTabIndex(1);
|
|
||||||
password.setTabIndex(2);
|
|
||||||
login.setTabIndex(3);
|
|
||||||
close.setTabIndex(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enable(final boolean on) {
|
|
||||||
username.setEnabled(on);
|
|
||||||
password.setEnabled(on);
|
|
||||||
login.setEnabled(on);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onLogin() {
|
|
||||||
hideError();
|
|
||||||
|
|
||||||
final String user = username.getText();
|
|
||||||
if (user == null || user.equals("")) {
|
|
||||||
showError(Util.C.usernameRequired());
|
|
||||||
username.setFocus(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String pass = password.getText();
|
|
||||||
if (pass == null || pass.equals("")) {
|
|
||||||
showError(Util.C.passwordRequired());
|
|
||||||
password.setFocus(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
enable(false);
|
|
||||||
Util.SVC.authenticate(user, pass, new GerritCallback<LoginResult>() {
|
|
||||||
public void onSuccess(final LoginResult result) {
|
|
||||||
if (result.success) {
|
|
||||||
String to = token;
|
|
||||||
if (!to.startsWith("/")) {
|
|
||||||
to = "/" + to;
|
|
||||||
}
|
|
||||||
if (result.isNew && !token.startsWith(PageLinks.REGISTER + "/")) {
|
|
||||||
to = PageLinks.REGISTER + to;
|
|
||||||
}
|
|
||||||
Location.replace(Location.getPath() + "login" + to);
|
|
||||||
} else {
|
|
||||||
final String message;
|
|
||||||
switch (result.getError()) {
|
|
||||||
case AUTHENTICATION_UNAVAILABLE:
|
|
||||||
message = Util.M.authenticationUnavailable(result.getAuthType());
|
|
||||||
break;
|
|
||||||
case INVALID_LOGIN:
|
|
||||||
default:
|
|
||||||
message = Util.C.invalidLogin();
|
|
||||||
}
|
|
||||||
showError(message);
|
|
||||||
enable(true);
|
|
||||||
password.selectAll();
|
|
||||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
|
||||||
@Override
|
|
||||||
public void execute() {
|
|
||||||
password.setFocus(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(final Throwable caught) {
|
|
||||||
super.onFailure(caught);
|
|
||||||
enable(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,30 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.userpass;
|
|
||||||
|
|
||||||
import com.google.gerrit.common.auth.userpass.UserPassAuthService;
|
|
||||||
import com.google.gwt.core.client.GWT;
|
|
||||||
import com.google.gwtjsonrpc.client.JsonUtil;
|
|
||||||
|
|
||||||
public class Util {
|
|
||||||
public static final UserPassConstants C = GWT.create(UserPassConstants.class);
|
|
||||||
public static final UserPassMessages M = GWT.create(UserPassMessages.class);
|
|
||||||
public static final UserPassAuthService SVC;
|
|
||||||
|
|
||||||
static {
|
|
||||||
SVC = GWT.create(UserPassAuthService.class);
|
|
||||||
JsonUtil.bind(SVC, "rpc/UserPassAuthService");
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,32 +0,0 @@
|
|||||||
/* Copyright (C) 2009 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.loginForm {
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
padding-top: 5px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error span {
|
|
||||||
padding-top: 4px;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
padding-left: 10px;
|
|
||||||
padding-right: 10px;
|
|
||||||
background: #fff1a8;
|
|
||||||
}
|
|
@@ -83,14 +83,6 @@ class GerritConfigProvider implements Provider<GerritConfig> {
|
|||||||
private GerritConfig create() throws MalformedURLException {
|
private GerritConfig create() throws MalformedURLException {
|
||||||
final GerritConfig config = new GerritConfig();
|
final GerritConfig config = new GerritConfig();
|
||||||
switch (authConfig.getAuthType()) {
|
switch (authConfig.getAuthType()) {
|
||||||
case OPENID:
|
|
||||||
config.setAllowedOpenIDs(authConfig.getAllowedOpenIDs());
|
|
||||||
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"));
|
||||||
@@ -109,6 +101,8 @@ class GerritConfigProvider implements Provider<GerritConfig> {
|
|||||||
case DEVELOPMENT_BECOME_ANY_ACCOUNT:
|
case DEVELOPMENT_BECOME_ANY_ACCOUNT:
|
||||||
case HTTP:
|
case HTTP:
|
||||||
case HTTP_LDAP:
|
case HTTP_LDAP:
|
||||||
|
case OPENID:
|
||||||
|
case OPENID_SSO:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
config.setUseContributorAgreements(cfg.getBoolean("auth",
|
config.setUseContributorAgreements(cfg.getBoolean("auth",
|
||||||
|
@@ -20,7 +20,7 @@ import static com.google.inject.Scopes.SINGLETON;
|
|||||||
import com.google.gerrit.common.data.GerritConfig;
|
import com.google.gerrit.common.data.GerritConfig;
|
||||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||||
import com.google.gerrit.extensions.webui.WebUiPlugin;
|
import com.google.gerrit.extensions.webui.WebUiPlugin;
|
||||||
import com.google.gerrit.httpd.auth.become.BecomeAnyAccountLoginServlet;
|
import com.google.gerrit.httpd.auth.become.BecomeAnyAccountModule;
|
||||||
import com.google.gerrit.httpd.auth.container.HttpAuthModule;
|
import com.google.gerrit.httpd.auth.container.HttpAuthModule;
|
||||||
import com.google.gerrit.httpd.auth.container.HttpsClientSslCertModule;
|
import com.google.gerrit.httpd.auth.container.HttpsClientSslCertModule;
|
||||||
import com.google.gerrit.httpd.auth.ldap.LdapAuthModule;
|
import com.google.gerrit.httpd.auth.ldap.LdapAuthModule;
|
||||||
@@ -45,7 +45,6 @@ import com.google.inject.Inject;
|
|||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.ProvisionException;
|
import com.google.inject.ProvisionException;
|
||||||
import com.google.inject.servlet.RequestScoped;
|
import com.google.inject.servlet.RequestScoped;
|
||||||
import com.google.inject.servlet.ServletModule;
|
|
||||||
|
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
@@ -103,12 +102,7 @@ public class WebModule extends FactoryModule {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DEVELOPMENT_BECOME_ANY_ACCOUNT:
|
case DEVELOPMENT_BECOME_ANY_ACCOUNT:
|
||||||
install(new ServletModule() {
|
install(new BecomeAnyAccountModule());
|
||||||
@Override
|
|
||||||
protected void configureServlets() {
|
|
||||||
serve("/become").with(BecomeAnyAccountLoginServlet.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPENID:
|
case OPENID:
|
||||||
|
@@ -16,6 +16,8 @@ package com.google.gerrit.httpd.auth.become;
|
|||||||
|
|
||||||
import static com.google.gerrit.reviewdb.client.AccountExternalId.SCHEME_USERNAME;
|
import static com.google.gerrit.reviewdb.client.AccountExternalId.SCHEME_USERNAME;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
import com.google.gerrit.common.PageLinks;
|
import com.google.gerrit.common.PageLinks;
|
||||||
import com.google.gerrit.httpd.HtmlDomUtil;
|
import com.google.gerrit.httpd.HtmlDomUtil;
|
||||||
import com.google.gerrit.httpd.WebSession;
|
import com.google.gerrit.httpd.WebSession;
|
||||||
@@ -52,7 +54,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
@Singleton
|
@Singleton
|
||||||
public class BecomeAnyAccountLoginServlet extends HttpServlet {
|
class BecomeAnyAccountLoginServlet extends HttpServlet {
|
||||||
private static final boolean IS_DEV = Boolean.getBoolean("Gerrit.GwtDevMode");
|
private static final boolean IS_DEV = Boolean.getBoolean("Gerrit.GwtDevMode");
|
||||||
|
|
||||||
private final SchemaFactory<ReviewDb> schema;
|
private final SchemaFactory<ReviewDb> schema;
|
||||||
@@ -114,7 +116,9 @@ public class BecomeAnyAccountLoginServlet extends HttpServlet {
|
|||||||
if (res != null) {
|
if (res != null) {
|
||||||
webSession.get().login(res, false);
|
webSession.get().login(res, false);
|
||||||
final StringBuilder rdr = new StringBuilder();
|
final StringBuilder rdr = new StringBuilder();
|
||||||
rdr.append(req.getContextPath());
|
rdr.append(Objects.firstNonNull(
|
||||||
|
Strings.emptyToNull(req.getContextPath()),
|
||||||
|
"/"));
|
||||||
if (IS_DEV && req.getParameter("gwt.codesvr") != null) {
|
if (IS_DEV && req.getParameter("gwt.codesvr") != null) {
|
||||||
if (rdr.indexOf("?") < 0) {
|
if (rdr.indexOf("?") < 0) {
|
||||||
rdr.append("?");
|
rdr.append("?");
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2009 The Android Open Source Project
|
// Copyright (C) 2013 The Android Open Source Project
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@@ -12,15 +12,13 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package com.google.gerrit.client.auth.openid;
|
package com.google.gerrit.httpd.auth.become;
|
||||||
|
|
||||||
import com.google.gwt.resources.client.CssResource;
|
import com.google.inject.servlet.ServletModule;
|
||||||
|
|
||||||
interface OpenIdCss extends CssResource {
|
public class BecomeAnyAccountModule extends ServletModule {
|
||||||
String loginForm();
|
@Override
|
||||||
String logo();
|
protected void configureServlets() {
|
||||||
String loginLine();
|
serve("/login", "/login/*").with(BecomeAnyAccountLoginServlet.class);
|
||||||
String identifier();
|
}
|
||||||
String directLink();
|
|
||||||
String error();
|
|
||||||
}
|
}
|
@@ -21,6 +21,6 @@ public class HttpAuthModule extends ServletModule {
|
|||||||
@Override
|
@Override
|
||||||
protected void configureServlets() {
|
protected void configureServlets() {
|
||||||
filter("/").through(HttpAuthFilter.class);
|
filter("/").through(HttpAuthFilter.class);
|
||||||
serve("/login/*").with(HttpLoginServlet.class);
|
serve("/login", "/login/*").with(HttpLoginServlet.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,6 @@ public class HttpsClientSslCertModule extends ServletModule {
|
|||||||
@Override
|
@Override
|
||||||
protected void configureServlets() {
|
protected void configureServlets() {
|
||||||
filter("/").through(HttpsClientSslCertAuthFilter.class);
|
filter("/").through(HttpsClientSslCertAuthFilter.class);
|
||||||
serve("/login/*").with(HttpsClientSslCertLoginServlet.class);
|
serve("/login", "/login/*").with(HttpsClientSslCertLoginServlet.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,20 +14,12 @@
|
|||||||
|
|
||||||
package com.google.gerrit.httpd.auth.ldap;
|
package com.google.gerrit.httpd.auth.ldap;
|
||||||
|
|
||||||
import com.google.gerrit.httpd.rpc.RpcServletModule;
|
|
||||||
import com.google.gerrit.httpd.rpc.UiRpcModule;
|
|
||||||
import com.google.inject.servlet.ServletModule;
|
import com.google.inject.servlet.ServletModule;
|
||||||
|
|
||||||
/** RPC support related to username/password LDAP authentication. */
|
/** Configure username/password LDAP authentication. */
|
||||||
public class LdapAuthModule extends ServletModule {
|
public class LdapAuthModule extends ServletModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configureServlets() {
|
protected void configureServlets() {
|
||||||
serve("/login/*").with(LoginRedirectServlet.class);
|
serve("/login", "/login/*").with(LdapLoginServlet.class);
|
||||||
install(new RpcServletModule(UiRpcModule.PREFIX) {
|
|
||||||
@Override
|
|
||||||
protected void configureServlets() {
|
|
||||||
rpc(UserPassAuthServiceImpl.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,166 @@
|
|||||||
|
// Copyright (C) 2009 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.httpd.auth.ldap;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.gerrit.common.PageLinks;
|
||||||
|
import com.google.gerrit.httpd.HtmlDomUtil;
|
||||||
|
import com.google.gerrit.httpd.WebSession;
|
||||||
|
import com.google.gerrit.server.account.AccountException;
|
||||||
|
import com.google.gerrit.server.account.AccountManager;
|
||||||
|
import com.google.gerrit.server.account.AccountUserNameException;
|
||||||
|
import com.google.gerrit.server.account.AuthRequest;
|
||||||
|
import com.google.gerrit.server.account.AuthResult;
|
||||||
|
import com.google.gerrit.server.auth.AuthenticationUnavailableException;
|
||||||
|
import com.google.gerrit.server.config.CanonicalWebUrl;
|
||||||
|
import com.google.gwtexpui.server.CacheHeaders;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/** Handles username/password based authentication against the directory. */
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
@Singleton
|
||||||
|
class LdapLoginServlet extends HttpServlet {
|
||||||
|
private static final Logger log = LoggerFactory
|
||||||
|
.getLogger(LdapLoginServlet.class);
|
||||||
|
|
||||||
|
private final AccountManager accountManager;
|
||||||
|
private final Provider<WebSession> webSession;
|
||||||
|
private final Provider<String> urlProvider;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
LdapLoginServlet(AccountManager accountManager,
|
||||||
|
Provider<WebSession> webSession,
|
||||||
|
@CanonicalWebUrl @Nullable Provider<String> urlProvider) {
|
||||||
|
this.accountManager = accountManager;
|
||||||
|
this.webSession = webSession;
|
||||||
|
this.urlProvider = urlProvider;
|
||||||
|
|
||||||
|
if (Strings.isNullOrEmpty(urlProvider.get())) {
|
||||||
|
log.error("gerrit.canonicalWebUrl must be set in gerrit.config");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendForm(HttpServletRequest req, HttpServletResponse res,
|
||||||
|
@Nullable String errorMessage) throws IOException {
|
||||||
|
String self = req.getRequestURI();
|
||||||
|
String cancel = Objects.firstNonNull(urlProvider.get(), "/");
|
||||||
|
String token = getToken(req);
|
||||||
|
if (!token.equals("/")) {
|
||||||
|
cancel += "#" + token;
|
||||||
|
}
|
||||||
|
|
||||||
|
Document doc =
|
||||||
|
HtmlDomUtil.parseFile(LdapLoginServlet.class, "LoginForm.html");
|
||||||
|
HtmlDomUtil.find(doc, "hostName").setTextContent(req.getServerName());
|
||||||
|
HtmlDomUtil.find(doc, "login_form").setAttribute("action", self);
|
||||||
|
HtmlDomUtil.find(doc, "cancel_link").setAttribute("href", cancel);
|
||||||
|
|
||||||
|
Element emsg = HtmlDomUtil.find(doc, "error_message");
|
||||||
|
if (Strings.isNullOrEmpty(errorMessage)) {
|
||||||
|
emsg.getParentNode().removeChild(emsg);
|
||||||
|
} else {
|
||||||
|
emsg.setTextContent(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] bin = HtmlDomUtil.toUTF8(doc);
|
||||||
|
res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
res.setContentType("text/html");
|
||||||
|
res.setCharacterEncoding("UTF-8");
|
||||||
|
res.setContentLength(bin.length);
|
||||||
|
ServletOutputStream out = res.getOutputStream();
|
||||||
|
try {
|
||||||
|
out.write(bin);
|
||||||
|
} finally {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest req, HttpServletResponse res)
|
||||||
|
throws IOException {
|
||||||
|
sendForm(req, res, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest req, HttpServletResponse res)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
String username = Strings.nullToEmpty(req.getParameter("username")).trim();
|
||||||
|
String password = Strings.nullToEmpty(req.getParameter("password"));
|
||||||
|
String remember = Strings.nullToEmpty(req.getParameter("rememberme"));
|
||||||
|
if (username.isEmpty() || password.isEmpty()) {
|
||||||
|
sendForm(req, res, "Invalid username or password.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthRequest areq = AuthRequest.forUser(username);
|
||||||
|
areq.setPassword(password);
|
||||||
|
|
||||||
|
AuthResult ares;
|
||||||
|
try {
|
||||||
|
ares = accountManager.authenticate(areq);
|
||||||
|
} catch (AccountUserNameException e) {
|
||||||
|
sendForm(req, res, e.getMessage());
|
||||||
|
return;
|
||||||
|
} catch (AuthenticationUnavailableException e) {
|
||||||
|
sendForm(req, res, "Authentication unavailable at this time.");
|
||||||
|
return;
|
||||||
|
} catch (AccountException e) {
|
||||||
|
log.info(String.format("'%s' failed to sign in: %s", username, e.getMessage()));
|
||||||
|
sendForm(req, res, "Invalid username or password.");
|
||||||
|
return;
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
log.error("LDAP authentication failed", e);
|
||||||
|
sendForm(req, res, "Authentication unavailable at this time.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = getToken(req);
|
||||||
|
StringBuilder dest = new StringBuilder();
|
||||||
|
dest.append(urlProvider.get());
|
||||||
|
dest.append('#');
|
||||||
|
dest.append(token);
|
||||||
|
|
||||||
|
CacheHeaders.setNotCacheable(res);
|
||||||
|
webSession.get().login(ares, "1".equals(remember));
|
||||||
|
res.sendRedirect(dest.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getToken(final HttpServletRequest req) {
|
||||||
|
String token = req.getPathInfo();
|
||||||
|
if (token == null || token.isEmpty()) {
|
||||||
|
token = PageLinks.MINE;
|
||||||
|
} else if (!token.startsWith("/")) {
|
||||||
|
token = "/" + token;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,84 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.httpd.auth.ldap;
|
|
||||||
|
|
||||||
import com.google.gerrit.common.PageLinks;
|
|
||||||
import com.google.gerrit.common.auth.SignInMode;
|
|
||||||
import com.google.gerrit.httpd.WebSession;
|
|
||||||
import com.google.gerrit.server.config.CanonicalWebUrl;
|
|
||||||
import com.google.gwtexpui.server.CacheHeaders;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Provider;
|
|
||||||
import com.google.inject.Singleton;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Servlet bound to {@code /login/*} to redirect after user/pass sign-in.
|
|
||||||
* <p>
|
|
||||||
* This servlet is required because user authentication is done over RPC, but if
|
|
||||||
* the RPC is successful we need to force the host page to fully reload to pick
|
|
||||||
* up the account information, as we don't support updating the UI on the fly
|
|
||||||
* after a sign-in.
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
class LoginRedirectServlet extends HttpServlet {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private final Provider<WebSession> webSession;
|
|
||||||
private final Provider<String> urlProvider;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
LoginRedirectServlet(final Provider<WebSession> webSession,
|
|
||||||
@CanonicalWebUrl @Nullable final Provider<String> urlProvider) {
|
|
||||||
this.webSession = webSession;
|
|
||||||
this.urlProvider = urlProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doGet(final HttpServletRequest req,
|
|
||||||
final HttpServletResponse rsp) throws IOException {
|
|
||||||
final String token;
|
|
||||||
if (webSession.get().isSignedIn()) {
|
|
||||||
token = getToken(req);
|
|
||||||
} else {
|
|
||||||
final String msg = "Session cookie not available.";
|
|
||||||
token = "/SignInFailure," + SignInMode.SIGN_IN + "," + msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
final StringBuilder rdr = new StringBuilder();
|
|
||||||
rdr.append(urlProvider.get());
|
|
||||||
rdr.append('#');
|
|
||||||
rdr.append(token);
|
|
||||||
|
|
||||||
CacheHeaders.setNotCacheable(rsp);
|
|
||||||
rsp.sendRedirect(rdr.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getToken(final HttpServletRequest req) {
|
|
||||||
String token = req.getPathInfo();
|
|
||||||
if (token == null || token.isEmpty()) {
|
|
||||||
token = PageLinks.MINE;
|
|
||||||
} else if (!token.startsWith("/")) {
|
|
||||||
token = "/" + token;
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,92 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.httpd.auth.ldap;
|
|
||||||
|
|
||||||
import com.google.gerrit.common.auth.userpass.LoginResult;
|
|
||||||
import com.google.gerrit.common.auth.userpass.UserPassAuthService;
|
|
||||||
import com.google.gerrit.httpd.WebSession;
|
|
||||||
import com.google.gerrit.reviewdb.client.AuthType;
|
|
||||||
import com.google.gerrit.server.account.AccountException;
|
|
||||||
import com.google.gerrit.server.account.AccountManager;
|
|
||||||
import com.google.gerrit.server.account.AccountUserNameException;
|
|
||||||
import com.google.gerrit.server.account.AuthRequest;
|
|
||||||
import com.google.gerrit.server.account.AuthResult;
|
|
||||||
import com.google.gerrit.server.auth.AuthenticationUnavailableException;
|
|
||||||
import com.google.gerrit.server.config.AuthConfig;
|
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Provider;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
class UserPassAuthServiceImpl implements UserPassAuthService {
|
|
||||||
private final Provider<WebSession> webSession;
|
|
||||||
private final AccountManager accountManager;
|
|
||||||
private final AuthType authType;
|
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory
|
|
||||||
.getLogger(UserPassAuthServiceImpl.class);
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
UserPassAuthServiceImpl(final Provider<WebSession> webSession,
|
|
||||||
final AccountManager accountManager, final AuthConfig authConfig) {
|
|
||||||
this.webSession = webSession;
|
|
||||||
this.accountManager = accountManager;
|
|
||||||
this.authType = authConfig.getAuthType();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void authenticate(String username, final String password,
|
|
||||||
final AsyncCallback<LoginResult> callback) {
|
|
||||||
LoginResult result = new LoginResult(authType);
|
|
||||||
if (username == null || "".equals(username.trim()) //
|
|
||||||
|| password == null || "".equals(password)) {
|
|
||||||
result.setError(LoginResult.Error.INVALID_LOGIN);
|
|
||||||
callback.onSuccess(result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
username = username.trim();
|
|
||||||
|
|
||||||
final AuthRequest req = AuthRequest.forUser(username);
|
|
||||||
req.setPassword(password);
|
|
||||||
|
|
||||||
final AuthResult res;
|
|
||||||
try {
|
|
||||||
res = accountManager.authenticate(req);
|
|
||||||
} catch (AccountUserNameException e) {
|
|
||||||
// entered user name and password were correct, but user name could not be
|
|
||||||
// set for the newly created account and this is why the login fails,
|
|
||||||
// error screen with error message should be shown to the user
|
|
||||||
callback.onFailure(e);
|
|
||||||
return;
|
|
||||||
} catch (AuthenticationUnavailableException e) {
|
|
||||||
result.setError(LoginResult.Error.AUTHENTICATION_UNAVAILABLE);
|
|
||||||
callback.onSuccess(result);
|
|
||||||
return;
|
|
||||||
} catch (AccountException e) {
|
|
||||||
log.info(String.format("'%s' failed to sign in: %s", username, e.getMessage()));
|
|
||||||
result.setError(LoginResult.Error.INVALID_LOGIN);
|
|
||||||
callback.onSuccess(result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.success = true;
|
|
||||||
result.isNew = res.isNew();
|
|
||||||
webSession.get().login(res, true /* persistent cookie */);
|
|
||||||
callback.onSuccess(result);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,75 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Gerrit Code Review - Sign In</title>
|
||||||
|
<style>
|
||||||
|
#error_message {
|
||||||
|
padding: 5px;
|
||||||
|
margin: 2em;
|
||||||
|
width: 20em;
|
||||||
|
background-color: rgb(255, 255, 116);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
#cancel_link {
|
||||||
|
margin-left: 45px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Sign In to Gerrit Code Review at <span id="hostName">example.com</span></h1>
|
||||||
|
<div id="error_message">Invalid username or password.</div>
|
||||||
|
<form method="POST" action="#" id="login_form">
|
||||||
|
<table style="border: 0;">
|
||||||
|
<tr>
|
||||||
|
<th>Username</th>
|
||||||
|
<td><input name="username" id="f_user"
|
||||||
|
type="text"
|
||||||
|
size="25"
|
||||||
|
tabindex="1" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Password</th>
|
||||||
|
<td><input name="password" id="f_pass"
|
||||||
|
type="password"
|
||||||
|
size="25"
|
||||||
|
tabindex="2" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<input name="rememberme" id="f_remember"
|
||||||
|
type="checkbox"
|
||||||
|
value="1"
|
||||||
|
tabindex="3" />
|
||||||
|
<label for="f_remember">Remember me</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<input type="submit" value="Sign In" tabindex="4"/>
|
||||||
|
<a href="../" id="cancel_link">Cancel</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script type="text/javascript" language="javascript">
|
||||||
|
var login_form = document.getElementById('login_form');
|
||||||
|
var f_user = document.getElementById('f_user');
|
||||||
|
var f_pass = document.getElementById('f_pass');
|
||||||
|
f_user.onkeydown = function(e) {
|
||||||
|
if (e.keyCode == 13) {
|
||||||
|
f_pass.focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f_pass.onkeydown = function(e) {
|
||||||
|
if (e.keyCode == 13) {
|
||||||
|
login_form.submit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f_user.focus();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -12,18 +12,15 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package com.google.gerrit.common.auth.openid;
|
package com.google.gerrit.httpd.auth.openid;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public final class DiscoveryResult {
|
final class DiscoveryResult {
|
||||||
public static enum Status {
|
static enum Status {
|
||||||
/** Provider was discovered and {@code providerUrl} is valid. */
|
/** Provider was discovered and {@code providerUrl} is valid. */
|
||||||
VALID,
|
VALID,
|
||||||
|
|
||||||
/** The identifier is not allowed to be used, by site configuration. */
|
|
||||||
NOT_ALLOWED,
|
|
||||||
|
|
||||||
/** Identifier isn't for an OpenID provider. */
|
/** Identifier isn't for an OpenID provider. */
|
||||||
NO_PROVIDER,
|
NO_PROVIDER,
|
||||||
|
|
||||||
@@ -31,20 +28,20 @@ public final class DiscoveryResult {
|
|||||||
ERROR;
|
ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Status status;
|
Status status;
|
||||||
public String providerUrl;
|
String providerUrl;
|
||||||
public Map<String, String> providerArgs;
|
Map<String, String> providerArgs;
|
||||||
|
|
||||||
protected DiscoveryResult() {
|
DiscoveryResult() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiscoveryResult(final String redirect, final Map<String, String> args) {
|
DiscoveryResult(String redirect, Map<String, String> args) {
|
||||||
status = Status.VALID;
|
status = Status.VALID;
|
||||||
providerUrl = redirect;
|
providerUrl = redirect;
|
||||||
providerArgs = args;
|
providerArgs = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiscoveryResult(final Status s) {
|
DiscoveryResult(Status s) {
|
||||||
status = s;
|
status = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,306 @@
|
|||||||
|
// Copyright (C) 2009 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.httpd.auth.openid;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.gerrit.common.PageLinks;
|
||||||
|
import com.google.gerrit.common.auth.openid.OpenIdUrls;
|
||||||
|
import com.google.gerrit.extensions.restapi.Url;
|
||||||
|
import com.google.gerrit.httpd.HtmlDomUtil;
|
||||||
|
import com.google.gerrit.reviewdb.client.AuthType;
|
||||||
|
import com.google.gerrit.server.config.AuthConfig;
|
||||||
|
import com.google.gerrit.server.config.CanonicalWebUrl;
|
||||||
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.Config;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/** Handles OpenID based login flow. */
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
@Singleton
|
||||||
|
class LoginForm extends HttpServlet {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(LoginForm.class);
|
||||||
|
private static final ImmutableMap<String, String> ALL_PROVIDERS = ImmutableMap.of(
|
||||||
|
"google", OpenIdUrls.URL_GOOGLE,
|
||||||
|
"yahoo", OpenIdUrls.URL_YAHOO);
|
||||||
|
|
||||||
|
private final ImmutableSet<String> suggestProviders;
|
||||||
|
private final Provider<String> urlProvider;
|
||||||
|
private final OpenIdServiceImpl impl;
|
||||||
|
private final int maxRedirectUrlLength;
|
||||||
|
private final String ssoUrl;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
LoginForm(
|
||||||
|
@CanonicalWebUrl @Nullable Provider<String> urlProvider,
|
||||||
|
@GerritServerConfig Config config,
|
||||||
|
AuthConfig authConfig,
|
||||||
|
OpenIdServiceImpl impl) {
|
||||||
|
this.urlProvider = urlProvider;
|
||||||
|
this.impl = impl;
|
||||||
|
this.maxRedirectUrlLength = config.getInt(
|
||||||
|
"openid", "maxRedirectUrlLength",
|
||||||
|
10);
|
||||||
|
|
||||||
|
if (Strings.isNullOrEmpty(urlProvider.get())) {
|
||||||
|
log.error("gerrit.canonicalWebUrl must be set in gerrit.config");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authConfig.getAuthType() == AuthType.OPENID_SSO) {
|
||||||
|
suggestProviders = ImmutableSet.of();
|
||||||
|
ssoUrl = authConfig.getOpenIdSsoUrl();
|
||||||
|
} else {
|
||||||
|
Set<String> providers = Sets.newHashSet();
|
||||||
|
for (Map.Entry<String, String> e : ALL_PROVIDERS.entrySet()) {
|
||||||
|
if (impl.isAllowedOpenID(e.getValue())) {
|
||||||
|
providers.add(e.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
suggestProviders = ImmutableSet.copyOf(providers);
|
||||||
|
ssoUrl = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest req, HttpServletResponse res)
|
||||||
|
throws IOException {
|
||||||
|
if (ssoUrl != null) {
|
||||||
|
String token = getToken(req);
|
||||||
|
SignInMode mode;
|
||||||
|
if (PageLinks.REGISTER.equals(token)) {
|
||||||
|
mode = SignInMode.REGISTER;
|
||||||
|
token = PageLinks.MINE;
|
||||||
|
} else {
|
||||||
|
mode = SignInMode.SIGN_IN;
|
||||||
|
}
|
||||||
|
discover(req, res, false, ssoUrl, false, token, mode);
|
||||||
|
} else {
|
||||||
|
String id = Strings.nullToEmpty(req.getParameter("id")).trim();
|
||||||
|
if (!id.isEmpty()) {
|
||||||
|
doPost(req, res);
|
||||||
|
} else {
|
||||||
|
boolean link = req.getParameter("link") != null;
|
||||||
|
sendForm(req, res, link, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest req, HttpServletResponse res)
|
||||||
|
throws IOException {
|
||||||
|
boolean link = req.getParameter("link") != null;
|
||||||
|
String id = Strings.nullToEmpty(req.getParameter("id")).trim();
|
||||||
|
if (id.isEmpty()) {
|
||||||
|
sendForm(req, res, link, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!id.startsWith("http://") && !id.startsWith("https://")) {
|
||||||
|
id = "http://" + id;
|
||||||
|
}
|
||||||
|
if ((ssoUrl != null && !ssoUrl.equals(id)) || !impl.isAllowedOpenID(id)) {
|
||||||
|
sendForm(req, res, link, "OpenID provider not permitted by site policy.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean remember = "1".equals(req.getParameter("rememberme"));
|
||||||
|
String token = getToken(req);
|
||||||
|
SignInMode mode;
|
||||||
|
if (link) {
|
||||||
|
mode = SignInMode.LINK_IDENTIY;
|
||||||
|
} else if (PageLinks.REGISTER.equals(token)) {
|
||||||
|
mode = SignInMode.REGISTER;
|
||||||
|
token = PageLinks.MINE;
|
||||||
|
} else {
|
||||||
|
mode = SignInMode.SIGN_IN;
|
||||||
|
}
|
||||||
|
|
||||||
|
discover(req, res, link, id, remember, token, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void discover(HttpServletRequest req, HttpServletResponse res,
|
||||||
|
boolean link, String id, boolean remember, String token, SignInMode mode)
|
||||||
|
throws IOException {
|
||||||
|
if (ssoUrl != null) {
|
||||||
|
remember = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscoveryResult r = impl.discover(id, mode, remember, token);
|
||||||
|
switch (r.status) {
|
||||||
|
case VALID:
|
||||||
|
redirect(r, res);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NO_PROVIDER:
|
||||||
|
sendForm(req, res, link,
|
||||||
|
"Provider is not supported, or was incorrectly entered.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ERROR:
|
||||||
|
sendForm(req, res, link, "Unable to connect with OpenID provider.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void redirect(DiscoveryResult r, HttpServletResponse res)
|
||||||
|
throws IOException {
|
||||||
|
StringBuilder url = new StringBuilder();
|
||||||
|
url.append(r.providerUrl);
|
||||||
|
if (r.providerArgs != null && !r.providerArgs.isEmpty()) {
|
||||||
|
boolean first = true;
|
||||||
|
for(Map.Entry<String, String> arg : r.providerArgs.entrySet()) {
|
||||||
|
if (first) {
|
||||||
|
url.append('?');
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
url.append('&');
|
||||||
|
}
|
||||||
|
url.append(Url.encode(arg.getKey()))
|
||||||
|
.append('=')
|
||||||
|
.append(Url.encode(arg.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (url.length() <= maxRedirectUrlLength) {
|
||||||
|
res.sendRedirect(url.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Document doc = HtmlDomUtil.parseFile(LoginForm.class, "RedirectForm.html");
|
||||||
|
Element form = HtmlDomUtil.find(doc, "redirect_form");
|
||||||
|
form.setAttribute("action", r.providerUrl);
|
||||||
|
if (r.providerArgs != null && !r.providerArgs.isEmpty()) {
|
||||||
|
for (Map.Entry<String, String> arg : r.providerArgs.entrySet()) {
|
||||||
|
Element in = doc.createElement("input");
|
||||||
|
in.setAttribute("type", "hidden");
|
||||||
|
in.setAttribute("name", arg.getKey());
|
||||||
|
in.setAttribute("value", arg.getValue());
|
||||||
|
form.appendChild(in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendHtml(res, doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getToken(HttpServletRequest req) {
|
||||||
|
String token = req.getPathInfo();
|
||||||
|
if (token == null || token.isEmpty()) {
|
||||||
|
token = PageLinks.MINE;
|
||||||
|
} else if (!token.startsWith("/")) {
|
||||||
|
token = "/" + token;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendForm(HttpServletRequest req, HttpServletResponse res,
|
||||||
|
boolean link, @Nullable String errorMessage) throws IOException {
|
||||||
|
String self = req.getRequestURI();
|
||||||
|
String cancel = Objects.firstNonNull(urlProvider.get(), "/");
|
||||||
|
String token = getToken(req);
|
||||||
|
if (!token.equals("/")) {
|
||||||
|
cancel += "#" + token;
|
||||||
|
}
|
||||||
|
|
||||||
|
Document doc = HtmlDomUtil.parseFile(LoginForm.class, "LoginForm.html");
|
||||||
|
HtmlDomUtil.find(doc, "hostName").setTextContent(req.getServerName());
|
||||||
|
HtmlDomUtil.find(doc, "login_form").setAttribute("action", self);
|
||||||
|
HtmlDomUtil.find(doc, "cancel_link").setAttribute("href", cancel);
|
||||||
|
|
||||||
|
if (!link || ssoUrl != null) {
|
||||||
|
Element input = HtmlDomUtil.find(doc, "f_link");
|
||||||
|
input.getParentNode().removeChild(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
String last = getLastId(req);
|
||||||
|
if (last != null) {
|
||||||
|
HtmlDomUtil.find(doc, "f_openid").setAttribute("value", last);
|
||||||
|
}
|
||||||
|
|
||||||
|
Element emsg = HtmlDomUtil.find(doc, "error_message");
|
||||||
|
if (Strings.isNullOrEmpty(errorMessage)) {
|
||||||
|
emsg.getParentNode().removeChild(emsg);
|
||||||
|
} else {
|
||||||
|
emsg.setTextContent(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String name : ALL_PROVIDERS.keySet()) {
|
||||||
|
Element div = HtmlDomUtil.find(doc, "provider_" + name);
|
||||||
|
if (div == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!suggestProviders.contains(name)) {
|
||||||
|
div.getParentNode().removeChild(div);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Element a = HtmlDomUtil.find(div, "id_" + name);
|
||||||
|
if (a == null) {
|
||||||
|
div.getParentNode().removeChild(div);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
StringBuilder u = new StringBuilder();
|
||||||
|
u.append(self).append(a.getAttribute("href"));
|
||||||
|
if (link) {
|
||||||
|
u.append("&link");
|
||||||
|
}
|
||||||
|
a.setAttribute("href", u.toString());
|
||||||
|
}
|
||||||
|
sendHtml(res, doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendHtml(HttpServletResponse res, Document doc)
|
||||||
|
throws IOException {
|
||||||
|
byte[] bin = HtmlDomUtil.toUTF8(doc);
|
||||||
|
res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
res.setContentType("text/html");
|
||||||
|
res.setCharacterEncoding("UTF-8");
|
||||||
|
res.setContentLength(bin.length);
|
||||||
|
ServletOutputStream out = res.getOutputStream();
|
||||||
|
try {
|
||||||
|
out.write(bin);
|
||||||
|
} finally {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getLastId(HttpServletRequest req) {
|
||||||
|
Cookie[] cookies = req.getCookies();
|
||||||
|
if (cookies != null) {
|
||||||
|
for (Cookie c : cookies) {
|
||||||
|
if (OpenIdUrls.LASTID_COOKIE.equals(c.getName())) {
|
||||||
|
return c.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@@ -14,22 +14,16 @@
|
|||||||
|
|
||||||
package com.google.gerrit.httpd.auth.openid;
|
package com.google.gerrit.httpd.auth.openid;
|
||||||
|
|
||||||
import com.google.gerrit.httpd.rpc.RpcServletModule;
|
|
||||||
import com.google.inject.servlet.ServletModule;
|
import com.google.inject.servlet.ServletModule;
|
||||||
|
|
||||||
/** Servlets and RPC support related to OpenID authentication. */
|
/** Servlets related to OpenID authentication. */
|
||||||
public class OpenIdModule extends ServletModule {
|
public class OpenIdModule extends ServletModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configureServlets() {
|
protected void configureServlets() {
|
||||||
|
serve("/login", "/login/*").with(LoginForm.class);
|
||||||
serve("/" + OpenIdServiceImpl.RETURN_URL).with(OpenIdLoginServlet.class);
|
serve("/" + OpenIdServiceImpl.RETURN_URL).with(OpenIdLoginServlet.class);
|
||||||
serve("/" + XrdsServlet.LOCATION).with(XrdsServlet.class);
|
serve("/" + XrdsServlet.LOCATION).with(XrdsServlet.class);
|
||||||
filter("/").through(XrdsFilter.class);
|
filter("/").through(XrdsFilter.class);
|
||||||
|
bind(OpenIdServiceImpl.class);
|
||||||
install(new RpcServletModule(RpcServletModule.PREFIX) {
|
|
||||||
@Override
|
|
||||||
protected void configureServlets() {
|
|
||||||
rpc(OpenIdServiceImpl.class);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,10 +15,6 @@
|
|||||||
package com.google.gerrit.httpd.auth.openid;
|
package com.google.gerrit.httpd.auth.openid;
|
||||||
|
|
||||||
import com.google.gerrit.common.PageLinks;
|
import com.google.gerrit.common.PageLinks;
|
||||||
import com.google.gerrit.common.auth.SignInMode;
|
|
||||||
import com.google.gerrit.common.auth.openid.DiscoveryResult;
|
|
||||||
import com.google.gerrit.common.auth.openid.OpenIdProviderPattern;
|
|
||||||
import com.google.gerrit.common.auth.openid.OpenIdService;
|
|
||||||
import com.google.gerrit.common.auth.openid.OpenIdUrls;
|
import com.google.gerrit.common.auth.openid.OpenIdUrls;
|
||||||
import com.google.gerrit.httpd.WebSession;
|
import com.google.gerrit.httpd.WebSession;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
@@ -26,11 +22,11 @@ import com.google.gerrit.server.IdentifiedUser;
|
|||||||
import com.google.gerrit.server.UrlEncoded;
|
import com.google.gerrit.server.UrlEncoded;
|
||||||
import com.google.gerrit.server.account.AccountException;
|
import com.google.gerrit.server.account.AccountException;
|
||||||
import com.google.gerrit.server.account.AccountManager;
|
import com.google.gerrit.server.account.AccountManager;
|
||||||
|
import com.google.gerrit.server.auth.openid.OpenIdProviderPattern;
|
||||||
import com.google.gerrit.server.config.AuthConfig;
|
import com.google.gerrit.server.config.AuthConfig;
|
||||||
import com.google.gerrit.server.config.CanonicalWebUrl;
|
import com.google.gerrit.server.config.CanonicalWebUrl;
|
||||||
import com.google.gerrit.server.config.ConfigUtil;
|
import com.google.gerrit.server.config.ConfigUtil;
|
||||||
import com.google.gerrit.server.config.GerritServerConfig;
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
import com.google.gwtjsonrpc.common.AsyncCallback;
|
|
||||||
import com.google.gwtorm.client.KeyUtil;
|
import com.google.gwtorm.client.KeyUtil;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
@@ -73,7 +69,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class OpenIdServiceImpl implements OpenIdService {
|
class OpenIdServiceImpl {
|
||||||
private static final Logger log =
|
private static final Logger log =
|
||||||
LoggerFactory.getLogger(OpenIdServiceImpl.class);
|
LoggerFactory.getLogger(OpenIdServiceImpl.class);
|
||||||
|
|
||||||
@@ -149,19 +145,12 @@ class OpenIdServiceImpl implements OpenIdService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void discover(final String openidIdentifier, final SignInMode mode,
|
DiscoveryResult discover(final String openidIdentifier, final SignInMode mode,
|
||||||
final boolean remember, final String returnToken,
|
final boolean remember, final String returnToken) {
|
||||||
final AsyncCallback<DiscoveryResult> cb) {
|
|
||||||
if (!isAllowedOpenID(openidIdentifier)) {
|
|
||||||
cb.onSuccess(new DiscoveryResult(DiscoveryResult.Status.NOT_ALLOWED));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final State state;
|
final State state;
|
||||||
state = init(openidIdentifier, mode, remember, returnToken);
|
state = init(openidIdentifier, mode, remember, returnToken);
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
cb.onSuccess(new DiscoveryResult(DiscoveryResult.Status.NO_PROVIDER));
|
return new DiscoveryResult(DiscoveryResult.Status.NO_PROVIDER);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final AuthRequest aReq;
|
final AuthRequest aReq;
|
||||||
@@ -189,16 +178,15 @@ class OpenIdServiceImpl implements OpenIdService {
|
|||||||
}
|
}
|
||||||
} catch (MessageException e) {
|
} catch (MessageException e) {
|
||||||
log.error("Cannot create OpenID redirect for " + openidIdentifier, e);
|
log.error("Cannot create OpenID redirect for " + openidIdentifier, e);
|
||||||
cb.onSuccess(new DiscoveryResult(DiscoveryResult.Status.ERROR));
|
return new DiscoveryResult(DiscoveryResult.Status.ERROR);
|
||||||
return;
|
|
||||||
} catch (ConsumerException e) {
|
} catch (ConsumerException e) {
|
||||||
log.error("Cannot create OpenID redirect for " + openidIdentifier, e);
|
log.error("Cannot create OpenID redirect for " + openidIdentifier, e);
|
||||||
cb.onSuccess(new DiscoveryResult(DiscoveryResult.Status.ERROR));
|
return new DiscoveryResult(DiscoveryResult.Status.ERROR);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cb.onSuccess(new DiscoveryResult(aReq.getDestinationUrl(false), //
|
return new DiscoveryResult(
|
||||||
aReq.getParameterMap()));
|
aReq.getDestinationUrl(false),
|
||||||
|
aReq.getParameterMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean requestRegistration(final AuthRequest aReq) {
|
private boolean requestRegistration(final AuthRequest aReq) {
|
||||||
@@ -209,7 +197,6 @@ class OpenIdServiceImpl implements OpenIdService {
|
|||||||
// registration information, in case the identity is new to us.
|
// registration information, in case the identity is new to us.
|
||||||
//
|
//
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We might already have this account on file. Look for it.
|
// We might already have this account on file. Look for it.
|
||||||
@@ -222,7 +209,7 @@ class OpenIdServiceImpl implements OpenIdService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called by {@link OpenIdLoginServlet} doGet, doPost */
|
/** Called by {@link OpenIdLoginForm} doGet, doPost */
|
||||||
void doAuth(final HttpServletRequest req, final HttpServletResponse rsp)
|
void doAuth(final HttpServletRequest req, final HttpServletResponse rsp)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
if (OMODE_CANCEL.equals(req.getParameter(OPENID_MODE))) {
|
if (OMODE_CANCEL.equals(req.getParameter(OPENID_MODE))) {
|
||||||
@@ -436,7 +423,7 @@ class OpenIdServiceImpl implements OpenIdService {
|
|||||||
arsp = accountManager.authenticate(areq);
|
arsp = accountManager.authenticate(areq);
|
||||||
|
|
||||||
final Cookie lastId = new Cookie(OpenIdUrls.LASTID_COOKIE, "");
|
final Cookie lastId = new Cookie(OpenIdUrls.LASTID_COOKIE, "");
|
||||||
lastId.setPath(req.getContextPath() + "/");
|
lastId.setPath(req.getContextPath() + "/login/");
|
||||||
if (remember) {
|
if (remember) {
|
||||||
lastId.setValue(rediscoverIdentifier);
|
lastId.setValue(rediscoverIdentifier);
|
||||||
lastId.setMaxAge(LASTID_AGE);
|
lastId.setMaxAge(LASTID_AGE);
|
||||||
@@ -559,7 +546,7 @@ class OpenIdServiceImpl implements OpenIdService {
|
|||||||
return new State(discovered, retTo, contextUrl);
|
return new State(discovered, retTo, contextUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAllowedOpenID(final String id) {
|
boolean isAllowedOpenID(final String id) {
|
||||||
for (final OpenIdProviderPattern pattern : allowedOpenIDs) {
|
for (final OpenIdProviderPattern pattern : allowedOpenIDs) {
|
||||||
if (pattern.matches(id)) {
|
if (pattern.matches(id)) {
|
||||||
return true;
|
return true;
|
||||||
|
@@ -12,8 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package com.google.gerrit.common.auth;
|
package com.google.gerrit.httpd.auth.openid;
|
||||||
|
|
||||||
public enum SignInMode {
|
enum SignInMode {
|
||||||
SIGN_IN, LINK_IDENTIY, REGISTER;
|
SIGN_IN, LINK_IDENTIY, REGISTER;
|
||||||
}
|
}
|
@@ -0,0 +1,82 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Gerrit Code Review - Sign In</title>
|
||||||
|
<style>
|
||||||
|
#error_message {
|
||||||
|
padding: 5px;
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
width: 20em;
|
||||||
|
background-color: rgb(255, 255, 116);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
#cancel_link {
|
||||||
|
margin-left: 45px;
|
||||||
|
}
|
||||||
|
#logo_box {
|
||||||
|
padding-left: 160px;
|
||||||
|
}
|
||||||
|
#logo_img {
|
||||||
|
width: 200px;
|
||||||
|
height: 80px;
|
||||||
|
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABQCAYAAABcbTqwAAANbUlEQVR42uxdeXBV1Rm/URYpuNDRFjtuZcaOZTpd7D+O07pi65QqFMQEE7KzhF2kQEUr1gUkIBQiIKDUBYRgUBCCIHEBBLKR5GUlKwlZSAKJtvUPZzr8+r73u80dfHnv3iyveeF9v5lvQsi53zvv3O93z/mWc66hUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgUCoVCoVAoFAoFQaClAtgQDhSmw1AoFBbwxRZgzgggwgBcShCFwgM0FAGrHgaiDEqcWwoPKEEUChxIBmZ+H5gkxBBRgigUBqozgeX3AU8YQLRb4kWUIAqFgT1LgSlDSI54ESWIQmH5G7EGMFkIoQRRKC4B6l3A1EFArBJEoeiEIIXA1MFKEIVCCaJQKEEUCiWIQqEEUSiUIApFcOdBlCAKhS9cPOtyRJCLWs2rCAVcuHBhakNDA2pqalBWVYOqI3twccogIM4XQfizdv8mlFXXea6T60WPoVD0d5w7dw6VlZUoLCxEbm4ucnJykJWV5ZHMUwUoPrTTEUHKd69DZn5Rx7XZ2dkefS6Xy6O/qalJZxhF/0BjYyNKSko8BmwatBBDRP6vQ7LzC1HySaojglR8kIJsF3Wa0qFTyCKfIf9XVFSEs2fPdoksLS0tOe5ZSQmmCBza2tpGnz59mqTgE96LEJReIoi3eJGlrKwM58+fX274gcw+J0+elKVbjwmCtjogOxVIXw58uJSy9wXgxLtAQ7ESMBQhBiizhRimLSm8CcIlVncIYi8dfZL+WUSxZrm8vLyOGe7MmTPoNjFKPwXWjgeShrJk/09uecSUsQa3DCcOBJbfD2TvuuyJguNvA4nXAnNvAM7XAuVHgZnXUmZcDSQN85YZbll4G/Dyb4B3ZgJZO/v/OMkT2jRCRwbLJZHlgwhBSg/vckSQyg9fcxOkVD7La4ZyShTpryynSktLuezj9T0iCLbNYQRuglmyv2gksH4i8O4sYPtcYHMUsPSXQLzZJtItKROA9st3SYcvNgHhBpBwBdBaDc8DJNqgJIQBiVd6S3wYEGWO0TiDD5qFtwOHU/rfONXV1dHwnBHDy0eQ5Uxzc3Ob6Pq2OtdRmPfb3D34n78gxlxcXIxTp06RLM774UXonhAEKx8CHvfMENwNWbAPPttWnQRem0AjeMwtz7lJc6EWlyVBjmwRA+c2htYaoOwz3t/EAcCpD4DGEqC+0JKGYuBMLpC3Fzi4Clg3Hpj+PWCiQaKt/gPwTdtooz/gO09ff9LRTpY4sqTpUaKw6ONOr5folfTJ/Dyny68eEwSbnhBycNZIewaOr/v8dSBhEG/+S3eFDkFiDGDKQOBcORzpaCoDNkbIA4XjvOqh4B+r/Px8J0/rjjZVVVX4f5aaVFdXW58fQILgy7doAJPckrqg6zPP0TeA6DA+HdMWI5QIIve7a9uxnwciTZJ88GxwjlV7e/tIy/Dso0jl5eXoy1osiaZJXwJGkIU/5g17+e7uO/ZbJlPHtKuAxlIoQXwD68bJw4RO/oW64Bsrifb4NziSR9qJj9DXxYrinwSKIO6QLW9+TFiP6sOEFJg2hCR535pFRCfKj+DSZdkm4PVIYMUDQPKDwJo/AmlLgLo8Z31uqQIOrABSJgLJD4gervPTV3icaK/2/2pNhSsdKP7E6ldzBbB7CbB6DHWsHA1sjoX0LeAEqcuTKCBJcvDV4CKIZKrF+O3IIUbZ19W8sqSziW71nCDrHzOd7J/bt7fXRV/kmVEgaUr4XZ++Ax1kWfgTCRuTSDEGxynCjPQkDga2z/PbDzEozBgOjDfY7xiK+3Opd9YNwOcbqcMiKX2rGdeAUamNwJSh/Mwosw+RnutptItHARXHEBiCEG5SMsK19pEgIQgNTozH1rjECe/Lcvf6+npPX06cOCH96bLIdeK/OOrvkyNoaDvm95wgR9+kIU0ZALRUAs0V/K5L7wRy0oCYK2ioshzL2QWcLZCID/8m5DIjYlgzBp3qf3+RkIlGvPxe4NhWoDYPkALRY//gbBRu+lJ7n4dFkHR+7pzrgf3L2GbezUyAVp4Amko9swu2z5FQLsn75I1A21kEhCD8LvyuC24KHoLYPY3l71Jj1Zf7QVpbW1PFuCV0LLNAN0TIwUSiDXAmlwYRZfRKIsttrEIO6svdLWFfhkLn/wiYeyOQdL3fQ7vx2UYglgYqy59L/pa9E4g0jf8932TGjqekDclYkmHNXHEG+xLnlmX3AO318JEUZJuJdKIDRBAubSOpUx4mwZIE9OuQy89Q2jAF137e6IQrgZos9IrOWdfRwD9ZI0bIsYg2TNKkwcGTldcnXQ20WFFD97KNT9x1Y+11bHicy5fl99DAiw7JmLMP824EvmqAjRPN61+5D+bM2PsEcaVTR/wVXM71NYQAdkur2traUCIIw7O88b1WW4Uld9A/2PeSZNdlLLgsWvmgI/34pn2ke8YhGT56ASaRadwJgxwZJOqLgISBQFwYPMGD019wzCeZOm2AjBSSdMEt/HxZvvUyQYQUMnuLHvl+Rp+Ba3pb30Oy2KG25RZHNsMiSBF6ReezPzMJ8vKlBMlYB8c63p5Gh/nV39NAd86nQ736Yec6XrmXs4As2yTrH+t8pkTeXvosScMCR5DK4+xPTF+/CoN5BL/LKzPXEXoEyU0TQ6DfUJffK/1xO8Jcv3+cLASh7jjDY1RdcPZJqgU300DXjCHp9ix1ruO9uSys3D5PwsxiiCwg/Lf9xjSpckC0tL86UAShXxRrcJYr+7RvbUEcb39LLJlduH8ixAhSeVzWwDSGvL097Q9zC9MG05hObJMkmDjGlHrHMxQNNIYGKpEkLP2VLLHo7C8Z5ZY7/Iv4K3NvYLQqZRxQ6NYXS30OjTfgBJEqaEymDi5v+7akxDZ6JdGjECMIE2izruV6+6MXe04Q3nRWstaeEie7OwTh+jzezMrX5kqY2NTrUOIMVtTGDgY2hgcnQQ6s4LjPHg7xu4KdIAyLhhRBCKy4nw5x8gM9J8hbU4GJVmxf8gsWQQq7OYPUsVI4QnIbfwOaykSXvTQU8edXjTLW1BdMBEkZz3F/8S4EQ/Zcl1g+4PYVaHwJA+39EPvoEwmyNQFmZbMYEY0t/6Ou+iBWFGnV7+i071/Wnf4xURgdPATBV03ArOGcQdKeDv4ciPytoqIiNAkifsJMLrOk5L27eiR8igiWfUhY9ZKxCKeD3fUoFqNW2DabUay1j6JLIeyUOHgSfyWHg2oGcZOCYxUvUbXsvrcDOfQgMzPTX5JQChNDkCCEO2NMI54cBmTt6PoNr84Cpg/j7LF+ArzGIpL1Wd3Og2Sn0kCnDwXO1zjT8+dbgDEGNyxVHg8WgjBBmHgVx2pjuHVtf0gUCpFCjyAEnv81b1rSdUC+44gWy1WeupUz0LwRUk3rTZAYJumk9sn+6bqYumZ8J5O+8Fb2b/Nkex2SxY8wdXzd3MYtsgEiSKPjuj2W0iSZs/X8mzhWQbRz0K7UhMnC0CQIK28X3MYnd8IAIO0vQFs9/N/wDfIGX5NYw4HSDHiNxZRBMh40iOgwSF2T330X8QNpQCw27IBU6CLCrLpNXehbR8E+YOowJgl3LQIN/uOAEUQeEH511eQAh1YDL97Nvj8m5LiN5SXBdgKigzJ3VvKGHkGsPMay34qB8kbO+yGwNRE4vI57rwv2S2aahzcsvl0Mlu2eHgVUfolOxyJxgBgafYHZ11P32rHAyW1ShetVzctl2kR02r83Yq0981K5e/wdqyJYiiPfjJPEG8mx8iHvat6koTBs4d0eR7cCk5hQJUE+tUr1F41k3mXJTztEfpcSf8y8RkLe/E7jDV7z90eB5nIYwQhxxB2UuzOrHsKnu8vJG1h0O594Yz03lwbyhEmIR82S8zk/AHYtBv7JAyt8EIRyvpoHGTx3p+ig0Mioa5wY4BDODn4g+RruB/GhIzYM2BzNQxGsGcEqHbGFd3scE4KYM4Z1aIMI20V1KrzP04aQNG9NB0qYMQ9qFBQUONowJZGvUH/9AfL3AbufATZEcMfdygf59N8xnzPC1+dgMxad5kGQlcqzopJHczfg+nAJ4TquB0NrFXBoDfB6FGeSZFPHh38FqjNtdhR6w6492us5exYd5O/uchUPiVxuKfQhBelA+TEuU/sX6LA7cdolfyL71/X9IDZwRhA9ibE/nchuOuaODoaTDUhKECVISJKEyy37Pd4S4ZLdekoQJUjogJW+QgBHx4ya7STrzuLGHr1hKl0JougHsE4PEXFCFLblsUDizEuCseMFOP+pzfdPkBgzGuQKAYLU5UskjFKXrwTp7687kHN2vY4htSeL9b4QVzHKMt73fXh1FAki8XzJ8BqXOSSCIxW+Iu5/K0H6P3g2rnl2VteP/Mxzdfb6A6vU4tlfAK59aiiK/g85rV2y6vQ9rFmlKy/QEeE5UVdJQk2Jobg8IdErc0+J17s8fBIkyiTHK/fLoQFKDkUogCekiGMuuxStdxaSNJmyxDq4AxeFHLNHABmvKTEUuhST87Qk9FtUVoHTGWm4uCVWjt1UcigUCoVCoVAoFAqFQqFQKBQKhUKhUCgUCsV/24MDEgAAAABB/1+3I1ABAGAilVZ2IKvvzEMAAAAASUVORK5CYII=') no-repeat 0px 0px;
|
||||||
|
}
|
||||||
|
#f_openid {
|
||||||
|
padding-left: 25px;
|
||||||
|
border: 1px solid #999;
|
||||||
|
background: #fff url('data:image/gif;base64,R0lGODlhEAAQAMQAAO3t7eHh4srKyvz8/P5pDP9rENLS0v/28P/17tXV1dHEvPDw8M3Nzfn5+d3d3f5jA97Syvnv6MfLzcfHx/1mCPx4Kc/S1Pf189C+tP+xgv/k1N3OxfHy9NLV1/39/f///yH5BAAAAAAALAAAAAAQABAAAAVq4CeOZGme6KhlSDoexdO6H0IUR+otwUYRkMDCUwIYJhLFTyGZJACAwQcgEAQ4kVuEE2AIGAOPQQAQwXCfS8KQGAwMjIYIUSi03B7iJ+AcnmclHg4TAh0QDzIpCw4WGBUZeikDFzk0lpcjIQA7') no-repeat scroll 5px 50%
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Sign In to Gerrit Code Review at <span id="hostName">example.com</span></h1>
|
||||||
|
<form method="POST" action="#" id="login_form">
|
||||||
|
<input type="hidden" name="link" id="f_link" value="1" />
|
||||||
|
<div id="logo_box"><div id="logo_img"></div></div>
|
||||||
|
<div id="error_message">Invalid OpenID identifier.</div>
|
||||||
|
<div>
|
||||||
|
<input type="text"
|
||||||
|
name="id"
|
||||||
|
id="f_openid"
|
||||||
|
size="60"
|
||||||
|
tabindex="1" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input name="rememberme" id="f_remember"
|
||||||
|
type="checkbox"
|
||||||
|
value="1"
|
||||||
|
tabindex="2" />
|
||||||
|
<label for="f_remember">Remember me</label>
|
||||||
|
</div>
|
||||||
|
<div style="margin-bottom: 25px;">
|
||||||
|
<input type="submit" value="Sign In" id="f_submit" tabindex="3" />
|
||||||
|
<a href="../" id="cancel_link">Cancel</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="provider_google">
|
||||||
|
<img height="16" width="16" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABsUlEQVR42rWSy0sbYRRH88fYhW5KQXThIkUQN6ISJFBBW6FFBN2UqlC78LVKFlHIoqWGakF8gUZ8gajVzKSKZpQmAWtK0pBmhkxmSgPuiuaYmRKhSEwU/ODyDZfzO8ydOxbLQx1NB0H4y8FBlmMpy9LyOavrKUoKB4IXvBsIIopRPJ441dY/2Fr8fAtFSxO0dkRy4eA1PDp+TkVlmGhMKS5IJOFpbYgj6fQalhV4UhVm0esvLojELimv1JiYOPwPflS2gM93WNoIXZ1nPC4/IRDQzYDTqTA0PM2dtuCZ8vGmV6SvP5srL/da5c+4TnNLFlvTMYmEVrpkazuM2x1naOQ7Dc1fqLOmaayXkaSz4hLHewm7fY+Z2R0iP+JmYGpym/q6DDb76u0CwR+g9+0FHz4u3wAdLh9VNWu5UX4VlqysfaXRDoODNz+aw7nDs9ZPpNPpwgJV1WhvF6m1/qb79T6fpwXm5kVGRnd5/mIdQSzwH2iahq7/27nxiq5xLy9fbdDWsUtPzyausRVC4VMMzmAMNv9syTdkWTZLVVUymYx5J5NJs5dKpVAUxaw8Z/SM7BV+fz9Uc4yYRAAAAABJRU5ErkJggg==" />
|
||||||
|
<a href="?id=https://www.google.com/accounts/o8/id" id="id_google">Sign in with a Google Account</a>
|
||||||
|
</div>
|
||||||
|
<div id="provider_yahoo">
|
||||||
|
<img height="16" width="16" src="data:image/gif;base64,R0lGODlhEAAQAPECAAAAAP8AAP///8zMzCH5BAEAAAMALAAAAAAQABAAAAIqnI+py30BY3AgAjCkfJDjiIAQlgUkNxqWkqrm0honKk7KhZOzw/f+fygAADs=" />
|
||||||
|
<a href="?id=https://me.yahoo.com" id="id_yahoo">Sign in with a Yahoo! ID</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 25px;">
|
||||||
|
<h2>What is OpenID?</h2>
|
||||||
|
<p>OpenID provides secure single-sign-on, without revealing your passwords to this website.</p>
|
||||||
|
<p>There are many OpenID providers available. You may already be member of one!</p>
|
||||||
|
<p><a href="http://openid.net/get/" target="_blank">Get OpenID</a></p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script type="text/javascript" language="javascript">
|
||||||
|
var f_openid = document.getElementById('f_openid');
|
||||||
|
var f_submit = document.getElementById('f_submit');
|
||||||
|
if (f_openid.value == '')
|
||||||
|
f_openid.focus();
|
||||||
|
else
|
||||||
|
f_submit.focus();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -0,0 +1,16 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Gerrit Code Review - Redirecting ...</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>Redirecting ...</div>
|
||||||
|
<form method="POST" action="#" id="redirect_form">
|
||||||
|
<input type="submit" value="Continue" />
|
||||||
|
</form>
|
||||||
|
<script type="text/javascript" language="javascript">
|
||||||
|
var r = document.getElementById('redirect_form');
|
||||||
|
r.style.display = 'none';
|
||||||
|
r.submit();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package com.google.gerrit.common.auth.openid;
|
package com.google.gerrit.server.auth.openid;
|
||||||
|
|
||||||
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
||||||
|
|
@@ -14,9 +14,9 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.config;
|
package com.google.gerrit.server.config;
|
||||||
|
|
||||||
import com.google.gerrit.common.auth.openid.OpenIdProviderPattern;
|
|
||||||
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
import com.google.gerrit.reviewdb.client.AccountExternalId;
|
||||||
import com.google.gerrit.reviewdb.client.AuthType;
|
import com.google.gerrit.reviewdb.client.AuthType;
|
||||||
|
import com.google.gerrit.server.auth.openid.OpenIdProviderPattern;
|
||||||
import com.google.gwtjsonrpc.server.SignedToken;
|
import com.google.gwtjsonrpc.server.SignedToken;
|
||||||
import com.google.gwtjsonrpc.server.XsrfException;
|
import com.google.gwtjsonrpc.server.XsrfException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
Reference in New Issue
Block a user