/* Copyright 2008-2013 Josh Drummond This file is part of WebPasswordSafe. WebPasswordSafe is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. WebPasswordSafe is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with WebPasswordSafe; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package net.webpasswordsafe.client.ui; import net.webpasswordsafe.client.ClientSessionUtil; import net.webpasswordsafe.client.MainWindow; import net.webpasswordsafe.client.WebPasswordSafe; import net.webpasswordsafe.client.i18n.TextMessages; import net.webpasswordsafe.client.remote.LoginService; import net.webpasswordsafe.common.util.Utils; import net.webpasswordsafe.common.util.Constants.AuthenticationStatus; import com.extjs.gxt.ui.client.Style.HorizontalAlignment; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.KeyListener; import com.extjs.gxt.ui.client.event.ButtonEvent; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.util.Format; import com.extjs.gxt.ui.client.widget.Info; import com.extjs.gxt.ui.client.widget.MessageBox; import com.extjs.gxt.ui.client.widget.Window; import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.widget.form.FormPanel; import com.extjs.gxt.ui.client.widget.form.TextField; import com.extjs.gxt.ui.client.widget.layout.FormData; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.user.client.rpc.AsyncCallback; /** * * @author Josh Drummond * */ public class LoginDialog extends Window implements LoginWindow { private TextField<String> usernameTextBox; private TextField<String> passwordTextBox; private Button enterButton; private MainWindow main; private boolean isSubmitting, isTwoStep; private String[] credentials; private final static TextMessages textMessages = GWT.create(TextMessages.class); public LoginDialog(MainWindow main) { this.main = main; this.setHeading(textMessages.login()); this.setModal(true); this.setClosable(false); this.setOnEsc(false); this.setResizable(false); this.isSubmitting = false; this.isTwoStep = false; this.credentials = new String[2]; FormPanel form = new FormPanel(); form.setHeaderVisible(false); form.setFrame(true); usernameTextBox = new TextField<String>(); usernameTextBox.setFieldLabel(textMessages.username()); usernameTextBox.addKeyListener(new KeyListener() { @Override public void componentKeyPress(ComponentEvent event) { if (event.getKeyCode() == KeyCodes.KEY_ENTER) { passwordTextBox.focus(); } } }); form.add(usernameTextBox, new FormData("-20")); passwordTextBox = new TextField<String>(); passwordTextBox.setFieldLabel(textMessages.password()); passwordTextBox.setPassword(true); passwordTextBox.addKeyListener(new KeyListener() { @Override public void componentKeyPress(ComponentEvent event) { if (event.getKeyCode() == KeyCodes.KEY_ENTER) { doSubmit(); } } }); form.add(passwordTextBox, new FormData("-20")); enterButton = new Button(textMessages.submit(), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { doSubmit(); } }); form.setButtonAlign(HorizontalAlignment.CENTER); form.addButton(enterButton); this.add(form); } @Override public void show() { super.show(); setFocusWidget(usernameTextBox); } private void setSubmitting(boolean isSubmit) { usernameTextBox.setEnabled(!isSubmit); passwordTextBox.setEnabled(!isSubmit); enterButton.setEnabled(!isSubmit); isSubmitting = isSubmit; } private boolean validateFields() { if (Utils.safeString(usernameTextBox.getValue()).equals("")) { MessageBox.alert(textMessages.error(), textMessages.mustEnterUsername(), null); return false; } if (Utils.safeString(passwordTextBox.getValue()).equals("")) { MessageBox.alert(textMessages.error(), isTwoStep ? textMessages.mustEnterTwoStepVerificationCode() : textMessages.mustEnterPassword(), null); return false; } if (isTwoStep && (Utils.safeInt(passwordTextBox.getValue()) == -1)) { MessageBox.alert(textMessages.error(), textMessages.mustEnterTwoStepVerificationCode(), null); return false; } return true; } private synchronized void doSubmit() { if (!isSubmitting) { if (validateFields()) { setSubmitting(true); if (isTwoStep) { credentials[1] = Utils.safeString(passwordTextBox.getValue()); } else { credentials[0] = Utils.safeString(passwordTextBox.getValue()); credentials[1] = ""; } AsyncCallback<AuthenticationStatus> callback = new AsyncCallback<AuthenticationStatus>() { @Override public void onFailure(Throwable caught) { WebPasswordSafe.handleServerFailure(caught); setSubmitting(false); } @Override public void onSuccess(AuthenticationStatus result) { if (AuthenticationStatus.SUCCESS == result) { doLoginSuccess(); } else if (AuthenticationStatus.TWO_STEP_REQ == result) { doTwoStep(); } else { MessageBox.alert(textMessages.error(), textMessages.invalidLogin(), null); isTwoStep = false; passwordTextBox.setFieldLabel(textMessages.password()); passwordTextBox.setValue(""); setSubmitting(false); } } }; LoginService.Util.getInstance().login(Utils.safeString(usernameTextBox.getValue()), credentials, callback); } } } private void doTwoStep() { setSubmitting(false); isTwoStep = true; usernameTextBox.setEnabled(false); passwordTextBox.setFieldLabel(textMessages.twoStepVerificationCode()); passwordTextBox.setValue(""); passwordTextBox.focus(); } private void doLoginSuccess() { main.doGetLoggedInUser(this); } @Override public void doGetLoginSuccess() { Info.display(textMessages.status(), textMessages.loggedIn(Format.htmlEncode(ClientSessionUtil.getInstance().getLoggedInUser().getUsername()))); hide(); } @Override public void doGetLoginFailure() { MessageBox.alert(textMessages.error(), textMessages.invalidUser(), null); } }