This repository has been archived on 2021-12-05. You can view files and clone it, but cannot push or open issues or pull requests.
envoy/src/main/java/envoy/client/ui/container/LoginDialog.java

347 lines
11 KiB
Java

package envoy.client.ui.container;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.logging.Logger;
import javax.naming.TimeLimitExceededException;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import envoy.client.data.*;
import envoy.client.event.HandshakeSuccessfulEvent;
import envoy.client.net.Client;
import envoy.client.ui.Theme;
import envoy.client.ui.primary.PrimaryButton;
import envoy.data.LoginCredentials;
import envoy.data.Message;
import envoy.data.User;
import envoy.event.EventBus;
import envoy.event.HandshakeRejectionEvent;
import envoy.exception.EnvoyException;
import envoy.util.EnvoyLog;
/**
* Project: <strong>envoy-client</strong><br>
* File: <strong>LoginDialog.java</strong><br>
* Created: <strong>01.01.2020</strong><br>
*
* @author Kai S. K. Engelbart
* @author Maximilian K&auml;fer
* @since Envoy Client v0.3-alpha
*/
public class LoginDialog extends JDialog {
private JPanel contentPanel;
private JTextField textField;
private JPasswordField passwordField;
private JPasswordField repeatPasswordField;
private JLabel lblUserName;
private JLabel lblPassword;
private JLabel lblRepeatPassword;
private JLabel errorMessage;
private GridBagConstraints gbc_lblRepeatPassword;
private GridBagConstraints gbc_repeatPasswordField;
private GridBagConstraints gbc_errorMessage;
private JPanel buttonPane;
private JTextPane registerText;
private JCheckBox registerCheckBox;
private PrimaryButton okButton;
private PrimaryButton cancelButton;
private LoginCredentials credentials;
private final Client client;
private final LocalDB localDB;
private final Cache<Message> receivedMessageCache;
private static final ClientConfig config = ClientConfig.getInstance();
private static final Logger logger = EnvoyLog.getLogger(LoginDialog.class);
private static final long serialVersionUID = 0L;
/**
* Displays a dialog enabling the user to enter their user name and password.
*
* @param client the client used to perform the handshake
* @param localDB the local database in which data is persisted
* @param receivedMessageCache the cache that stored messages received during
* the handshake
* @since Envoy Client v0.3-alpha
*/
public LoginDialog(Client client, LocalDB localDB, Cache<Message> receivedMessageCache) {
this.client = client;
this.localDB = localDB;
this.receivedMessageCache = receivedMessageCache;
// Prepare handshake
localDB.loadIDGenerator();
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) { abortLogin(); }
});
initUi();
okButton.addActionListener((evt) -> {
try {
if (registerCheckBox.isSelected()) {
// Check password equality
if (Arrays.equals(passwordField.getPassword(), repeatPasswordField.getPassword())) {
credentials = new LoginCredentials(textField.getText(), passwordField.getPassword(), true);
performHandshake();
} else {
JOptionPane.showMessageDialog(this, "The repeated password is not the original password!");
clearPasswordFields();
}
} else {
credentials = new LoginCredentials(textField.getText(), passwordField.getPassword(), false);
performHandshake();
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
});
// Listen to handshake rejections
EventBus.getInstance()
.register(HandshakeRejectionEvent.class,
evt -> { clearPasswordFields(); errorMessage.setVisible(true); errorMessage.setText(evt.get()); });
// Exit the application when the dialog is cancelled
cancelButton.addActionListener(evt -> abortLogin());
// Log in directly if configured
if (config.hasLoginCredentials()) {
credentials = config.getLoginCredentials();
performHandshake();
return;
}
setVisible(true);
}
private void performHandshake() {
try {
client.performHandshake(credentials, receivedMessageCache);
if (client.isOnline()) {
client.initReceiver(localDB, receivedMessageCache);
dispose();
}
} catch (IOException | InterruptedException | TimeLimitExceededException e) {
logger.warning("Could not connect to server. Trying offline mode...");
e.printStackTrace();
try {
// Try entering offline mode
localDB.loadUsers();
User clientUser = localDB.getUsers().get(credentials.getIdentifier());
if (clientUser == null) throw new EnvoyException("Could not enter offline mode: user name unknown");
client.setSender(clientUser);
JOptionPane.showMessageDialog(null,
"A connection to the server could not be established. Starting in offline mode.\n" + e,
"Connection error",
JOptionPane.WARNING_MESSAGE);
dispose();
} catch (Exception e1) {
JOptionPane.showMessageDialog(null, e1, "Client error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
return;
}
}
}
private void initUi() {
setSize(338, 123);
setLocationRelativeTo(null);
setResizable(false);
getContentPane().setLayout(new BorderLayout());
contentPanel = new JPanel();
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
GridBagLayout gbl_contentPanel = new GridBagLayout();
gbl_contentPanel.columnWidths = new int[] { 0, 0, 0 };
gbl_contentPanel.rowHeights = new int[] { 0, 0, 0 };
gbl_contentPanel.columnWeights = new double[] { 0.0, 1.0, Double.MIN_VALUE };
gbl_contentPanel.rowWeights = new double[] { 0.0, 0.0, Double.MIN_VALUE };
contentPanel.setLayout(gbl_contentPanel);
lblUserName = new JLabel("Username:");
GridBagConstraints gbc_lblUserName = new GridBagConstraints();
gbc_lblUserName.anchor = GridBagConstraints.EAST;
gbc_lblUserName.insets = new Insets(0, 0, 5, 5);
gbc_lblUserName.gridx = 0;
gbc_lblUserName.gridy = 0;
contentPanel.add(lblUserName, gbc_lblUserName);
textField = new JTextField();
textField.setBorder(null);
GridBagConstraints gbc_textField = new GridBagConstraints();
gbc_textField.insets = new Insets(0, 0, 5, 0);
gbc_textField.fill = GridBagConstraints.HORIZONTAL;
gbc_textField.gridx = 1;
gbc_textField.gridy = 0;
contentPanel.add(textField, gbc_textField);
textField.setColumns(10);
lblPassword = new JLabel("Password:");
GridBagConstraints gbc_lblPassword = new GridBagConstraints();
gbc_lblPassword.anchor = GridBagConstraints.EAST;
gbc_lblPassword.insets = new Insets(0, 0, 0, 5);
gbc_lblPassword.gridx = 0;
gbc_lblPassword.gridy = 1;
contentPanel.add(lblPassword, gbc_lblPassword);
passwordField = new JPasswordField();
passwordField.setBorder(null);
GridBagConstraints gbc_passwordField = new GridBagConstraints();
gbc_passwordField.fill = GridBagConstraints.HORIZONTAL;
gbc_passwordField.gridx = 1;
gbc_passwordField.gridy = 1;
contentPanel.add(passwordField, gbc_passwordField);
lblRepeatPassword = new JLabel("Repeat Password:");
gbc_lblRepeatPassword = new GridBagConstraints();
gbc_lblRepeatPassword.anchor = GridBagConstraints.EAST;
gbc_lblRepeatPassword.insets = new Insets(0, 0, 0, 5);
gbc_lblRepeatPassword.gridx = 0;
gbc_lblRepeatPassword.gridy = 2;
repeatPasswordField = new JPasswordField();
gbc_repeatPasswordField = new GridBagConstraints();
gbc_repeatPasswordField.fill = GridBagConstraints.HORIZONTAL;
gbc_repeatPasswordField.gridx = 1;
gbc_repeatPasswordField.gridy = 2;
errorMessage = new JLabel();
gbc_errorMessage = new GridBagConstraints();
gbc_errorMessage.gridx = 1;
gbc_errorMessage.gridy = 3;
gbc_errorMessage.fill = GridBagConstraints.HORIZONTAL;
gbc_errorMessage.insets = new Insets(5, 5, 5, 5);
errorMessage.setForeground(Color.RED);
errorMessage.setVisible(false);
contentPanel.add(errorMessage, gbc_errorMessage);
buttonPane = new JPanel();
registerText = new JTextPane();
registerText.setEditable(false);
registerText.setText("Register?");
registerText.setFont(new Font("Arial", Font.BOLD, 12));
registerText.setAlignmentX(LEFT_ALIGNMENT);
buttonPane.add(registerText);
registerCheckBox = new JCheckBox();
registerCheckBox.setAlignmentX(LEFT_ALIGNMENT);
registerCheckBox.addItemListener(e -> {
switch (e.getStateChange()) {
case ItemEvent.SELECTED:
contentPanel.add(lblRepeatPassword, gbc_lblRepeatPassword);
contentPanel.add(repeatPasswordField, gbc_repeatPasswordField);
setSize(338, 173);
break;
case ItemEvent.DESELECTED:
if (repeatPasswordField.getParent() == contentPanel) {
contentPanel.remove(lblRepeatPassword);
contentPanel.remove(repeatPasswordField);
setSize(338, 148);
}
break;
}
contentPanel.revalidate();
contentPanel.repaint();
});
buttonPane.add(registerCheckBox);
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane, BorderLayout.SOUTH);
okButton = new PrimaryButton("OK");
okButton.setActionCommand("OK");
buttonPane.add(okButton);
getRootPane().setDefaultButton(okButton);
cancelButton = new PrimaryButton("Cancel");
cancelButton.setActionCommand("Cancel");
buttonPane.add(cancelButton);
setTheme();
setModalityType(Dialog.DEFAULT_MODALITY_TYPE);
EventBus.getInstance().register(HandshakeSuccessfulEvent.class, evt -> dispose());
}
/**
* Resets the text stored in the password fields.
*
* @since Envoy Client v0.3-alpha
*/
private void clearPasswordFields() {
passwordField.setText(null);
repeatPasswordField.setText(null);
}
private void setTheme() {
Theme theme = Settings.getInstance().getCurrentTheme();
// Panels
contentPanel.setBackground(theme.getBackgroundColor());
contentPanel.setForeground(theme.getBackgroundColor());
buttonPane.setBackground(theme.getBackgroundColor());
buttonPane.setForeground(theme.getBackgroundColor());
// Input Fields
textField.setBackground(theme.getCellColor());
textField.setForeground(theme.getUserNameColor());
passwordField.setBackground(theme.getCellColor());
passwordField.setForeground(theme.getUserNameColor());
repeatPasswordField.setBackground(theme.getCellColor());
repeatPasswordField.setForeground(theme.getUserNameColor());
// JLabels
lblUserName.setBackground(theme.getCellColor());
lblUserName.setForeground(theme.getUserNameColor());
lblPassword.setBackground(theme.getCellColor());
lblPassword.setForeground(theme.getUserNameColor());
lblRepeatPassword.setBackground(theme.getCellColor());
lblRepeatPassword.setForeground(theme.getUserNameColor());
// Register
registerText.setBackground(theme.getCellColor());
registerText.setForeground(theme.getUserNameColor());
registerCheckBox.setBackground(theme.getCellColor());
// Buttons
okButton.setBackground(theme.getInteractableBackgroundColor());
okButton.setForeground(theme.getInteractableForegroundColor());
cancelButton.setBackground(theme.getInteractableBackgroundColor());
cancelButton.setForeground(theme.getInteractableForegroundColor());
}
/**
* Shuts the system down properly if the login was aborted.
*
* @since Envoy Client v0.1-beta
*/
private void abortLogin() {
logger.info("The login process has been cancelled. Exiting...");
System.exit(0);
}
}