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:
Daniel Cortés
2019-05-27 12:06:23 -04:00
parent 32afdce86a
commit 3b69bbcfe7
12 changed files with 426 additions and 10 deletions

Binary file not shown.

View File

@@ -2,6 +2,7 @@
#-----------------------------Eliminar todas las tablas--------------------------# #-----------------------------Eliminar todas las tablas--------------------------#
#--------------------------------------------------------------------------------# #--------------------------------------------------------------------------------#
set foreign_key_checks = 0; set foreign_key_checks = 0;
drop table if exists usuario;
drop table if exists libro_arriendo; drop table if exists libro_arriendo;
drop table if exists libro_venta; drop table if exists libro_venta;
drop table if exists libro_compra; drop table if exists libro_compra;
@@ -297,6 +298,17 @@ create table libro_arriendo
foreign key (arriendo_id) references arriendo (id) on delete restrict on update cascade foreign key (arriendo_id) references arriendo (id) on delete restrict on update cascade
); );
#--------------------------------------------------------------------------------#
#---------------------Definicion de las tablas de usuario------------------------#
#--------------------------------------------------------------------------------#
create table usuario
(
id int unsigned primary key auto_increment,
nombre varchar(255) not null,
password varbinary(2000) not null
);
#--------------------------------------------------------------------------------# #--------------------------------------------------------------------------------#
#------------------------Poblar con datos iniciales------------------------------# #------------------------Poblar con datos iniciales------------------------------#
#--------------------------------------------------------------------------------# #--------------------------------------------------------------------------------#

View File

@@ -5,13 +5,18 @@ import java.lang.reflect.Field;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException; import javax.swing.UnsupportedLookAndFeelException;
import xyz.danielcortes.controllers.LaunchController; import xyz.danielcortes.controllers.LaunchController;
import xyz.danielcortes.login.LoginController;
import xyz.danielcortes.login.LoginPanel;
public class App { public class App {
public static void main(String[] args) { public static void main(String[] args) {
setupLookAndFeel(); setupLookAndFeel();
LaunchController launchController = new LaunchController(); LoginController loginController = new LoginController(new LoginPanel());
loginController.setLoggedListener(e -> {
LaunchController launchController = new LaunchController(e.getUser());
launchController.run(); launchController.run();
});
} }
private static void setupLookAndFeel() { private static void setupLookAndFeel() {

View File

@@ -29,6 +29,7 @@ import xyz.danielcortes.controllers.libro.LibroUpdateController;
import xyz.danielcortes.controllers.libro.LibroViewController; import xyz.danielcortes.controllers.libro.LibroViewController;
import xyz.danielcortes.framework.BaseController; import xyz.danielcortes.framework.BaseController;
import xyz.danielcortes.framework.PanelName; import xyz.danielcortes.framework.PanelName;
import xyz.danielcortes.models.Usuario;
import xyz.danielcortes.views.LaunchFrame; import xyz.danielcortes.views.LaunchFrame;
import xyz.danielcortes.views.autor.AutorCreatePanel; import xyz.danielcortes.views.autor.AutorCreatePanel;
import xyz.danielcortes.views.autor.AutorSearchPanel; import xyz.danielcortes.views.autor.AutorSearchPanel;
@@ -55,8 +56,10 @@ public class LaunchController {
private LaunchFrame frame; private LaunchFrame frame;
private Map<PanelName, BaseController> controllers; private Map<PanelName, BaseController> controllers;
private Usuario user;
public LaunchController() { public LaunchController(Usuario user) {
this.user = user;
this.controllers = new HashMap<>(); this.controllers = new HashMap<>();
} }

View 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);
}
}

View 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;
}
}

View 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);
}

View 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;
}
}

View 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>

View 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;
}
}

View 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;
}
}

View File

@@ -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();
}
}
}