Package games.stendhal.client.gui.login

Source Code of games.stendhal.client.gui.login.CreateAccountDialog$LowerCaseLetterDocument

/* $Id: CreateAccountDialog.java,v 1.12 2011/01/06 14:37:12 martinfuchs Exp $ */
/***************************************************************************
*                      (C) Copyright 2003 - Marauroa                      *
***************************************************************************
***************************************************************************
*                                                                         *
*   This program 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.                                   *
*                                                                         *
***************************************************************************/
package games.stendhal.client.gui.login;

import games.stendhal.client.StendhalClient;
import games.stendhal.client.stendhal;
import games.stendhal.client.gui.ProgressBar;
import games.stendhal.client.gui.layout.SBoxLayout;
import games.stendhal.client.gui.layout.SLayout;
import games.stendhal.client.update.ClientGameConfiguration;

import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Locale;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
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.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

import marauroa.client.BannedAddressException;
import marauroa.client.LoginFailedException;
import marauroa.client.TimeoutException;
import marauroa.common.game.AccountResult;
import marauroa.common.net.InvalidVersionException;

import org.apache.log4j.Logger;


public class CreateAccountDialog extends JDialog {

  private static final long serialVersionUID = 4436228792112530975L;

  private static final Logger logger = Logger.getLogger(CreateAccountDialog.class);

  // Variables declaration
  private JLabel usernameLabel;
  private JLabel serverLabel;
  private JLabel serverPortLabel;
  private JLabel passwordLabel;
  private JLabel passwordretypeLabel;
  private JLabel emailLabel;
  private JTextField usernameField;
  private JPasswordField passwordField;
  private JPasswordField passwordretypeField;
  private JTextField emailField;
  private JTextField serverField;
  private JTextField serverPortField;
  private JButton createAccountButton;
  private JPanel contentPane;

  // End of variables declaration
  private StendhalClient client;
  private Frame owner;
  private String badEmailTitle, badEmailReason, badPasswordReason;

  public CreateAccountDialog(final Frame owner, final StendhalClient client) {
    super(owner, true);
    this.client = client;
    this.owner = owner;
    initializeComponent();

    this.setVisible(true);
  }

  CreateAccountDialog() {
    super();
    initializeComponent();
  }

