diff --git a/biblioteca.vpp b/biblioteca.vpp index 34f5a52..682d42d 100644 Binary files a/biblioteca.vpp and b/biblioteca.vpp differ diff --git a/script.sql b/script.sql index 4bcfe3f..43d55c1 100644 --- a/script.sql +++ b/script.sql @@ -2,6 +2,7 @@ #-----------------------------Eliminar todas las tablas--------------------------# #--------------------------------------------------------------------------------# set foreign_key_checks = 0; +drop table if exists usuario; drop table if exists libro_arriendo; drop table if exists libro_venta; drop table if exists libro_compra; @@ -84,10 +85,10 @@ create table libro create table ejemplar ( - id int unsigned primary key auto_increment, - serie varchar(255) not null, - libro_id int unsigned not null, - estado_id int unsigned default 1, + id int unsigned primary key auto_increment, + serie varchar(255) not null, + libro_id int unsigned not null, + estado_id int unsigned default 1, unique key serie_libro (serie, libro_id), foreign key (libro_id) references libro (id) on delete cascade on update cascade, foreign key (estado_id) references estado (id) on delete restrict on update cascade @@ -297,6 +298,17 @@ create table libro_arriendo 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------------------------------# #--------------------------------------------------------------------------------# diff --git a/src/main/java/xyz/danielcortes/App.java b/src/main/java/xyz/danielcortes/App.java index c3f389b..e9dda4b 100644 --- a/src/main/java/xyz/danielcortes/App.java +++ b/src/main/java/xyz/danielcortes/App.java @@ -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"; diff --git a/src/main/java/xyz/danielcortes/controllers/LaunchController.java b/src/main/java/xyz/danielcortes/controllers/LaunchController.java index 725d5c5..85ed4c8 100644 --- a/src/main/java/xyz/danielcortes/controllers/LaunchController.java +++ b/src/main/java/xyz/danielcortes/controllers/LaunchController.java @@ -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 controllers; + private Usuario user; - public LaunchController() { + public LaunchController(Usuario user) { + this.user = user; this.controllers = new HashMap<>(); } diff --git a/src/main/java/xyz/danielcortes/framework/Hash.java b/src/main/java/xyz/danielcortes/framework/Hash.java new file mode 100644 index 0000000..f5394f5 --- /dev/null +++ b/src/main/java/xyz/danielcortes/framework/Hash.java @@ -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); + } +} diff --git a/src/main/java/xyz/danielcortes/framework/LoggedEvent.java b/src/main/java/xyz/danielcortes/framework/LoggedEvent.java new file mode 100644 index 0000000..075e8fb --- /dev/null +++ b/src/main/java/xyz/danielcortes/framework/LoggedEvent.java @@ -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; + } +} diff --git a/src/main/java/xyz/danielcortes/framework/LoggedListener.java b/src/main/java/xyz/danielcortes/framework/LoggedListener.java new file mode 100644 index 0000000..98766e3 --- /dev/null +++ b/src/main/java/xyz/danielcortes/framework/LoggedListener.java @@ -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); +} diff --git a/src/main/java/xyz/danielcortes/login/LoginController.java b/src/main/java/xyz/danielcortes/login/LoginController.java new file mode 100644 index 0000000..e611689 --- /dev/null +++ b/src/main/java/xyz/danielcortes/login/LoginController.java @@ -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 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; + } + +} diff --git a/src/main/java/xyz/danielcortes/login/LoginPanel.form b/src/main/java/xyz/danielcortes/login/LoginPanel.form new file mode 100644 index 0000000..06f337d --- /dev/null +++ b/src/main/java/xyz/danielcortes/login/LoginPanel.form @@ -0,0 +1,75 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/xyz/danielcortes/login/LoginPanel.java b/src/main/java/xyz/danielcortes/login/LoginPanel.java new file mode 100644 index 0000000..7eb14bc --- /dev/null +++ b/src/main/java/xyz/danielcortes/login/LoginPanel.java @@ -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; + } + +} diff --git a/src/main/java/xyz/danielcortes/models/Usuario.java b/src/main/java/xyz/danielcortes/models/Usuario.java new file mode 100644 index 0000000..1c491db --- /dev/null +++ b/src/main/java/xyz/danielcortes/models/Usuario.java @@ -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; + } +} diff --git a/src/main/java/xyz/danielcortes/repository/UsuarioRepository.java b/src/main/java/xyz/danielcortes/repository/UsuarioRepository.java new file mode 100644 index 0000000..317243c --- /dev/null +++ b/src/main/java/xyz/danielcortes/repository/UsuarioRepository.java @@ -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 { + + public Optional getByName(String name) { + TypedQuery 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(); + } + } +}