Add a password field to the account identities
Some types of identities, e.g. "username:", now support having an optional password generated alongside of them. This can be used in the future to authenticate the user. Currently we intend to use this only for authentication over HTTP, so we generate the password for the user as they would need to store it into a local ~/.netrc. We don't want them to reuse an existing password that might be vulnerable. Change-Id: I047a97f00249c81638625d7654087ea71f8f386a Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -120,6 +120,7 @@ public interface GerritCss extends CssResource {
|
||||
String needsReview();
|
||||
String negscore();
|
||||
String noLineLineNumber();
|
||||
String noborder();
|
||||
String patchBrowserPopup();
|
||||
String patchBrowserPopupBody();
|
||||
String patchComments();
|
||||
@@ -160,6 +161,7 @@ public interface GerritCss extends CssResource {
|
||||
String sshKeyPanelEncodedKey();
|
||||
String sshKeyPanelInvalid();
|
||||
String sshPanelUsername();
|
||||
String sshPanelPassword();
|
||||
String topmenu();
|
||||
String topmenuMenuLeft();
|
||||
String topmenuMenuRight();
|
||||
|
||||
@@ -46,7 +46,9 @@ public interface AccountConstants extends Constants {
|
||||
String buttonAddSshKey();
|
||||
|
||||
String userName();
|
||||
String password();
|
||||
String buttonChangeUserName();
|
||||
String buttonGeneratePassword();
|
||||
String invalidUserName();
|
||||
|
||||
String sshKeyInvalid();
|
||||
|
||||
@@ -26,7 +26,9 @@ buttonOpenSshKey = Open Key ...
|
||||
buttonAddSshKey = Add
|
||||
|
||||
userName = Username
|
||||
password = Password
|
||||
buttonChangeUserName = Change Username
|
||||
buttonGeneratePassword = Regenerate
|
||||
invalidUserName = Username must contain only letters, numbers, _, - or .
|
||||
|
||||
sshKeyInvalid = Invalid Key
|
||||
|
||||
@@ -45,6 +45,7 @@ class ExternalIdPanel extends Composite {
|
||||
|
||||
ExternalIdPanel() {
|
||||
final FlowPanel body = new FlowPanel();
|
||||
body.add(new UsernamePanel());
|
||||
|
||||
identites = new IdTable();
|
||||
body.add(identites);
|
||||
@@ -80,10 +81,7 @@ class ExternalIdPanel extends Composite {
|
||||
@Override
|
||||
protected void onLoad() {
|
||||
super.onLoad();
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
Util.ACCOUNT_SEC
|
||||
.myExternalIds(new GerritCallback<List<AccountExternalId>>() {
|
||||
public void onSuccess(final List<AccountExternalId> result) {
|
||||
|
||||
@@ -14,48 +14,34 @@
|
||||
|
||||
package com.google.gerrit.client.account;
|
||||
|
||||
import static com.google.gerrit.reviewdb.AccountExternalId.SCHEME_USERNAME;
|
||||
|
||||
import com.google.gerrit.client.ErrorDialog;
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.ui.FancyFlexTable;
|
||||
import com.google.gerrit.client.ui.SmallHeading;
|
||||
import com.google.gerrit.client.ui.TextSaveButtonListener;
|
||||
import com.google.gerrit.common.data.SshHostKey;
|
||||
import com.google.gerrit.common.errors.InvalidSshKeyException;
|
||||
import com.google.gerrit.common.errors.InvalidUserNameException;
|
||||
import com.google.gerrit.reviewdb.Account;
|
||||
import com.google.gerrit.reviewdb.AccountExternalId;
|
||||
import com.google.gerrit.reviewdb.AccountSshKey;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
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.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.i18n.client.LocaleInfo;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
import com.google.gwt.user.client.Timer;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.HTML;
|
||||
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Panel;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
|
||||
import com.google.gwtexpui.globalkey.client.NpTextArea;
|
||||
import com.google.gwtexpui.globalkey.client.NpTextBox;
|
||||
import com.google.gwtjsonrpc.client.RemoteJsonException;
|
||||
import com.google.gwtjsonrpc.client.VoidResult;
|
||||
|
||||
@@ -69,11 +55,6 @@ class SshPanel extends Composite {
|
||||
private static String appletErrorInvalidKey;
|
||||
private static String appletErrorSecurity;
|
||||
|
||||
private int labelIdx, fieldIdx;
|
||||
|
||||
private NpTextBox userNameTxt;
|
||||
private Button changeUserName;
|
||||
|
||||
private SshKeyTable keys;
|
||||
|
||||
private Button showAddKeyBlock;
|
||||
@@ -89,51 +70,8 @@ class SshPanel extends Composite {
|
||||
private Panel serverKeys;
|
||||
|
||||
SshPanel() {
|
||||
if (LocaleInfo.getCurrentLocale().isRTL()) {
|
||||
labelIdx = 1;
|
||||
fieldIdx = 0;
|
||||
} else {
|
||||
labelIdx = 0;
|
||||
fieldIdx = 1;
|
||||
}
|
||||
|
||||
final FlowPanel body = new FlowPanel();
|
||||
|
||||
userNameTxt = new NpTextBox();
|
||||
userNameTxt.addKeyPressHandler(new UserNameValidator());
|
||||
userNameTxt.addStyleName(Gerrit.RESOURCES.css().sshPanelUsername());
|
||||
userNameTxt.setVisibleLength(16);
|
||||
userNameTxt.setReadOnly(!canEditUserName());
|
||||
|
||||
changeUserName = new Button(Util.C.buttonChangeUserName());
|
||||
changeUserName.setVisible(canEditUserName());
|
||||
changeUserName.setEnabled(false);
|
||||
changeUserName.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(final ClickEvent event) {
|
||||
doChangeUserName();
|
||||
}
|
||||
});
|
||||
new TextSaveButtonListener(userNameTxt, changeUserName);
|
||||
|
||||
final Grid userInfo = new Grid(1, 2);
|
||||
userInfo.setStyleName(Gerrit.RESOURCES.css().infoBlock());
|
||||
userInfo.addStyleName(Gerrit.RESOURCES.css().accountInfoBlock());
|
||||
body.add(userInfo);
|
||||
|
||||
final FlowPanel userNameRow = new FlowPanel();
|
||||
userNameRow.add(userNameTxt);
|
||||
userNameRow.add(changeUserName);
|
||||
|
||||
row(userInfo, 0, Util.C.userName(), userNameRow);
|
||||
userInfo.getCellFormatter().addStyleName(0, 0,
|
||||
Gerrit.RESOURCES.css().topmost());
|
||||
userInfo.getCellFormatter().addStyleName(0, 0,
|
||||
Gerrit.RESOURCES.css().topmost());
|
||||
userInfo.getCellFormatter().addStyleName(0, 1,
|
||||
Gerrit.RESOURCES.css().topmost());
|
||||
userInfo.getCellFormatter().addStyleName(0, 0,
|
||||
Gerrit.RESOURCES.css().bottomheader());
|
||||
body.add(new UsernamePanel());
|
||||
|
||||
showAddKeyBlock = new Button(Util.C.buttonShowAddSshKey());
|
||||
showAddKeyBlock.addClickHandler(new ClickHandler() {
|
||||
@@ -224,68 +162,12 @@ class SshPanel extends Composite {
|
||||
initWidget(body);
|
||||
}
|
||||
|
||||
private boolean canEditUserName() {
|
||||
return Gerrit.getConfig().canEdit(Account.FieldName.USER_NAME);
|
||||
}
|
||||
|
||||
protected void row(final Grid info, final int row, final String name,
|
||||
final Widget field) {
|
||||
info.setText(row, labelIdx, name);
|
||||
info.setWidget(row, fieldIdx, field);
|
||||
info.getCellFormatter().addStyleName(row, 0,
|
||||
Gerrit.RESOURCES.css().header());
|
||||
}
|
||||
|
||||
void setKeyTableVisible(final boolean on) {
|
||||
keys.setVisible(on);
|
||||
deleteKey.setVisible(on);
|
||||
closeAddKeyBlock.setVisible(on);
|
||||
}
|
||||
|
||||
void doChangeUserName() {
|
||||
if (!canEditUserName()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String newName = userNameTxt.getText();
|
||||
if ("".equals(newName)) {
|
||||
newName = null;
|
||||
}
|
||||
if (newName != null && !newName.matches(Account.USER_NAME_PATTERN)) {
|
||||
invalidUserName();
|
||||
return;
|
||||
}
|
||||
|
||||
userNameTxt.setEnabled(false);
|
||||
changeUserName.setEnabled(false);
|
||||
|
||||
final String newUserName = newName;
|
||||
Util.ACCOUNT_SEC.changeSshUserName(newUserName,
|
||||
new GerritCallback<VoidResult>() {
|
||||
public void onSuccess(final VoidResult result) {
|
||||
Gerrit.getUserAccount().setUserName(newUserName);
|
||||
userNameTxt.setEnabled(true);
|
||||
changeUserName.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable caught) {
|
||||
userNameTxt.setEnabled(true);
|
||||
changeUserName.setEnabled(true);
|
||||
if (InvalidUserNameException.MESSAGE.equals(caught.getMessage())) {
|
||||
invalidUserName();
|
||||
} else {
|
||||
super.onFailure(caught);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void invalidUserName() {
|
||||
userNameTxt.setFocus(true);
|
||||
new ErrorDialog(Util.C.invalidUserName()).center();
|
||||
}
|
||||
|
||||
void doBrowse() {
|
||||
browse.setEnabled(false);
|
||||
|
||||
@@ -431,23 +313,6 @@ class SshPanel extends Composite {
|
||||
protected void onLoad() {
|
||||
super.onLoad();
|
||||
|
||||
userNameTxt.setEnabled(false);
|
||||
Util.ACCOUNT_SEC
|
||||
.myExternalIds(new GerritCallback<List<AccountExternalId>>() {
|
||||
public void onSuccess(final List<AccountExternalId> result) {
|
||||
String userName = null;
|
||||
for (AccountExternalId i : result) {
|
||||
if (i.isScheme(SCHEME_USERNAME)) {
|
||||
userName = i.getSchemeRest();
|
||||
break;
|
||||
}
|
||||
}
|
||||
Gerrit.getUserAccount().setUserName(userName);
|
||||
userNameTxt.setText(userName);
|
||||
userNameTxt.setEnabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
Util.ACCOUNT_SEC.mySshKeys(new GerritCallback<List<AccountSshKey>>() {
|
||||
public void onSuccess(final List<AccountSshKey> result) {
|
||||
keys.display(result);
|
||||
@@ -482,53 +347,6 @@ class SshPanel extends Composite {
|
||||
addKeyBlock.setVisible(show);
|
||||
}
|
||||
|
||||
private final class UserNameValidator implements KeyPressHandler {
|
||||
@Override
|
||||
public void onKeyPress(final KeyPressEvent event) {
|
||||
final char code = event.getCharCode();
|
||||
switch (code) {
|
||||
case KeyCodes.KEY_ALT:
|
||||
case KeyCodes.KEY_BACKSPACE:
|
||||
case KeyCodes.KEY_CTRL:
|
||||
case KeyCodes.KEY_DELETE:
|
||||
case KeyCodes.KEY_DOWN:
|
||||
case KeyCodes.KEY_END:
|
||||
case KeyCodes.KEY_ENTER:
|
||||
case KeyCodes.KEY_ESCAPE:
|
||||
case KeyCodes.KEY_HOME:
|
||||
case KeyCodes.KEY_LEFT:
|
||||
case KeyCodes.KEY_PAGEDOWN:
|
||||
case KeyCodes.KEY_PAGEUP:
|
||||
case KeyCodes.KEY_RIGHT:
|
||||
case KeyCodes.KEY_SHIFT:
|
||||
case KeyCodes.KEY_TAB:
|
||||
case KeyCodes.KEY_UP:
|
||||
// Allow these, even if one of their assigned codes is
|
||||
// identical to an ASCII character we do not want to
|
||||
// allow in the box.
|
||||
//
|
||||
// We still want to let the user move around the input box
|
||||
// with their arrow keys, or to move between fields using tab.
|
||||
// Invalid characters introduced will be caught through the
|
||||
// server's own validation of the input data.
|
||||
//
|
||||
break;
|
||||
|
||||
default:
|
||||
final TextBox box = (TextBox) event.getSource();
|
||||
final String re;
|
||||
if (box.getCursorPos() == 0)
|
||||
re = Account.USER_NAME_PATTERN_FIRST;
|
||||
else
|
||||
re = Account.USER_NAME_PATTERN_REST;
|
||||
if (!String.valueOf(code).matches("^" + re + "$")) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SshKeyTable extends FancyFlexTable<AccountSshKey> {
|
||||
private ValueChangeHandler<Boolean> updateDeleteHandler;
|
||||
|
||||
|
||||
@@ -0,0 +1,289 @@
|
||||
// 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.account;
|
||||
|
||||
import static com.google.gerrit.reviewdb.AccountExternalId.SCHEME_USERNAME;
|
||||
|
||||
import com.google.gerrit.client.ErrorDialog;
|
||||
import com.google.gerrit.client.Gerrit;
|
||||
import com.google.gerrit.client.rpc.GerritCallback;
|
||||
import com.google.gerrit.client.ui.TextSaveButtonListener;
|
||||
import com.google.gerrit.common.errors.InvalidUserNameException;
|
||||
import com.google.gerrit.reviewdb.Account;
|
||||
import com.google.gerrit.reviewdb.AccountExternalId;
|
||||
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.i18n.client.LocaleInfo;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
|
||||
import com.google.gwtexpui.clippy.client.CopyableLabel;
|
||||
import com.google.gwtexpui.globalkey.client.NpTextBox;
|
||||
import com.google.gwtjsonrpc.client.VoidResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UsernamePanel extends Composite {
|
||||
private NpTextBox userNameTxt;
|
||||
private Button changeUserName;
|
||||
|
||||
private CopyableLabel password;
|
||||
private Button generatePassword;
|
||||
|
||||
private AccountExternalId.Key idKey;
|
||||
|
||||
UsernamePanel() {
|
||||
final FlowPanel body = new FlowPanel();
|
||||
initWidget(body);
|
||||
|
||||
userNameTxt = new NpTextBox();
|
||||
userNameTxt.addKeyPressHandler(new UserNameValidator());
|
||||
userNameTxt.addStyleName(Gerrit.RESOURCES.css().sshPanelUsername());
|
||||
userNameTxt.setVisibleLength(16);
|
||||
userNameTxt.setReadOnly(!canEditUserName());
|
||||
|
||||
changeUserName = new Button(Util.C.buttonChangeUserName());
|
||||
changeUserName.setVisible(canEditUserName());
|
||||
changeUserName.setEnabled(false);
|
||||
changeUserName.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(final ClickEvent event) {
|
||||
doChangeUserName();
|
||||
}
|
||||
});
|
||||
new TextSaveButtonListener(userNameTxt, changeUserName);
|
||||
|
||||
password = new CopyableLabel("");
|
||||
password.addStyleName(Gerrit.RESOURCES.css().sshPanelPassword());
|
||||
password.setVisible(false);
|
||||
|
||||
generatePassword = new Button(Util.C.buttonGeneratePassword());
|
||||
generatePassword.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
doGeneratePassword();
|
||||
}
|
||||
});
|
||||
|
||||
final Grid userInfo = new Grid(2, 3);
|
||||
final CellFormatter fmt = userInfo.getCellFormatter();
|
||||
userInfo.setStyleName(Gerrit.RESOURCES.css().infoBlock());
|
||||
userInfo.addStyleName(Gerrit.RESOURCES.css().accountInfoBlock());
|
||||
body.add(userInfo);
|
||||
|
||||
row(userInfo, 0, Util.C.userName(), userNameTxt, changeUserName);
|
||||
row(userInfo, 1, Util.C.password(), password, generatePassword);
|
||||
|
||||
fmt.addStyleName(0, 0, Gerrit.RESOURCES.css().topmost());
|
||||
fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().topmost());
|
||||
fmt.addStyleName(0, 2, Gerrit.RESOURCES.css().topmost());
|
||||
|
||||
fmt.addStyleName(1, 0, Gerrit.RESOURCES.css().bottomheader());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLoad() {
|
||||
super.onLoad();
|
||||
|
||||
enableUI(false);
|
||||
Util.ACCOUNT_SEC
|
||||
.myExternalIds(new GerritCallback<List<AccountExternalId>>() {
|
||||
public void onSuccess(final List<AccountExternalId> result) {
|
||||
AccountExternalId id = null;
|
||||
for (AccountExternalId i : result) {
|
||||
if (i.isScheme(SCHEME_USERNAME)) {
|
||||
id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
display(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void display(AccountExternalId id) {
|
||||
String user, pass;
|
||||
if (id != null) {
|
||||
idKey = id.getKey();
|
||||
user = id.getSchemeRest();
|
||||
pass = id.getPassword();
|
||||
} else {
|
||||
idKey = null;
|
||||
user = null;
|
||||
pass = null;
|
||||
}
|
||||
|
||||
Gerrit.getUserAccount().setUserName(user);
|
||||
userNameTxt.setText(user);
|
||||
userNameTxt.setEnabled(true);
|
||||
generatePassword.setEnabled(idKey != null);
|
||||
|
||||
if (pass != null) {
|
||||
password.setText(pass);
|
||||
password.setVisible(true);
|
||||
} else {
|
||||
password.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void row(final Grid info, final int row, final String name,
|
||||
final Widget field1, final Widget field2) {
|
||||
final CellFormatter fmt = info.getCellFormatter();
|
||||
if (LocaleInfo.getCurrentLocale().isRTL()) {
|
||||
info.setText(row, 2, name);
|
||||
info.setWidget(row, 1, field1);
|
||||
info.setWidget(row, 0, field2);
|
||||
fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().noborder());
|
||||
fmt.addStyleName(row, 2, Gerrit.RESOURCES.css().header());
|
||||
} else {
|
||||
info.setText(row, 0, name);
|
||||
info.setWidget(row, 1, field1);
|
||||
info.setWidget(row, 2, field2);
|
||||
fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().noborder());
|
||||
fmt.addStyleName(row, 0, Gerrit.RESOURCES.css().header());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canEditUserName() {
|
||||
return Gerrit.getConfig().canEdit(Account.FieldName.USER_NAME);
|
||||
}
|
||||
|
||||
void doChangeUserName() {
|
||||
if (!canEditUserName()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String newName = userNameTxt.getText();
|
||||
if ("".equals(newName)) {
|
||||
newName = null;
|
||||
}
|
||||
if (newName != null && !newName.matches(Account.USER_NAME_PATTERN)) {
|
||||
invalidUserName();
|
||||
return;
|
||||
}
|
||||
|
||||
enableUI(false);
|
||||
|
||||
final String newUserName = newName;
|
||||
Util.ACCOUNT_SEC.changeUserName(newUserName,
|
||||
new GerritCallback<VoidResult>() {
|
||||
public void onSuccess(final VoidResult result) {
|
||||
Gerrit.getUserAccount().setUserName(newUserName);
|
||||
enableUI(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable caught) {
|
||||
enableUI(true);
|
||||
if (InvalidUserNameException.MESSAGE.equals(caught.getMessage())) {
|
||||
invalidUserName();
|
||||
} else {
|
||||
super.onFailure(caught);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void invalidUserName() {
|
||||
userNameTxt.setFocus(true);
|
||||
new ErrorDialog(Util.C.invalidUserName()).center();
|
||||
}
|
||||
|
||||
void doGeneratePassword() {
|
||||
if (idKey == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
enableUI(false);
|
||||
|
||||
Util.ACCOUNT_SEC.generatePassword(idKey,
|
||||
new GerritCallback<AccountExternalId>() {
|
||||
public void onSuccess(final AccountExternalId result) {
|
||||
enableUI(true);
|
||||
display(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(final Throwable caught) {
|
||||
enableUI(true);
|
||||
if (InvalidUserNameException.MESSAGE.equals(caught.getMessage())) {
|
||||
invalidUserName();
|
||||
} else {
|
||||
super.onFailure(caught);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void enableUI(final boolean on) {
|
||||
userNameTxt.setEnabled(on);
|
||||
changeUserName.setEnabled(on);
|
||||
generatePassword.setEnabled(on && idKey != null);
|
||||
}
|
||||
|
||||
private final class UserNameValidator implements KeyPressHandler {
|
||||
@Override
|
||||
public void onKeyPress(final KeyPressEvent event) {
|
||||
final char code = event.getCharCode();
|
||||
switch (code) {
|
||||
case KeyCodes.KEY_ALT:
|
||||
case KeyCodes.KEY_BACKSPACE:
|
||||
case KeyCodes.KEY_CTRL:
|
||||
case KeyCodes.KEY_DELETE:
|
||||
case KeyCodes.KEY_DOWN:
|
||||
case KeyCodes.KEY_END:
|
||||
case KeyCodes.KEY_ENTER:
|
||||
case KeyCodes.KEY_ESCAPE:
|
||||
case KeyCodes.KEY_HOME:
|
||||
case KeyCodes.KEY_LEFT:
|
||||
case KeyCodes.KEY_PAGEDOWN:
|
||||
case KeyCodes.KEY_PAGEUP:
|
||||
case KeyCodes.KEY_RIGHT:
|
||||
case KeyCodes.KEY_SHIFT:
|
||||
case KeyCodes.KEY_TAB:
|
||||
case KeyCodes.KEY_UP:
|
||||
// Allow these, even if one of their assigned codes is
|
||||
// identical to an ASCII character we do not want to
|
||||
// allow in the box.
|
||||
//
|
||||
// We still want to let the user move around the input box
|
||||
// with their arrow keys, or to move between fields using tab.
|
||||
// Invalid characters introduced will be caught through the
|
||||
// server's own validation of the input data.
|
||||
//
|
||||
break;
|
||||
|
||||
default:
|
||||
final TextBox box = (TextBox) event.getSource();
|
||||
final String re;
|
||||
if (box.getCursorPos() == 0)
|
||||
re = Account.USER_NAME_PATTERN_FIRST;
|
||||
else
|
||||
re = Account.USER_NAME_PATTERN_REST;
|
||||
if (!String.valueOf(code).matches("^" + re + "$")) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -754,6 +754,10 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.infoBlock td.noborder {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.infoBlock td.bottomheader {
|
||||
border-bottom: 1px solid trim-color;
|
||||
}
|
||||
@@ -861,7 +865,10 @@
|
||||
.sshPanelUsername {
|
||||
font-family: mono-font;
|
||||
font-size: small;
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
.sshPanelPassword {
|
||||
font-family: mono-font;
|
||||
font-size: small;
|
||||
}
|
||||
.sshKeyPanelEncodedKey {
|
||||
white-space: nowrap;
|
||||
|
||||
Reference in New Issue
Block a user