From 42bb4ad63d2cbe4a35889eb9ad4bf5f1d08c2f6d Mon Sep 17 00:00:00 2001 From: Gustavo Martin Morcuende Date: Mon, 3 Oct 2016 14:17:10 +0200 Subject: [PATCH] Code refactoring. Handlers and sessions. --- src/main/java/com/prueba/core/MainRun.java | 10 ++-- .../prueba/core/context/ApplicationContext.java | 2 + .../core/context/security/handle/LoginHandler.java | 8 ++- .../core/context/security/handle/PagesHandler.java | 52 +++++++++++++++++ .../context/security/handle/SessionHandler.java | 65 ++++------------------ .../context/security/persistence/Sessions.java | 56 +++++++++++++++++++ .../web/application/ApplicationWebContext.java | 17 ++++-- .../com/prueba/core/web/controller/Controller.java | 1 - .../resources/controllers/LoginController.java | 48 ++++++++-------- .../resources/controllers/PagesController.java | 45 +++++++++++++++ src/main/java/com/prueba/view/login/PageImpl.java | 34 +++++++++++ 11 files changed, 245 insertions(+), 93 deletions(-) create mode 100644 src/main/java/com/prueba/core/context/security/handle/PagesHandler.java create mode 100644 src/main/java/com/prueba/core/context/security/persistence/Sessions.java create mode 100644 src/main/java/com/prueba/resources/controllers/PagesController.java create mode 100644 src/main/java/com/prueba/view/login/PageImpl.java diff --git a/src/main/java/com/prueba/core/MainRun.java b/src/main/java/com/prueba/core/MainRun.java index 65c9f0b..87972a9 100644 --- a/src/main/java/com/prueba/core/MainRun.java +++ b/src/main/java/com/prueba/core/MainRun.java @@ -4,19 +4,21 @@ import java.io.IOException; import java.net.InetSocketAddress; import com.prueba.core.context.ApplicationContext; +import com.prueba.core.context.security.handle.LoginHandler; +import com.prueba.core.context.security.handle.PagesHandler; import com.prueba.core.context.web.application.ApplicationWebContext; -import com.sun.net.httpserver.HttpContext; import com.sun.net.httpserver.HttpServer; public class MainRun { public static void main(String[] args) throws IOException { - HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); ApplicationContext appContext = ApplicationWebContext.getInstance(); - server.createContext(ApplicationWebContext.WEB_CONTEXT, appContext.getWebHandler()); - server.createContext(ApplicationWebContext.LOGIN_CONTEXT, appContext.getLoginHandler()); + HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); + server.createContext(PagesHandler.CONTEXT, appContext.getWebHandler()); + server.createContext(LoginHandler.CONTEXT, appContext.getLoginHandler()); server.setExecutor(null); + server.start(); } } diff --git a/src/main/java/com/prueba/core/context/ApplicationContext.java b/src/main/java/com/prueba/core/context/ApplicationContext.java index acb35db..b59f1e7 100644 --- a/src/main/java/com/prueba/core/context/ApplicationContext.java +++ b/src/main/java/com/prueba/core/context/ApplicationContext.java @@ -12,4 +12,6 @@ public interface ApplicationContext { HttpHandler getWebHandler(); HttpHandler getLoginHandler(); + + public HttpHandler getSessionHandler(); } diff --git a/src/main/java/com/prueba/core/context/security/handle/LoginHandler.java b/src/main/java/com/prueba/core/context/security/handle/LoginHandler.java index d8d6960..1b8d50c 100644 --- a/src/main/java/com/prueba/core/context/security/handle/LoginHandler.java +++ b/src/main/java/com/prueba/core/context/security/handle/LoginHandler.java @@ -9,13 +9,19 @@ import com.sun.net.httpserver.HttpHandler; public class LoginHandler implements HttpHandler { + public static final String CONTEXT = "/app/login/"; public static final String LOGIN_PAGE = "/app/login/login.html?serviceName=http://localhost:8080"; private final LoginController loginController = new LoginController(); + private final HttpHandler sessionHandler; + + public LoginHandler(HttpHandler sessionHandler) { + this.sessionHandler = sessionHandler; + } @Override public void handle(HttpExchange httpExchange) throws IOException { - final Headers headers = httpExchange.getRequestHeaders(); + sessionHandler.handle(httpExchange); loginController.handle(httpExchange); diff --git a/src/main/java/com/prueba/core/context/security/handle/PagesHandler.java b/src/main/java/com/prueba/core/context/security/handle/PagesHandler.java new file mode 100644 index 0000000..b51e3c9 --- /dev/null +++ b/src/main/java/com/prueba/core/context/security/handle/PagesHandler.java @@ -0,0 +1,52 @@ +package com.prueba.core.context.security.handle; + +import java.io.IOException; +import java.net.URI; +import java.time.LocalDateTime; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import com.prueba.core.context.security.persistence.SessionInfo; +import com.prueba.core.context.security.persistence.Sessions; +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + + +public class PagesHandler implements HttpHandler { + public static final String CONTEXT = "/app/pages/"; + + private static final String SERVER_ADDRESS = "http://localhost:8080"; + + private final HttpHandler sessionHandler; + + public PagesHandler(HttpHandler sessionHandler) { + this.sessionHandler = sessionHandler; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + this.sessionHandler.handle(httpExchange); + + final SessionInfo sessionInfo = SessionHandler.getLocalSession(); + if (Sessions.getInstance().isValidSession(httpExchange)) { + + // Call controller + Sessions.getInstance().refreshSession(sessionInfo.getUUID(), sessionInfo.getUsername()); + } else { + this.doRedirect(httpExchange); + } + + httpExchange.close(); + } + + protected void doRedirect(HttpExchange httpExchange) throws IOException { + URI requestURI = httpExchange.getRequestURI(); + String requestURIString = requestURI.toString(); + Headers responseHeaders = httpExchange.getResponseHeaders(); + + responseHeaders.add("Location", SERVER_ADDRESS + LoginHandler.LOGIN_PAGE + requestURIString); + httpExchange.sendResponseHeaders(302, 0); + } +} diff --git a/src/main/java/com/prueba/core/context/security/handle/SessionHandler.java b/src/main/java/com/prueba/core/context/security/handle/SessionHandler.java index 3e1ac0a..7caeaf8 100644 --- a/src/main/java/com/prueba/core/context/security/handle/SessionHandler.java +++ b/src/main/java/com/prueba/core/context/security/handle/SessionHandler.java @@ -1,86 +1,41 @@ package com.prueba.core.context.security.handle; import java.io.IOException; -import java.net.URI; -import java.time.LocalDateTime; -import java.util.Map; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; import com.prueba.core.context.security.persistence.SessionInfo; +import com.prueba.core.context.security.persistence.Sessions; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; - public class SessionHandler implements HttpHandler { private static final String COOKIE_HEADER = "Cookie"; - private static final String SERVER_ADDRESS = "http://localhost:8080"; - - private final Map sessions = new ConcurrentHashMap<>(); + private static final ThreadLocal localContextSession = new ThreadLocal<>(); + @Override public void handle(HttpExchange httpExchange) throws IOException { - final Headers headers = httpExchange.getRequestHeaders(); - final String cookieValue = headers.getFirst(COOKIE_HEADER); - final SessionInfo sessionInfo = getSessionInfo(httpExchange); - if (this.isValidSession(httpExchange)) { - // Call next handler - - this.refreshSession(sessionInfo.getUUID(), sessionInfo.getUsername()); - } else { - this.doRedirect(httpExchange); - } - httpExchange.close(); + localContextSession.set(sessionInfo); } - - public boolean isValidSession(HttpExchange httpExchange) { - final SessionInfo sessionInfo = getSessionInfo(httpExchange); - - boolean isValid = false; - - if (sessionInfo != null) { - LocalDateTime currentDateTime = LocalDateTime.now(); - if (sessionInfo.getLastSessionTime().plusMinutes(5).compareTo(currentDateTime) > 0) { - isValid = true; - } else { - sessions.remove(sessionInfo).getUUID(); - } - } - - return isValid; - } - - public void refreshSession(UUID uuid, String username) { - final SessionInfo newSessionInfo = - new SessionInfo(uuid, username, LocalDateTime.now()); - sessions.put(uuid, newSessionInfo); - } - - public Map getSessions() { - return this.sessions; - } - - public SessionInfo getSessionInfo(HttpExchange httpExchange) { + + protected SessionInfo getSessionInfo(HttpExchange httpExchange) { final Headers headers = httpExchange.getRequestHeaders(); final String cookieValue = headers.getFirst(COOKIE_HEADER); + SessionInfo sessionInfo = null; if (cookieValue != null) { final UUID uuid = UUID.fromString(cookieValue); - sessionInfo = sessions.get(uuid); + sessionInfo = Sessions.getInstance().getSession(uuid); } return sessionInfo; } - protected void doRedirect(HttpExchange httpExchange) throws IOException { - URI requestURI = httpExchange.getRequestURI(); - String requestURIString = requestURI.toString(); - Headers responseHeaders = httpExchange.getResponseHeaders(); - responseHeaders.add("Location", SERVER_ADDRESS + LoginHandler.LOGIN_PAGE + requestURIString); - httpExchange.sendResponseHeaders(302, 0); + public static SessionInfo getLocalSession() { + return localContextSession.get(); } } diff --git a/src/main/java/com/prueba/core/context/security/persistence/Sessions.java b/src/main/java/com/prueba/core/context/security/persistence/Sessions.java new file mode 100644 index 0000000..25b772e --- /dev/null +++ b/src/main/java/com/prueba/core/context/security/persistence/Sessions.java @@ -0,0 +1,56 @@ +package com.prueba.core.context.security.persistence; + +import java.time.LocalDateTime; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import com.prueba.core.context.security.handle.SessionHandler; +import com.sun.net.httpserver.HttpExchange; + +public class Sessions { + private final Map sessions = new ConcurrentHashMap<>(); + + private Sessions() { + + } + + private static class SessionsContextHolder { + private static final Sessions INSTANCE = new Sessions(); + } + + public static Sessions getInstance() { + return SessionsContextHolder.INSTANCE; + } + + public SessionInfo getSession(final UUID uuid) { + return sessions.get(uuid); + } + + public void refreshSession(UUID uuid, String username) { + final SessionInfo newSessionInfo = + new SessionInfo(uuid, username, LocalDateTime.now()); + sessions.put(uuid, newSessionInfo); + } + + public void removeSession(SessionInfo sessionInfo) { + sessions.remove(sessionInfo); + } + + public boolean isValidSession(HttpExchange httpExchange) { + final SessionInfo sessionInfo = SessionHandler.getLocalSession(); + + boolean isValid = false; + + if (sessionInfo != null) { + LocalDateTime currentDateTime = LocalDateTime.now(); + if (sessionInfo.getLastSessionTime().plusMinutes(5).compareTo(currentDateTime) > 0) { + isValid = true; + } else { + sessions.remove(sessionInfo); + } + } + + return isValid; + } +} diff --git a/src/main/java/com/prueba/core/context/web/application/ApplicationWebContext.java b/src/main/java/com/prueba/core/context/web/application/ApplicationWebContext.java index a90ff6f..a3c8fd1 100644 --- a/src/main/java/com/prueba/core/context/web/application/ApplicationWebContext.java +++ b/src/main/java/com/prueba/core/context/web/application/ApplicationWebContext.java @@ -7,16 +7,15 @@ import com.prueba.core.context.integration.datasource.impl.DoDataSourceContext; import com.prueba.core.context.integration.liquibase.impl.LiquibaseContext; import com.prueba.core.context.security.handle.LoginHandler; import com.prueba.core.context.security.handle.SessionHandler; +import com.prueba.core.context.security.handle.PagesHandler; import com.prueba.resources.controllers.LoginController; import com.sun.net.httpserver.HttpHandler; -public class ApplicationWebContext implements ApplicationContext { - public static final String WEB_CONTEXT = "/app/pages/"; - public static final String LOGIN_CONTEXT = "/app/login/"; - +public class ApplicationWebContext implements ApplicationContext { private final DataSource dataSource; private final LiquibaseContext liquibaseContext; + private final HttpHandler sessionHandler; private final HttpHandler webHttpHandler; private final HttpHandler loginHandler; @@ -24,8 +23,9 @@ public class ApplicationWebContext implements ApplicationContext { this.dataSource = DoDataSourceContext.getInstance().getDataSource(); this.liquibaseContext = new LiquibaseContext(dataSource); this.liquibaseContext.init(); - this.webHttpHandler = new SessionHandler(); - this.loginHandler = new LoginHandler(); + this.sessionHandler = new SessionHandler(); + this.webHttpHandler = new PagesHandler(sessionHandler); + this.loginHandler = new LoginHandler(sessionHandler); } private static class ApplicationWebContextHolder { @@ -50,4 +50,9 @@ public class ApplicationWebContext implements ApplicationContext { public HttpHandler getLoginHandler() { return this.loginHandler; } + + @Override + public HttpHandler getSessionHandler() { + return this.sessionHandler; + } } diff --git a/src/main/java/com/prueba/core/web/controller/Controller.java b/src/main/java/com/prueba/core/web/controller/Controller.java index 922bdb4..2584910 100644 --- a/src/main/java/com/prueba/core/web/controller/Controller.java +++ b/src/main/java/com/prueba/core/web/controller/Controller.java @@ -4,5 +4,4 @@ import com.sun.net.httpserver.HttpHandler; public interface Controller extends HttpHandler { - public String getURI(); } diff --git a/src/main/java/com/prueba/resources/controllers/LoginController.java b/src/main/java/com/prueba/resources/controllers/LoginController.java index 8a806f9..82da5db 100644 --- a/src/main/java/com/prueba/resources/controllers/LoginController.java +++ b/src/main/java/com/prueba/resources/controllers/LoginController.java @@ -10,7 +10,7 @@ import java.util.UUID; import com.prueba.core.context.security.handle.SessionHandler; import com.prueba.core.context.security.persistence.SessionInfo; -import com.prueba.core.context.web.application.ApplicationWebContext; +import com.prueba.core.context.security.persistence.Sessions; import com.prueba.core.web.controller.Controller; import com.prueba.services.impl.LoginServiceImpl; import com.prueba.view.login.LoginFormImpl; @@ -22,15 +22,14 @@ public class LoginController implements Controller { @Override public void handle(HttpExchange httpExchange) throws IOException { - final SessionHandler handler = (SessionHandler) ApplicationWebContext.getInstance().getWebHandler(); final String requestMethod = httpExchange.getRequestMethod(); switch (requestMethod) { case "GET": - this.processLogin(handler, httpExchange); + this.processLoginGet(httpExchange); break; case "POST": - this.processLoginPost(handler, httpExchange); + this.processLoginPost(httpExchange); break; default: httpExchange.sendResponseHeaders(404, 0); @@ -39,15 +38,15 @@ public class LoginController implements Controller { } - protected void processLogin(SessionHandler handler, HttpExchange httpExchange) throws IOException { + protected void processLoginGet(HttpExchange httpExchange) throws IOException { final String requestedURI = httpExchange.getRequestURI().toString(); - final SessionInfo sessionInfo = handler.getSessionInfo(httpExchange); + final SessionInfo sessionInfo = SessionHandler.getLocalSession(); final LoginFormImpl loginForm = new LoginFormImpl(); String html; - if (handler.isValidSession(httpExchange)) { + if (Sessions.getInstance().isValidSession(httpExchange)) { html = loginForm.doNoRequiredLogin(); - handler.refreshSession(sessionInfo.getUUID(), sessionInfo.getUsername()); + Sessions.getInstance().refreshSession(sessionInfo.getUUID(), sessionInfo.getUsername()); } else { html = loginForm.doRequiredLogin(requestedURI); } @@ -60,10 +59,10 @@ public class LoginController implements Controller { } - private void processLoginPost(SessionHandler handler, HttpExchange httpExchange) throws IOException { - final SessionInfo sessionInfo = handler.getSessionInfo(httpExchange); + private void processLoginPost(HttpExchange httpExchange) throws IOException { + final SessionInfo sessionInfo = SessionHandler.getLocalSession(); - if (!handler.isValidSession(httpExchange)) { + if (!Sessions.getInstance().isValidSession(httpExchange)) { String body = this.getBody(httpExchange); String [] formData = body.split("&"); if (formData.length == 2) { @@ -73,15 +72,15 @@ public class LoginController implements Controller { LoginServiceImpl loginService = new LoginServiceImpl(); if (loginService.isValidUser(username, password)) { UUID uuid = UUID.randomUUID(); - setCookieHeader(httpExchange, uuid.toString()); - handler.refreshSession(uuid, username); - doRedirect(httpExchange); + this.setCookieHeader(httpExchange, uuid.toString()); + Sessions.getInstance().refreshSession(uuid, username); + this.doRedirect(httpExchange); } else { httpExchange.sendResponseHeaders(401, 0); } } } else { - handler.refreshSession(sessionInfo.getUUID(), sessionInfo.getUsername()); + Sessions.getInstance().refreshSession(sessionInfo.getUUID(), sessionInfo.getUsername()); doRedirect(httpExchange); } } @@ -104,25 +103,22 @@ public class LoginController implements Controller { protected void setCookieHeader(HttpExchange httpExchange, String UUIDString) { Headers headers = httpExchange.getResponseHeaders(); + headers.remove("Set-Cookie"); headers.set("Set-Cookie", UUIDString + "; path=/"); } protected void doRedirect(HttpExchange httpExchange) throws IOException { - URI requestURI = httpExchange.getRequestURI(); - String requestURIString = requestURI.toString(); + String requestURIString = httpExchange.getRequestURI().toString(); String[] urls = requestURIString.split("serviceName="); + String serviceName = ""; if (urls.length == 2) { - String serviceName = urls[1]; - Headers responseHeaders = httpExchange.getResponseHeaders(); - responseHeaders.add("Location", serviceName); - httpExchange.sendResponseHeaders(302, 0); + serviceName = urls[1]; } - } - - @Override - public String getURI() { - return URI; + + Headers responseHeaders = httpExchange.getResponseHeaders(); + responseHeaders.add("Location", serviceName); + httpExchange.sendResponseHeaders(302, 0); } } diff --git a/src/main/java/com/prueba/resources/controllers/PagesController.java b/src/main/java/com/prueba/resources/controllers/PagesController.java new file mode 100644 index 0000000..b057df6 --- /dev/null +++ b/src/main/java/com/prueba/resources/controllers/PagesController.java @@ -0,0 +1,45 @@ +package com.prueba.resources.controllers; + +import java.io.IOException; + +import com.prueba.core.web.controller.Controller; +import com.sun.net.httpserver.HttpExchange; + +public class PagesController implements Controller { + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + final String requestMethod = httpExchange.getRequestMethod(); + + switch (requestMethod) { + case "GET": + this.processPages(httpExchange); + break; + default: + httpExchange.sendResponseHeaders(404, 0); + break; + } + + } + + protected void processPages(HttpExchange httpExchange) throws IOException { + final String requestedURI = httpExchange.getRequestURI().toString(); + + switch (requestedURI) { + case "/app/pages/page_1.html": + + break; + case "/app/pages/page_2.html": + + break; + case "/app/pages/page_3.html": + + break; + default: + httpExchange.sendResponseHeaders(404, 0); + break; + } + } + + +} diff --git a/src/main/java/com/prueba/view/login/PageImpl.java b/src/main/java/com/prueba/view/login/PageImpl.java new file mode 100644 index 0000000..889b214 --- /dev/null +++ b/src/main/java/com/prueba/view/login/PageImpl.java @@ -0,0 +1,34 @@ +package com.prueba.view.login; + +import java.io.IOException; + +import org.rendersnake.HtmlCanvas; + +import com.prueba.core.context.security.handle.SessionHandler; +import com.prueba.core.context.security.persistence.SessionInfo; + +public class PageImpl { + + public String doPage(int number) throws IOException { + final HtmlCanvas html = new HtmlCanvas(); + return html + .html() + .body() + .h1().content("PAGE: " + number) + .output().content("Hello: " + getSafeUserName()) + ._body() + ._html() + .toHtml(); + } + + private String getSafeUserName() { + SessionInfo sessionInfo = SessionHandler.getLocalSession(); + String userName = null; + + if (sessionInfo != null) { + userName = sessionInfo.getUsername(); + } + + return userName; + } +} -- 2.1.4