diff --git a/backoffice/src/main/java/uy/edu/fing/tse/jsf/UserLoginBean.java b/backoffice/src/main/java/uy/edu/fing/tse/jsf/UserLoginBean.java index 6ffbd0ff986a0e462241d283afda4773769796df..92d6fe21dd9c26e9d7422599e4fc382947e4c8a4 100644 --- a/backoffice/src/main/java/uy/edu/fing/tse/jsf/UserLoginBean.java +++ b/backoffice/src/main/java/uy/edu/fing/tse/jsf/UserLoginBean.java @@ -1,5 +1,11 @@ package uy.edu.fing.tse.jsf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import uy.edu.fing.tse.central.business.security.SecurityLocal; +import uy.edu.fing.tse.dto.UserBO; + +import javax.ejb.EJB; import javax.enterprise.context.RequestScoped; import javax.inject.Named; import java.io.Serializable; @@ -10,24 +16,15 @@ public class UserLoginBean implements Serializable { private static final long serialVersionUID = -7674319505640122631L; - private String username; - private String password; - private String repassword; + private static final Logger LOG = LoggerFactory.getLogger(UserLoginBean.class); + @EJB + private SecurityLocal securityLocal; - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } + final UserBO user = new UserBO(); + private String repassword; - public void setPassword(String password) { - this.password = password; + public UserBO getUser() { + return user; } public String getRepassword() { @@ -40,11 +37,13 @@ public class UserLoginBean implements Serializable { public void login() { - //aca va el login + + final var s = securityLocal.login(user); + LOG.info(s); } public void register() { - //aca va el register + final var s = securityLocal.register(user); } } diff --git a/backoffice/src/main/webapp/jsf/login.xhtml b/backoffice/src/main/webapp/jsf/login.xhtml index 13dd09f9f53e65f784b9e85deaec9711f6c9a61e..02c8eb5001081ab35c5463ee6c76c88a1fdea690 100644 --- a/backoffice/src/main/webapp/jsf/login.xhtml +++ b/backoffice/src/main/webapp/jsf/login.xhtml @@ -14,14 +14,14 @@ <h:panelGrid columns="2" cellpadding="5" id="form"> <h:outputLabel for="username" value="Username:"/> - <p:inputText id="username" value="#{userLoginView.username}" required="true" label="username"/> + <p:inputText id="username" value="#{userLoginView.user.mail}" required="true" label="username"/> <h:outputLabel for="password" value="Password:"/> - <p:password id="password" value="#{userLoginView.password}" required="true" label="password"/> + <p:password id="password" value="#{userLoginView.user.password}" required="true" label="password"/> <f:facet name="footer"> <p:commandButton value="Register" action="register.xhmtl?faces-redirect=true" update="form"/> - <p:commandButton value="Login" action="#{userLoginView.login}"/> + <p:commandButton value="Login" action="#{userLoginView.login()}"/> </f:facet> </h:panelGrid> </h:form> diff --git a/backoffice/src/main/webapp/jsf/register.xhtml b/backoffice/src/main/webapp/jsf/register.xhtml index 55964beaf881de1f1ab400bceaca906f34e38c34..67596c67325c79e1895b94ca83f63d4543236dd3 100644 --- a/backoffice/src/main/webapp/jsf/register.xhtml +++ b/backoffice/src/main/webapp/jsf/register.xhtml @@ -14,16 +14,16 @@ <h:panelGrid columns="2" cellpadding="5" id="form"> <h:outputLabel for="username" value="Username:"/> - <p:inputText id="username" value="#{userLoginView.username}" required="true" label="username"/> + <p:inputText id="username" value="#{userLoginView.user.mail}" required="true" label="username"/> <h:outputLabel for="password" value="Password:"/> - <p:password id="password" value="#{userLoginView.password}" required="true" label="password"/> + <p:password id="password" value="#{userLoginView.user.password}" required="true" label="password"/> <h:outputLabel for="repassword" value="RePassword:"/> <p:password id="repassword" value="#{userLoginView.repassword}" required="true" label="repassword"/> <f:facet name="footer"> - <p:commandButton value="Register" action="#{userLoginView.register}"/> + <p:commandButton value="Register" action="#{userLoginView.register()}"/> </f:facet> </h:panelGrid> </h:form> diff --git a/central-db/src/main/java/uy/edu/fing/tse/central/db/dao/user/UserDAOBean.java b/central-db/src/main/java/uy/edu/fing/tse/central/db/dao/user/UserDAOBean.java new file mode 100644 index 0000000000000000000000000000000000000000..fb1b5e10bc95b14116f397784cf3523ca95885ec --- /dev/null +++ b/central-db/src/main/java/uy/edu/fing/tse/central/db/dao/user/UserDAOBean.java @@ -0,0 +1,51 @@ +package uy.edu.fing.tse.central.db.dao.user; + +import uy.edu.fing.tse.central.db.entity.Usuario; +import uy.edu.fing.tse.central.db.mapper.MyMapper; +import uy.edu.fing.tse.dto.User; + +import javax.annotation.PostConstruct; +import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.List; +import java.util.stream.Collectors; + +@Stateless +public class UserDAOBean implements UserDaoLocal { + + @PersistenceContext(unitName = "central") + private EntityManager em; + + @PostConstruct + void init() { + //Despues del constructor hace esto + } + + + @Override + public void register(User user) { + + final var newUser = MyMapper.INSTANCE.convert(user); + em.persist(newUser); + em.flush(); + + } + + @Override + public User find(String mail) { + final var query = em.createNamedQuery("Usuario.findByMail", Usuario.class); + query.setParameter("mail", mail); + final Usuario usuario = query.getSingleResult(); + return MyMapper.INSTANCE.convert(usuario); + } + + @Override + public List<User> findAll() { + final var query = em.createNamedQuery("Usuario.findAll", Usuario.class); + final List<Usuario> usuarios = query.getResultList(); + + return usuarios.stream().map(MyMapper.INSTANCE::convert).collect(Collectors.toList()); + } + +} diff --git a/central-db/src/main/java/uy/edu/fing/tse/central/db/dao/user/UserDaoLocal.java b/central-db/src/main/java/uy/edu/fing/tse/central/db/dao/user/UserDaoLocal.java new file mode 100644 index 0000000000000000000000000000000000000000..0849cb6eb96bf5e85150135801fefdd81aae4e90 --- /dev/null +++ b/central-db/src/main/java/uy/edu/fing/tse/central/db/dao/user/UserDaoLocal.java @@ -0,0 +1,16 @@ +package uy.edu.fing.tse.central.db.dao.user; + +import uy.edu.fing.tse.dto.User; + +import javax.ejb.Local; +import java.util.List; + +@Local +public interface UserDaoLocal { + + void register(User user); + + User find(String mail); + + List<User> findAll(); +} diff --git a/central-db/src/main/java/uy/edu/fing/tse/central/db/entity/Usuario.java b/central-db/src/main/java/uy/edu/fing/tse/central/db/entity/Usuario.java index 59f512cdc7bf39db698585c59c148fd09df0f0e0..81b41ee44f1d34be06320385eead111b0241c64c 100644 --- a/central-db/src/main/java/uy/edu/fing/tse/central/db/entity/Usuario.java +++ b/central-db/src/main/java/uy/edu/fing/tse/central/db/entity/Usuario.java @@ -4,7 +4,12 @@ import javax.persistence.*; @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +@NamedQueries({ + @NamedQuery(name = "Usuario.findByMail", query = "SELECT u FROM Usuario u WHERE u.mail = :mail"), + @NamedQuery(name = "Usuario.findAll", query = "SELECT u FROM Usuario u") +}) public abstract class Usuario { + @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; diff --git a/central-db/src/main/java/uy/edu/fing/tse/central/db/entity/UsuarioBO.java b/central-db/src/main/java/uy/edu/fing/tse/central/db/entity/UsuarioBO.java index 6d7cbb05314c1711928f0679570c77a8c9f5bcbc..b0126c1a7455e764805d4677016dac06a041ad7f 100644 --- a/central-db/src/main/java/uy/edu/fing/tse/central/db/entity/UsuarioBO.java +++ b/central-db/src/main/java/uy/edu/fing/tse/central/db/entity/UsuarioBO.java @@ -3,13 +3,12 @@ package uy.edu.fing.tse.central.db.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.ManyToOne; -import java.util.UUID; @Entity public class UsuarioBO extends Usuario { @Column(nullable = false) - private String salt = UUID.randomUUID().toString(); + private String salt; @Column(nullable = false) private String password; @@ -21,6 +20,10 @@ public class UsuarioBO extends Usuario { return salt; } + public void setSalt(String salt) { + this.salt = salt; + } + public String getPassword() { return password; } diff --git a/central-ejb/pom.xml b/central-ejb/pom.xml index 91f5fc68016634ed1549499b1e9bf6b65e53ed23..0af5d6ce6f11560a2458fac236a181397f4f34bb 100644 --- a/central-ejb/pom.xml +++ b/central-ejb/pom.xml @@ -54,6 +54,12 @@ <artifactId>javax.annotation-api</artifactId> </dependency> + <dependency> + <groupId>at.favre.lib</groupId> + <artifactId>bcrypt</artifactId> + <version>0.8.0</version> + </dependency> + <!-- Test scope dependencies --> <dependency> <groupId>junit</groupId> diff --git a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/common/Secure.java b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/common/Secure.java new file mode 100644 index 0000000000000000000000000000000000000000..b003721f725214d2e07a5408244c560ce22c8df1 --- /dev/null +++ b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/common/Secure.java @@ -0,0 +1,56 @@ +package uy.edu.fing.tse.central.business.common; + +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Base64; + +public final class Secure { + private static final Charset CHARSET = StandardCharsets.UTF_8; + + private Secure() { + } + + public static String generateSalt() { + final SecureRandom random = new SecureRandom(); + final byte[] salt = new byte[16]; + random.nextBytes(salt); + + return new String(Base64.getEncoder().encode(salt), CHARSET); + } + + + public static String encriptSHA(final String pass, final String salt) { + try { + MessageDigest md = MessageDigest.getInstance("SHA-512"); + md.update(salt.getBytes(CHARSET)); + + byte[] hashedPassword = md.digest(pass.getBytes(CHARSET)); + return new String(Base64.getEncoder().encode(hashedPassword), CHARSET); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + + public static String encriptPBKDF(final String pass, final String salt) { + try { + KeySpec spec = new PBEKeySpec(pass.toCharArray(), salt.getBytes(CHARSET), 65536, 128); + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); + + byte[] hashedPassword = factory.generateSecret(spec).getEncoded(); + return new String(Base64.getEncoder().encode(hashedPassword), CHARSET); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + e.printStackTrace(); + } + return null; + } + + +} diff --git a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/mq/RabbitConfig.java b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/mq/RabbitConfig.java index 222443fb13e3e62e512dfbf70d2688cbac7be0da..f69dc7c2687b2389ea8fabfaeff3244a5ceb4261 100644 --- a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/mq/RabbitConfig.java +++ b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/mq/RabbitConfig.java @@ -39,4 +39,5 @@ final class RabbitConfig { return factory; } + } diff --git a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/Security.java b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/Security.java new file mode 100644 index 0000000000000000000000000000000000000000..873570cb667f098be29450729b901bdaeeeef08b --- /dev/null +++ b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/Security.java @@ -0,0 +1,14 @@ +package uy.edu.fing.tse.central.business.security; + + +import uy.edu.fing.tse.dto.User; +import uy.edu.fing.tse.dto.UserBO; + +public interface Security { + + User register(UserBO p); + + String login(UserBO p); + +} + diff --git a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityBean.java b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityBean.java new file mode 100644 index 0000000000000000000000000000000000000000..5d835dc2c1720e2e6734c5dafb705b01fd22f4e4 --- /dev/null +++ b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityBean.java @@ -0,0 +1,52 @@ +package uy.edu.fing.tse.central.business.security; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import uy.edu.fing.tse.central.business.common.Secure; +import uy.edu.fing.tse.central.db.dao.user.UserDaoLocal; +import uy.edu.fing.tse.dto.User; +import uy.edu.fing.tse.dto.UserBO; + +import javax.annotation.PostConstruct; +import javax.ejb.EJB; +import javax.ejb.Stateless; +import java.util.Objects; + +@Stateless +public class SecurityBean implements SecurityLocal, SecurityRemote { + + private static final Logger LOG = LoggerFactory.getLogger(Security.class); + + @EJB + private UserDaoLocal dao; + + @PostConstruct + void init() { + //Despues Hace esto + } + + @Override + public User register(UserBO p) { + final var salt = Secure.generateSalt(); + p.setSalt(salt); + final var newPassword = Secure.encriptPBKDF(p.getPassword(), salt); + p.setPassword(newPassword); + dao.register(p); + return dao.find(p.getMail()); + } + + @Override + public String login(UserBO p) { + //Valido la password + final var user = (UserBO) dao.find(p.getMail()); + final var salt = user.getSalt(); + final var thisPassword = Secure.encriptPBKDF(p.getPassword(), salt); + + if (Objects.equals(thisPassword, user.getPassword())) { + return thisPassword; + } + return null; + } + +} diff --git a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityLocal.java b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityLocal.java new file mode 100644 index 0000000000000000000000000000000000000000..fab0b6a2162fcc05ba762d0317a63f21578ac705 --- /dev/null +++ b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityLocal.java @@ -0,0 +1,7 @@ +package uy.edu.fing.tse.central.business.security; + +import javax.ejb.Local; + +@Local +public interface SecurityLocal extends Security { +} diff --git a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityRemote.java b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityRemote.java new file mode 100644 index 0000000000000000000000000000000000000000..b001861457f97323f99a7a7fbb6bd7240d13bd16 --- /dev/null +++ b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/security/SecurityRemote.java @@ -0,0 +1,5 @@ +package uy.edu.fing.tse.central.business.security; + +//@Remote +public interface SecurityRemote extends Security { +}