package net.sf.colossus.webclient; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.GridLayout; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.util.logging.Logger; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; import net.sf.colossus.webcommon.User; /** * A panel with which one can either create a new account, * or change the password. * * @author Clemens Katzer */ class RegisterPasswordPanel extends JDialog { private static final Logger LOGGER = Logger .getLogger(RegisterPasswordPanel.class.getName()); private final static Point defaultLocation = new Point(600, 100); private final static String defaultEmail = "your.email@some.domain"; private final WebClient webClient; private final boolean isRegister; private final Box yBox; private final JTextField rploginField; private JTextField rpEmailField; private JPasswordField rpOldPW; private final JPasswordField rpNewPW1; private final JPasswordField rpNewPW2; private final JButton rpButton; public RegisterPasswordPanel(WebClient webClient, boolean isRegister, String username) { super(webClient, "", true); this.webClient = webClient; this.isRegister = isRegister; setTitle(isRegister ? "Create account" : "Change password"); Container rootPane = getContentPane(); yBox = new Box(BoxLayout.Y_AXIS); yBox.setBorder(new EmptyBorder(20, 20, 20, 20)); JPanel p = new JPanel(new GridLayout(0, 2)); p.setAlignmentX(LEFT_ALIGNMENT); if (isRegister) { addText("A registration to the \"Colossus Public Game Server\" is only needed and useful if you are "); addText("familiar with Colossus, and want now to connect to the server to find opponents to play."); addText("If you don't know Colossus yet, it's recommended that you first play a few games locally."); addText("\n"); addText("You do not need to register to be able to play Colossus locally on your PC. "); addText("\n"); yBox.add(p); addText("\n"); addText("Fill in the values and click 'Create Account'. In the next step you will be asked "); addText("for a confirmation code which is sent to that address."); addText("\n"); } else { yBox.add(p); addText("\n"); } p.add(new JLabel("Login name")); rploginField = new JTextField(username); rploginField.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { rploginField.selectAll(); } }); p.add(rploginField); // old password only needed in change password if (!isRegister) { // @@TODO: in future, for change password (change properties) // fetch email from server and let user change it? p.add(new JLabel("Old Password")); rpOldPW = new JPasswordField(""); rpOldPW.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { rpOldPW.selectAll(); } }); p.add(rpOldPW); } else { // register instead needs an email: p.add(new JLabel("Email address")); rpEmailField = new JTextField(defaultEmail, 20); rpEmailField.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { rpEmailField.selectAll(); } }); p.add(rpEmailField); } p.add(new JLabel("Password")); rpNewPW1 = new JPasswordField(""); rpNewPW1.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { rpNewPW1.selectAll(); } }); p.add(rpNewPW1); p.add(new JLabel("Repeat Password")); rpNewPW2 = new JPasswordField(""); rpNewPW2.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { rpNewPW2.selectAll(); } }); p.add(rpNewPW2); p.add(new JLabel("")); String buttonText = isRegister ? "Create account" : "Change password"; rpButton = new JButton(buttonText); rpButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getSource() == rpButton) { buttonPressed(); } } }); rpButton.setEnabled(true); p.add(rpButton); final JButton cancelButton = new JButton("Cancel"); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getSource() == cancelButton) { dispose(); } } }); Box xBox = new Box(BoxLayout.X_AXIS); xBox.add(Box.createHorizontalGlue()); xBox.add(cancelButton); xBox.add(Box.createHorizontalGlue()); JPanel cancelPanel = new JPanel(new BorderLayout()); cancelPanel.setAlignmentX(LEFT_ALIGNMENT); cancelPanel.add(xBox, BorderLayout.CENTER); cancelPanel.add(Box.createHorizontalGlue(), BorderLayout.WEST); cancelPanel.add(Box.createHorizontalGlue(), BorderLayout.EAST); yBox.add(cancelPanel); rootPane.add(yBox); this.setLocation(defaultLocation); } private void addText(String message) { yBox.add(WebClient.nonBoldLabel(message)); } public void packAndShow() { pack(); setVisible(true); } private void buttonPressed() { Runnable tempRunnable = new Runnable() { public void run() { // System.out.println("** Runnable started"); buttonPressedActualAction(); // System.out.println("** Runnable completed"); } }; // System.out.println("* Creating the runnable"); Thread tempThread = new Thread(tempRunnable, "RegisterPasswordPanelButtonPressedRunnable"); tempThread.start(); // System.out.println("* Done with creating the runnable"); } /** Run inside the Runnable/thread that was created when the * Register / Change password button was pressed. * */ private void buttonPressedActualAction() { boolean ok = true; String name = rploginField.getText(); String newPW1 = new String(rpNewPW1.getPassword()); String newPW2 = new String(rpNewPW2.getPassword()); String oldPW = null; ok = ok && webClient.validateField(this, name, "Login name"); ok = ok && webClient.validateField(this, newPW1, "New Password"); ok = ok && webClient.validateField(this, newPW2, "Password repeat"); if (!isRegister) { oldPW = new String(rpOldPW.getPassword()); ok = ok && webClient.validateField(this, oldPW, "Old Password"); } if (!newPW1.equals(newPW2)) { JOptionPane.showMessageDialog(this, "Password and repeated password do not match!"); ok = false; } if (newPW1.equals(oldPW)) { JOptionPane.showMessageDialog(this, "Old and new are the same - no point to change!"); ok = false; } // validateXXXchecks and PW-compare showed message dialog if // something is wrong, so here we simply abort. if (!ok) { return; } if (isRegister) { String hostname = webClient.getHost(); String portText = webClient.getPort(); String email = rpEmailField.getText(); ok = ok && webClient.validateField(this, hostname, "Host name"); ok = ok && webClient.validatePort(this, portText); ok = ok && webClient.validateField(this, email, "Email Adress"); if (email.equals(defaultEmail)) { JOptionPane.showMessageDialog(this, "Please provide an email address!"); ok = false; } else if (!looksLikeValidEmailAddress(email)) { ok = false; } if (!ok) { return; } String reason = webClient.createRegisterWebClientSocketThread( name, newPW1, email, null); LOGGER.info("First createRegisterReturnsWCST() reason:" + reason); if (reason.equals(User.PROVIDE_CONFCODE)) { webClient .updateStatus("Provide confirmation code", Color.blue); handleConfirmation(name, newPW1, email); } else if (reason.equals(User.WRONG_CONFCODE)) { LOGGER.severe("WRONG CONF CODE message on first try??"); JOptionPane.showMessageDialog(this, reason); webClient.updateStatus(User.WRONG_CONFCODE, Color.red); handleConfirmation(name, newPW1, email); } else { webClient.updateStatus("Registration failed " + "(" + reason + ")", Color.red); JOptionPane.showMessageDialog(this, reason); } } else { String reason = webClient.tryChangePassword(name, oldPW, newPW1); if (reason == null) { JOptionPane.showMessageDialog(this, "Password was changed successfully.", "Password change OK", JOptionPane.INFORMATION_MESSAGE); this.dispose(); } else { JOptionPane.showMessageDialog(this, "Changing password failed: " + reason, "Changing password failed", JOptionPane.ERROR_MESSAGE); } } } private boolean looksLikeValidEmailAddress(String email) { String regex = "[-.\\w]+@[-.\\w]+\\.[-\\w]+"; if (email.matches(regex)) { return true; } else { JOptionPane.showMessageDialog(this, "Email address does appear to be invalid!\n" + "(allowed are: 'a-z, A-Z, 0-9, _ - .' and one '@'."); return false; } } private void handleConfirmation(String name, String newPW1, String email) { boolean done = false; while (!done) { String providedConfCode = JOptionPane.showInputDialog(this, "Type in the confirmation code sent to you via mail: ", User.TEMPLATE_CONFCODE); if (providedConfCode == null) { // TODO send a cancel message to server so that it // removes the pending user from list? // Not critical, because if user tries again // it will replace it anyway... done = true; } else if (providedConfCode.equals(User.TEMPLATE_CONFCODE) || providedConfCode.equals("")) { JOptionPane.showMessageDialog(this, "Confirmation code must not be empty and not " + "the provided example!!"); } else { providedConfCode = providedConfCode.trim(); String reason2 = webClient .createRegisterWebClientSocketThread(name, newPW1, email, providedConfCode); if (reason2 == null) { // OK! done = true; } else { // otherwise just show what's wrong webClient.updateStatus(reason2, Color.red); JOptionPane.showMessageDialog(this, reason2); } } } } @Override public void dispose() { webClient.restoreStatusField(); setVisible(false); super.dispose(); } }