Agregado sistema de logeo
Es bastante bonito, me gusta la logica esta en su propio package ya que no encontraba que estuviera 100% relacionado con el resto de controlardores y vistas, dado que no heredan de las clases BaseController y BasePanel El main obtiene el resultado del logeo a travez de un listener customizado el cual entrega por evento un LoggedEvent, que contiene el usuario que fue logeado, de tal manera que se lo pueda entregar al resto de las vistas. Me costo 2 dias encontrar la combianacion perfecta de cosas para que esto funcionara llegando al final a la solucion de un listener superior. Pareciera que swing al no ejecutarse en el mismo thread no puedo tener un listener que cambie una variable de la instacia, que termine la ejecucion de swing y despues desde la clase superior leer la variable de instancia, ya que no parece que alcance a actualizarse en el thread principal.
This commit is contained in:
@@ -5,22 +5,27 @@ import java.lang.reflect.Field;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import xyz.danielcortes.controllers.LaunchController;
|
||||
import xyz.danielcortes.login.LoginController;
|
||||
import xyz.danielcortes.login.LoginPanel;
|
||||
|
||||
public class App {
|
||||
|
||||
public static void main(String[] args) {
|
||||
setupLookAndFeel();
|
||||
LaunchController launchController = new LaunchController();
|
||||
launchController.run();
|
||||
LoginController loginController = new LoginController(new LoginPanel());
|
||||
loginController.setLoggedListener(e -> {
|
||||
LaunchController launchController = new LaunchController(e.getUser());
|
||||
launchController.run();
|
||||
});
|
||||
}
|
||||
|
||||
private static void setupLookAndFeel(){
|
||||
System.setProperty("awt.useSystemAAFontSettings","lcd");
|
||||
private static void setupLookAndFeel() {
|
||||
System.setProperty("awt.useSystemAAFontSettings", "lcd");
|
||||
System.setProperty("swing.aatext", "true");
|
||||
|
||||
try {
|
||||
String windows = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
|
||||
String motif ="com.sun.java.swing.plaf.motif.MotifLookAndFeel";
|
||||
String motif = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
|
||||
String nimbus = "javax.swing.plaf.nimbus.NimbusLookAndFeel";
|
||||
String metal = "javax.swing.plaf.metal.MetalLookAndFeel";
|
||||
String gtk = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
|
||||
|
||||
@@ -29,6 +29,7 @@ import xyz.danielcortes.controllers.libro.LibroUpdateController;
|
||||
import xyz.danielcortes.controllers.libro.LibroViewController;
|
||||
import xyz.danielcortes.framework.BaseController;
|
||||
import xyz.danielcortes.framework.PanelName;
|
||||
import xyz.danielcortes.models.Usuario;
|
||||
import xyz.danielcortes.views.LaunchFrame;
|
||||
import xyz.danielcortes.views.autor.AutorCreatePanel;
|
||||
import xyz.danielcortes.views.autor.AutorSearchPanel;
|
||||
@@ -55,8 +56,10 @@ public class LaunchController {
|
||||
|
||||
private LaunchFrame frame;
|
||||
private Map<PanelName, BaseController> controllers;
|
||||
private Usuario user;
|
||||
|
||||
public LaunchController() {
|
||||
public LaunchController(Usuario user) {
|
||||
this.user = user;
|
||||
this.controllers = new HashMap<>();
|
||||
}
|
||||
|
||||
|
||||
21
src/main/java/xyz/danielcortes/framework/Hash.java
Normal file
21
src/main/java/xyz/danielcortes/framework/Hash.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package xyz.danielcortes.framework;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class Hash {
|
||||
|
||||
private static MessageDigest sha;
|
||||
|
||||
static {
|
||||
try {
|
||||
sha = MessageDigest.getInstance("SHA-256");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] sha256(byte[] toHash) {
|
||||
return sha.digest(toHash);
|
||||
}
|
||||
}
|
||||
31
src/main/java/xyz/danielcortes/framework/LoggedEvent.java
Normal file
31
src/main/java/xyz/danielcortes/framework/LoggedEvent.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package xyz.danielcortes.framework;
|
||||
|
||||
import java.util.EventObject;
|
||||
import xyz.danielcortes.models.Usuario;
|
||||
|
||||
/**
|
||||
* Un evento que indica que un usuario a sido logeado
|
||||
*/
|
||||
public class LoggedEvent extends EventObject {
|
||||
|
||||
private Usuario user;
|
||||
|
||||
/**
|
||||
* Crea el objeto y almacena los datos entregados
|
||||
*
|
||||
* El metodo lanza un {@code IllegalArgumentException} en caso que
|
||||
* {@code source} y {@code user} sean nulos.
|
||||
*
|
||||
* @param source El objeto en el que el evento se origino
|
||||
* @param user El usuario que fue logeado en el sistema
|
||||
* @throws IllegalArgumentException if source is null
|
||||
*/
|
||||
public LoggedEvent(Object source, Usuario user) {
|
||||
super(source);
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public Usuario getUser() {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
15
src/main/java/xyz/danielcortes/framework/LoggedListener.java
Normal file
15
src/main/java/xyz/danielcortes/framework/LoggedListener.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package xyz.danielcortes.framework;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
/**
|
||||
* La interfaz para recibir acciones de logeo de un usuario
|
||||
*/
|
||||
public interface LoggedListener extends EventListener {
|
||||
|
||||
/**
|
||||
* Se invoca cuando un usuario se logra logear al sistema.
|
||||
* @param e El evento que se ejecutara
|
||||
*/
|
||||
public void loginTry(LoggedEvent e);
|
||||
}
|
||||
66
src/main/java/xyz/danielcortes/login/LoginController.java
Normal file
66
src/main/java/xyz/danielcortes/login/LoginController.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package xyz.danielcortes.login;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.WindowConstants;
|
||||
import xyz.danielcortes.framework.Hash;
|
||||
import xyz.danielcortes.framework.LoggedEvent;
|
||||
import xyz.danielcortes.framework.LoggedListener;
|
||||
import xyz.danielcortes.models.Usuario;
|
||||
import xyz.danielcortes.repository.UsuarioRepository;
|
||||
|
||||
public class LoginController {
|
||||
|
||||
private JFrame frame;
|
||||
private LoginPanel view;
|
||||
private UsuarioRepository repository;
|
||||
private LoggedListener loggedListener;
|
||||
|
||||
public LoginController(LoginPanel view) {
|
||||
this.view = view;
|
||||
this.repository = new UsuarioRepository();
|
||||
this.setupListeners();
|
||||
this.createFrame();
|
||||
}
|
||||
|
||||
private void setupListeners() {
|
||||
this.view.getUserField().addActionListener(e -> login());
|
||||
this.view.getPassField().addActionListener(e -> login());
|
||||
this.view.getLoginButton().addActionListener(e -> login());
|
||||
}
|
||||
|
||||
private void login() {
|
||||
String name = this.view.getUserField().getText();
|
||||
|
||||
Optional<Usuario> optionalUser = this.repository.getByName(name);
|
||||
if (optionalUser.isEmpty())
|
||||
return;
|
||||
|
||||
Usuario user = optionalUser.get();
|
||||
byte[] pass = Hash.sha256(new String(this.view.getPassField().getPassword()).getBytes(StandardCharsets.UTF_8));
|
||||
if (Arrays.equals(pass, user.getPassword())) {
|
||||
this.frame.dispose();
|
||||
loggedListener.loginTry(new LoggedEvent(this, user));
|
||||
}
|
||||
}
|
||||
|
||||
private void createFrame() {
|
||||
Dimension dimension = new Dimension(400, 400);
|
||||
this.frame = new JFrame();
|
||||
this.frame.setSize(dimension);
|
||||
this.frame.setMinimumSize(dimension);
|
||||
this.frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
this.frame.setLocationRelativeTo(null);
|
||||
this.frame.setTitle("Login");
|
||||
this.frame.setContentPane(this.view.getContentPane());
|
||||
this.frame.setVisible(true);
|
||||
}
|
||||
|
||||
public void setLoggedListener(LoggedListener listener) {
|
||||
this.loggedListener = listener;
|
||||
}
|
||||
|
||||
}
|
||||
75
src/main/java/xyz/danielcortes/login/LoginPanel.form
Normal file
75
src/main/java/xyz/danielcortes/login/LoginPanel.form
Normal file
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="xyz.danielcortes.login.LoginPanel">
|
||||
<grid id="27dc6" binding="contentPane" layout-manager="GridLayoutManager" row-count="7" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="20" left="20" bottom="20" right="20"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="484" height="234"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="b31e3" class="javax.swing.JButton" binding="loginButton" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="5" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Login"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="f3513" class="javax.swing.JPasswordField" binding="passField">
|
||||
<constraints>
|
||||
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="300" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="89272" class="javax.swing.JTextField" binding="userField">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="300" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="c504f" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Usuario:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="575d2" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Contraseña:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="9f99a">
|
||||
<constraints>
|
||||
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<hspacer id="e1767">
|
||||
<constraints>
|
||||
<grid row="6" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<hspacer id="9c1e9">
|
||||
<constraints>
|
||||
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<vspacer id="e42c2">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
99
src/main/java/xyz/danielcortes/login/LoginPanel.java
Normal file
99
src/main/java/xyz/danielcortes/login/LoginPanel.java
Normal file
@@ -0,0 +1,99 @@
|
||||
package xyz.danielcortes.login;
|
||||
|
||||
import com.intellij.uiDesigner.core.GridConstraints;
|
||||
import com.intellij.uiDesigner.core.GridLayoutManager;
|
||||
import com.intellij.uiDesigner.core.Spacer;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Insets;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
public class LoginPanel {
|
||||
|
||||
private JButton loginButton;
|
||||
private JPanel contentPane;
|
||||
private JPasswordField passField;
|
||||
private JTextField userField;
|
||||
|
||||
public JButton getLoginButton() {
|
||||
return loginButton;
|
||||
}
|
||||
|
||||
public JPanel getContentPane() {
|
||||
return contentPane;
|
||||
}
|
||||
|
||||
public JPasswordField getPassField() {
|
||||
return passField;
|
||||
}
|
||||
|
||||
public JTextField getUserField() {
|
||||
return userField;
|
||||
}
|
||||
|
||||
{
|
||||
// GUI initializer generated by IntelliJ IDEA GUI Designer
|
||||
// >>> IMPORTANT!! <<<
|
||||
// DO NOT EDIT OR ADD ANY CODE HERE!
|
||||
$$$setupUI$$$();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method generated by IntelliJ IDEA GUI Designer >>> IMPORTANT!! <<< DO NOT edit this method OR call it in your code!
|
||||
*
|
||||
* @noinspection ALL
|
||||
*/
|
||||
private void $$$setupUI$$$() {
|
||||
contentPane = new JPanel();
|
||||
contentPane.setLayout(new GridLayoutManager(7, 3, new Insets(20, 20, 20, 20), -1, -1));
|
||||
loginButton = new JButton();
|
||||
loginButton.setText("Login");
|
||||
contentPane.add(loginButton, new GridConstraints(5, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE,
|
||||
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1),
|
||||
null, 0, false));
|
||||
passField = new JPasswordField();
|
||||
contentPane.add(passField, new GridConstraints(4, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
|
||||
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(300, -1),
|
||||
null, 0, false));
|
||||
userField = new JTextField();
|
||||
contentPane.add(userField, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL,
|
||||
GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(300, -1),
|
||||
null, 0, false));
|
||||
final JLabel label1 = new JLabel();
|
||||
label1.setText("Usuario:");
|
||||
contentPane.add(label1, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED,
|
||||
GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
|
||||
final JLabel label2 = new JLabel();
|
||||
label2.setText("Contraseña:");
|
||||
contentPane.add(label2, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED,
|
||||
GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
|
||||
final Spacer spacer1 = new Spacer();
|
||||
contentPane.add(spacer1,
|
||||
new GridConstraints(6, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null,
|
||||
null, null, 0, false));
|
||||
final Spacer spacer2 = new Spacer();
|
||||
contentPane.add(spacer2,
|
||||
new GridConstraints(6, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null,
|
||||
null, null, 0, false));
|
||||
final Spacer spacer3 = new Spacer();
|
||||
contentPane.add(spacer3,
|
||||
new GridConstraints(6, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null,
|
||||
null, null, 0, false));
|
||||
final Spacer spacer4 = new Spacer();
|
||||
contentPane.add(spacer4,
|
||||
new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null,
|
||||
null, null, 0, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection ALL
|
||||
*/
|
||||
public JComponent $$$getRootComponent$$$() {
|
||||
return contentPane;
|
||||
}
|
||||
|
||||
}
|
||||
67
src/main/java/xyz/danielcortes/models/Usuario.java
Normal file
67
src/main/java/xyz/danielcortes/models/Usuario.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package xyz.danielcortes.models;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "usuario")
|
||||
public class Usuario {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
|
||||
@Column(name = "nombre")
|
||||
private String nombre;
|
||||
|
||||
@Column(name = "password", columnDefinition = "varbinary(2000)")
|
||||
private byte[] password;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNombre() {
|
||||
return nombre;
|
||||
}
|
||||
|
||||
public void setNombre(String nombre) {
|
||||
this.nombre = nombre;
|
||||
}
|
||||
|
||||
public byte[] getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(byte[] password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!(o instanceof Usuario))
|
||||
return false;
|
||||
Usuario usuario = (Usuario) o;
|
||||
return Objects.equals(id, usuario.id) &&
|
||||
Objects.equals(nombre, usuario.nombre) &&
|
||||
Arrays.equals(password, usuario.password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Objects.hash(id, nombre);
|
||||
result = 31 * result + Arrays.hashCode(password);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package xyz.danielcortes.repository;
|
||||
|
||||
import java.util.Optional;
|
||||
import javax.persistence.NoResultException;
|
||||
import javax.persistence.TypedQuery;
|
||||
import xyz.danielcortes.framework.BaseRepository;
|
||||
import xyz.danielcortes.models.Usuario;
|
||||
|
||||
public class UsuarioRepository extends BaseRepository<Usuario> {
|
||||
|
||||
public Optional<Usuario> getByName(String name) {
|
||||
TypedQuery<Usuario> query = em.createQuery("SELECT u FROM Usuario u WHERE nombre = :nombre", Usuario.class);
|
||||
query.setParameter("nombre", name);
|
||||
|
||||
try{
|
||||
Usuario user = query.getSingleResult();
|
||||
return Optional.of(user);
|
||||
}catch (NoResultException e){
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user