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 589e11e4afa3b06890a33e8e748f7d1ac759a607..8a3ae8fbcfaa04dc42cacaf255902827a29b901b 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 @@ -15,8 +15,14 @@ import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import javax.inject.Inject; import javax.inject.Named; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.Size; import java.io.Serializable; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.List; +import java.util.Map; @RequestScoped @Named("userLoginView") @@ -43,6 +49,8 @@ public class UserLoginBean implements Serializable { final UserBO user = new UserBO(); + @NotEmpty + @Size(min = 8, message = "Password must have at least 8 characters") private String repassword; public List<Role> getRoles() { @@ -65,22 +73,22 @@ public class UserLoginBean implements Serializable { this.repassword = repassword; } - - public void login() { + public String login() { String token = securityLocal.login(user); if (token != null) { + addCookieToken(token); session.setToken(token); session.setUser(user); - // return "gestionhechos"; + return "jsf/gestionhechos"; } else { FacesContext.getCurrentInstance().addMessage( null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Ingreso Incorrecto", "Por favor verificar los datos ingresados")); - // return ""; } + return ""; } public String register() { @@ -92,7 +100,7 @@ public class UserLoginBean implements Serializable { //TODO if (valid) { final var s = securityLocal.register(user); - return "gestionhechos"; + return "jsf/gestionhechos"; } else { FacesContext.getCurrentInstance().addMessage( null, @@ -103,4 +111,12 @@ public class UserLoginBean implements Serializable { } } + private void addCookieToken(final String token) { + final Map<String, Object> properties = new HashMap<>(); + properties.put("maxAge", 31536000); + properties.put("path", "/"); + FacesContext.getCurrentInstance().getExternalContext() + .addResponseCookie("token", URLEncoder.encode(token, StandardCharsets.UTF_8), properties); + } + } diff --git a/backoffice/src/main/java/uy/edu/fing/tse/jsf/security/JwtFilter.java b/backoffice/src/main/java/uy/edu/fing/tse/jsf/security/JwtFilter.java index c0112eaf8817058e12e5745991edf4a5c54d3a8b..b0bc473fa49141c66d6b5164bc2d37c8220041ad 100644 --- a/backoffice/src/main/java/uy/edu/fing/tse/jsf/security/JwtFilter.java +++ b/backoffice/src/main/java/uy/edu/fing/tse/jsf/security/JwtFilter.java @@ -5,43 +5,52 @@ import io.jsonwebtoken.Jwts; import javax.servlet.*; import javax.servlet.annotation.WebFilter; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -//@WebFilter("/jsf/*") -//public class JwtFilter implements javax.servlet.Filter { -// @Override -// public void init(FilterConfig filterConfig) throws ServletException { -// -// } -// -// @Override -// public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { -// final HttpServletRequest request = (HttpServletRequest) req; -// final HttpServletResponse response = (HttpServletResponse) res; -// -// final String authHeader = request.getHeader("Authorization"); -// if (authHeader == null || !authHeader.startsWith("Bearer ")) { -// //TODO se puede hacer un send Redirect para enviarlo al Login -// response.setStatus(401); -// return; -// } -// -// try { -// final String token = authHeader.substring(7); // The part after "Bearer " -// final Claims claims = Jwts.parser().setSigningKey("1q2w3e4r5t6y7u8i9o0p").parseClaimsJws(token).getBody(); -// request.setAttribute("claims", claims); -// } catch (final Exception e) { -// response.setStatus(401); -// return; -// } -// -// chain.doFilter(req, res); -// } -// -// @Override -// public void destroy() { -// -// } -//} +@WebFilter("/jsf/*") +public class JwtFilter implements javax.servlet.Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + final HttpServletRequest request = (HttpServletRequest) req; + final HttpServletResponse response = (HttpServletResponse) res; + + Cookie cookieToken = null; + for (Cookie cookie : request.getCookies()) { + if ("token".equals(cookie.getName())) { + cookieToken = cookie; + break; + } + } + + if (cookieToken == null || cookieToken.getValue() == null) { + response.setStatus(401); + response.sendRedirect(request.getContextPath() + "/login.xhtml"); + return; + } + + final var token = cookieToken.getValue(); + + try { + final Claims claims = Jwts.parser().setSigningKey("1q2w3e4r5t6y7u8i9o0p").parseClaimsJws(token).getBody(); + request.setAttribute("claims", claims); + } catch (final Exception e) { + response.setStatus(401); + response.sendRedirect(request.getContextPath() + "/login.xhtml"); + return; + } + + chain.doFilter(req, res); + } + + @Override + public void destroy() { + } +} diff --git a/backoffice/src/main/java/uy/edu/fing/tse/jsf/session/SessionBean.java b/backoffice/src/main/java/uy/edu/fing/tse/jsf/session/SessionBean.java index ae950252835b231acebd35924b5006d524fbac91..54b7c8223e42ec2c3fb89422763dc491f9fe9d87 100644 --- a/backoffice/src/main/java/uy/edu/fing/tse/jsf/session/SessionBean.java +++ b/backoffice/src/main/java/uy/edu/fing/tse/jsf/session/SessionBean.java @@ -3,9 +3,7 @@ package uy.edu.fing.tse.jsf.session; import uy.edu.fing.tse.dto.UserBO; import javax.enterprise.context.SessionScoped; -import javax.faces.context.FacesContext; import javax.inject.Named; -import javax.servlet.http.HttpServletResponse; import java.io.Serializable; @SessionScoped @@ -34,11 +32,15 @@ public class SessionBean implements Serializable { this.user = user; } - public void putToken() { + public String makeToken() { if (token == null) { - return; + return null; } - HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); - response.setHeader("Authorization", "Bearer " + token); + return "Bearer " + token; + } + + public void invalidate() { + token = null; + user = null; } } diff --git a/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml b/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml index 624423b2d086142fd70dab5f8e32a8c80ac1cdb3..62700bce971f7e42f2aa21ec49a73fd492aca5ad 100644 --- a/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml +++ b/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml @@ -2,7 +2,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui" - xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core" + xmlns:h="http://xmlns.jcp.org/jsf/html" > <h:head> <style type="text/css"> @@ -30,9 +30,9 @@ </style> + <title>BackOffice - feiknius</title> </h:head> - <h:body> <header> @@ -40,7 +40,6 @@ </header> <!-- Menús, headers y todo lo que vaya antes del contenido --> <p:messages/> - <f:event type="preRenderView" listener="#{sessionBean.putToken()}"/> <ui:insert name="contenido"> Contenido por defecto para que no quede en blanco... </ui:insert> diff --git a/backoffice/src/main/webapp/jsf/gestionhechos.xhtml b/backoffice/src/main/webapp/jsf/gestionhechos.xhtml index 0efbe0c3eb76d683deac361337b31ac6bc9477ff..45ada12404979dca800bd54fa4365c6b05fc298d 100644 --- a/backoffice/src/main/webapp/jsf/gestionhechos.xhtml +++ b/backoffice/src/main/webapp/jsf/gestionhechos.xhtml @@ -12,7 +12,7 @@ <h:form> <p:outputPanel style="font-size: 30px;text-align: center"> <h:outputText value="Bienvenido "/> - <h:outputText value="#{userLoginView.user.mail}"/> + <h:outputText value="#{sessionBean.user.mail}"/> </p:outputPanel> <p:dataTable var="hecho" id="dataHecho" value="#{gestionHechos.facts}" widgetVar="NoticiasTable" diff --git a/backoffice/src/main/webapp/login.xhtml b/backoffice/src/main/webapp/login.xhtml index 13361863583e03012f5026ad1bf7bc6cd9e21df4..69689b8b37399b128216b19cb44ca5574edf699f 100644 --- a/backoffice/src/main/webapp/login.xhtml +++ b/backoffice/src/main/webapp/login.xhtml @@ -23,10 +23,13 @@ <f:facet name="footer"> - <h:commandButton value="Register" action="register.xhmtl?faces-redirect=true" + <h:commandButton styleClass="btn btn-primary" value="Crear Usuario" + action="register.xhmtl?faces-redirect=true" update="form" async="true" process="@this"/> - <h:commandButton value="Login" action="#{userLoginView.login()}" update="form"/> + <h:commandButton styleClass="btn btn-primary" + value="Login" action="#{userLoginView.login()}" + update="form"/> </f:facet> <h:inputHidden id="token" value="#{sessionBean.token}"/> </h:panelGrid> diff --git a/backoffice/src/main/webapp/jsf/register.xhtml b/backoffice/src/main/webapp/register.xhtml similarity index 100% rename from backoffice/src/main/webapp/jsf/register.xhtml rename to backoffice/src/main/webapp/register.xhtml