  private void initializeComponent() {
    this.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent e) {
        if (owner == null) {
          System.exit(0);
        }
        owner.setEnabled(true);
        dispose();
      }
    });

    serverLabel = new JLabel("Server name");
    serverField = new JTextField(
        ClientGameConfiguration.get("DEFAULT_SERVER"));
    serverField.setEditable(true);
    serverPortLabel = new JLabel("Server port");
    serverPortField = new JTextField(
        ClientGameConfiguration.get("DEFAULT_PORT"));

    usernameLabel = new JLabel("Choose a username");
    usernameField = new JTextField();
    usernameField.setDocument(new LowerCaseLetterDocument());

    passwordLabel = new JLabel("Choose a password");
    passwordField = new JPasswordField();

    passwordretypeLabel = new JLabel("Retype password");
    passwordretypeField = new JPasswordField();

    emailLabel = new JLabel("E-mail address (optional)");
    emailField = new JTextField();

    // createAccountButton
    //
    createAccountButton = new JButton();
    createAccountButton.setText("Create Account");
    createAccountButton.setMnemonic(KeyEvent.VK_C);
    this.rootPane.setDefaultButton(createAccountButton);
    createAccountButton.addActionListener(new ActionListener() {

      public void actionPerformed(final ActionEvent e) {
        createAccountButton_actionPerformed(e, false);
      }
    });

    //
    // contentPane
    //
    int padding = SBoxLayout.COMMON_PADDING;
    contentPane = (JPanel) this.getContentPane();
    contentPane.setLayout(new SBoxLayout(SBoxLayout.VERTICAL, padding));
    contentPane.setBorder(BorderFactory.createEmptyBorder(padding, padding, padding, padding));
   
    JComponent grid = new JComponent() {private static final long serialVersionUID = 1L;};
    grid.setLayout(new GridLayout(6, 2, padding, padding));
    contentPane.add(grid, SBoxLayout.constraint(SLayout.EXPAND_X, SLayout.EXPAND_Y));

    // row 0
    grid.add(serverLabel);
    grid.add(serverField);

    // row 1
    grid.add(serverPortLabel);
    grid.add(serverPortField);

    // row 2
    grid.add(usernameLabel);
    grid.add(usernameField);
 
    // row 3
    grid.add(passwordLabel);
    grid.add(passwordField);

    // row 4
    grid.add(passwordretypeLabel);
    grid.add(passwordretypeField);

    // row 5
    grid.add(emailLabel);
    grid.add(emailField);

    // Warning label
    JLabel logLabel = new JLabel("<html><body><p><font size=\"-2\">On login information which identifies your computer on <br>the internet will be logged to prevent abuse (like many <br>attempts to guess a password in order to hack an <br>account or creation of many accounts to cause trouble). <br>Furthermore all events and actions that happen within <br>the game-world (like solving quests, attacking monsters) <br>are logged. This information is used to analyse bugs and <br>in rare cases for abuse handling.</font></p></body></html>");
    // Add a bit more empty space around it
    logLabel.setBorder(BorderFactory.createEmptyBorder(padding, padding, padding, padding));
    logLabel.setAlignmentX(CENTER_ALIGNMENT);
    contentPane.add(logLabel, SBoxLayout.constraint(SLayout.EXPAND_X, SLayout.EXPAND_Y));
   
    createAccountButton.setAlignmentX(RIGHT_ALIGNMENT);
    contentPane.add(createAccountButton);
   
    // CreateAccountDialog
    this.setTitle("Create New Account");
    this.setResizable(false);
    // required on Compiz
    this.pack();

    usernameField.requestFocusInWindow();
    if (owner != null) {
      owner.setEnabled(false);
      this.setLocationRelativeTo(owner);
    }
  }

  private void createAccountButton_actionPerformed(final ActionEvent e,
      final boolean saveLoginBoxStatus) {
    final String accountUsername = usernameField.getText();
    final String password = new String(passwordField.getPassword());

    // If this window isn't enabled, we shouldn't act.
    if (!this.isEnabled()) {
      return;
    }

    final boolean ok = checkFields();

    if (!ok) {
      return;
    }

    final String email = emailField.getText();
    final String server = serverField.getText();
    int port = 32160;

    // standalone check
    if (client == null) {
      JOptionPane.showMessageDialog(this,
          "Account not created (running standalone)!");
      return;
    }
    // port couldn't be accessed from inner class
    final int finalPort;
    final ProgressBar progressBar = new ProgressBar(owner);

    try {
      port = Integer.parseInt(serverPortField.getText());
    } catch (final Exception ex) {
      JOptionPane.showMessageDialog(owner,
          "That is not a valid port number. Please try again.",
          "Invalid Port", JOptionPane.WARNING_MESSAGE);
      return;
    }
    finalPort = port;

    /* separate thread for connection process added by TheGeneral */
    // run the connection process in separate thread
    final Thread m_connectionThread = new Thread() {

      @Override
      public void run() {
        // initialize progress bar
        progressBar.start();
        // disable this screen when attempting to connect
        setEnabled(false);
 

        try {
          client.connect(server, finalPort);
          // for each major connection milestone call step()
          progressBar.step();
        } catch (final Exception ex) {
          // if something goes horribly just cancel the progress bar
          progressBar.cancel();
          setEnabled(true);
          JOptionPane.showMessageDialog(
              owner,
              "Unable to connect to server to create your account. The server may be down or, if you are using a custom server, " +
              "you may have entered its name and port number incorrectly.");

          logger.error(ex, ex);

          return;
        }

        try {
          final AccountResult result = client.createAccount(
              accountUsername, password, email);
          if (result.failed()) {
            /*
             * If the account can't be created, show an error
             * message and don't continue.
             */
            progressBar.cancel();
            setEnabled(true);
            JOptionPane.showMessageDialog(owner,
                result.getResult().getText(),
                "Create account failed",
                JOptionPane.ERROR_MESSAGE);
          } else {

            /*
             * Print username returned by server, as server can
             * modify it at will to match account names rules.
             */

            progressBar.step();
            progressBar.finish();

            client.setAccountUsername(accountUsername);
            client.setCharacter(accountUsername);

            /*
             * Once the account is created, login into server.
             */
            client.login(accountUsername, password);
            progressBar.step();
            progressBar.finish();

            setEnabled(false);
            if (owner != null) {
              owner.setVisible(false);
              owner.dispose();
            }

            stendhal.setDoLogin();
          }
        } catch (final TimeoutException e) {
          progressBar.cancel();
          setEnabled(true);
          JOptionPane.showMessageDialog(
              owner,
              "Unable to connect to server to create your account. The server may be down or, if you are using a custom server, you may have entered its name and port number incorrectly.",
              "Error Creating Account", JOptionPane.ERROR_MESSAGE);
        } catch (final InvalidVersionException e) {
          progressBar.cancel();
          setEnabled(true);
          JOptionPane.showMessageDialog(
              owner,
              "You are running an incompatible version of Stendhal. Please update",
              "Invalid version", JOptionPane.ERROR_MESSAGE);
        } catch (final BannedAddressException e) {
          progressBar.cancel();
          setEnabled(true);
          JOptionPane.showMessageDialog(
              owner,
              "Your IP is banned. If you think this is not right, please send a Support Request to http://sourceforge.net/tracker/?func=add&group_id=1111&atid=201111",
              "IP Banned", JOptionPane.ERROR_MESSAGE);
        } catch (final LoginFailedException e) {
          progressBar.cancel();
          setEnabled(true);
          JOptionPane.showMessageDialog(owner, e.getMessage(),
              "Login failed", JOptionPane.INFORMATION_MESSAGE);
        }
      }
    };
    m_connectionThread.start();
  }

  /**
   * Runs field checks, to, ex. confirm the passwords correct, etc.
   * @return if no error found
   */
  private boolean checkFields() {
    //
    // Check the password
    //
    final String password = new String(passwordField.getPassword());
    final String passwordretype = new String(
        passwordretypeField.getPassword());
    if (!password.equals(passwordretype)) {
      JOptionPane.showMessageDialog(owner,
          "The passwords do not match. Please retype both.",
          "Password Mismatch", JOptionPane.WARNING_MESSAGE);
      return false;
    }

    //
    // Password strength
    //
    final boolean valPass = validatePassword(usernameField.getText(), password);
    if (!valPass) {
      if (badPasswordReason != null) {
        // didn't like the password for some reason, show a dialog and
        // try again
        final int i = JOptionPane.showOptionDialog(owner, badPasswordReason,
            "Bad Password", JOptionPane.YES_NO_OPTION,
            JOptionPane.WARNING_MESSAGE, null, null, 1);

        if (i == JOptionPane.NO_OPTION) {
          return false;
        }
      } else {
        return false;
      }
    }

    //
    // Check the email
    //
    final String email = (emailField.getText()).trim();
    if  (!validateEmail(email)){
          final String warning = badEmailReason + "An email address is the only means for administrators to contact with the legitimate owner of an account.\nIf you don't provide one then you won't be able to get a new password for this account if, for example:\n- You forget your password.\n- Another player somehow gets your password and changes it.\nDo you want to continue anyway?"
             final int i = JOptionPane.showOptionDialog(owner, warning, badEmailTitle,
        JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
        null, null, 1);
            if (i != 0) {
          // no, let me type a valid email
                return false;
      }
      // yes, continue anyway   
    }
    return true;
  }

  private boolean validateEmail(final String email) {
    if  (email.length() == 0){
        badEmailTitle = "Email address is empty";
      badEmailReason = "You didn't enter an email address.\n";
        return false;
    } else {
           if (!email.contains("@") || !email.contains(".") || (email.length() <= 5)) {
            badEmailTitle =  "Misspelled email address?";
            badEmailReason = "The email address you entered is probably misspelled.\n";
            return false;
      }
    }
    return true;
  }

  /**
   * Used to preview the CreateAccountDialog.
   * @param args
   */
  public static void main(final String[] args) {
    new CreateAccountDialog(null, null);
  }

  private static class LowerCaseLetterDocument extends PlainDocument {
    private static final long serialVersionUID = -5123268875802709841L;

    @Override
    public void insertString(final int offs, final String str, final AttributeSet a)
        throws BadLocationException {
      final String lower = str.toLowerCase(Locale.ENGLISH);
      boolean ok = true;
      for (int i = lower.length() - 1; i >= 0; i--) {
        final char chr = lower.charAt(i);
        if ((chr < 'a') || (chr > 'z')) {
          ok = false;
          break;
        }
      }
      if (ok) {
        super.insertString(offs, lower, a);
      } else {
        Toolkit.getDefaultToolkit().beep();
      }
    }
  }

  public boolean validatePassword(final String username, final String password) {
    if (password.length() > 5) {

      // check for all numbers
      boolean allNumbers = true;
      try {
        Integer.parseInt(password);
      } catch (final Exception e) {
        allNumbers = false;
      }
      if (allNumbers) {
        badPasswordReason = "You have used only numbers in your password. This is not a good security practice.\n"
            + " Are you sure that you want to use this password?";
      }

      // check for username
      boolean hasUsername = false;
      if (password.contains(username)) {
        hasUsername = true;
      }

      if (!hasUsername) {
        // now we'll do some more checks to see if the password
        // contains more than three letters of the username
        debug("Checking if password contains a derivative of the username, trimming from the back...");
        final int min_user_length = 3;
        for (int i = 1; i < username.length(); i++) {
          final String subuser = username.substring(0, username.length()
              - i);
          debug("\tchecking for \"" + subuser + "\"...");
          if (subuser.length() <= min_user_length) {
            break;
          }

          if (password.contains(subuser)) {
            hasUsername = true;
            debug("Password contains username!");
            break;
          }
        }

        if (!hasUsername) {
          // now from the end of the password..
          debug("Checking if password contains a derivative of the username, trimming from the front...");
          for (int i = 0; i < username.length(); i++) {
            final String subuser = username.substring(i);
            debug("\tchecking for \"" + subuser + "\"...");
            if (subuser.length() <= min_user_length) {
              break;
            }
            if (password.contains(subuser)) {
              hasUsername = true;
              debug("Password contains username!");
              break;
            }
          }
        }
      }

      if (hasUsername) {
        badPasswordReason = "You have used your username or a derivative of your username in your password. This is a bad security practice.\n"
            + " Are you sure that you want to use this password?";
        return false;
      }

    } else {
      final String text = "The password you provided is too short. It must be at least 6 characters long.";
      if (isVisible()) {
        JOptionPane.showMessageDialog(owner, text);
      } else {
        logger.warn(text);
      }
      return false;
    }

    return true;
  }

  /**
   * Prints text only when running stand-alone.
   * @param text
   */
  public void debug(final String text) {

    if (client == null) {
      logger.debug(text);
    }
  }
}
TOP

Related Classes of games.stendhal.client.gui.login.CreateAccountDialog$LowerCaseLetterDocument

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.