From 4e0f2e8763089b2f0060ade83d6d016e0d4bca1f Mon Sep 17 00:00:00 2001 From: Gustavo Martin Morcuende Date: Mon, 3 Oct 2016 01:19:21 +0200 Subject: [PATCH] Session handler --- src/main/java/com/prueba/core/Handle.java | 12 +++++ src/main/java/com/prueba/core/MainRun.java | 21 ++++++++ .../prueba/core/context/ApplicationContext.java | 4 ++ .../authenticator/CustomBasicAuthenticator.java | 60 ++++++++++++++++++++++ .../context/security/handle/SessionHandle.java | 57 ++++++++++++++++++++ .../context/security/persistence/SessionInfo.java | 21 ++++++++ .../web/application/ApplicationWebContext.java | 23 +++++++-- .../context/ApplicationContextIntegrationTest.java | 26 ++++++++-- .../context/security/handle/SessionHandleTest.java | 14 +++++ .../security/persistence/SessionInfoTest.java | 21 ++++++++ 10 files changed, 250 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/prueba/core/Handle.java create mode 100644 src/main/java/com/prueba/core/MainRun.java create mode 100644 src/main/java/com/prueba/core/context/security/authenticator/CustomBasicAuthenticator.java create mode 100644 src/main/java/com/prueba/core/context/security/handle/SessionHandle.java create mode 100644 src/main/java/com/prueba/core/context/security/persistence/SessionInfo.java create mode 100644 src/test/java/com/prueba/core/context/security/handle/SessionHandleTest.java create mode 100644 src/test/java/com/prueba/core/context/security/persistence/SessionInfoTest.java diff --git a/src/main/java/com/prueba/core/Handle.java b/src/main/java/com/prueba/core/Handle.java new file mode 100644 index 0000000..67231a1 --- /dev/null +++ b/src/main/java/com/prueba/core/Handle.java @@ -0,0 +1,12 @@ +package com.prueba.core; + +import com.sun.net.httpserver.HttpExchange; + +public interface Handle { + + /** + * Handle some HTTP request + * @param httpExchange the HTTP request + */ + public void handle(HttpExchange httpExchange); +} diff --git a/src/main/java/com/prueba/core/MainRun.java b/src/main/java/com/prueba/core/MainRun.java new file mode 100644 index 0000000..496904d --- /dev/null +++ b/src/main/java/com/prueba/core/MainRun.java @@ -0,0 +1,21 @@ +package com.prueba.core; + +import java.io.IOException; +import java.net.InetSocketAddress; + +import com.prueba.core.context.ApplicationContext; +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(); + HttpContext hc1 = server.createContext( + ApplicationWebContext.WEB_CONTEXT, appContext.getWebHandler()); + 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 3d5b8ff..1a6b1d4 100644 --- a/src/main/java/com/prueba/core/context/ApplicationContext.java +++ b/src/main/java/com/prueba/core/context/ApplicationContext.java @@ -2,8 +2,12 @@ package com.prueba.core.context; import javax.sql.DataSource; +import com.sun.net.httpserver.HttpHandler; + + public interface ApplicationContext { DataSource getDataSource(); + HttpHandler getWebHandler(); } diff --git a/src/main/java/com/prueba/core/context/security/authenticator/CustomBasicAuthenticator.java b/src/main/java/com/prueba/core/context/security/authenticator/CustomBasicAuthenticator.java new file mode 100644 index 0000000..70af950 --- /dev/null +++ b/src/main/java/com/prueba/core/context/security/authenticator/CustomBasicAuthenticator.java @@ -0,0 +1,60 @@ +package com.prueba.core.context.security.authenticator; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + +import com.prueba.core.context.integration.database.DataBaseAccess; +import com.prueba.core.context.integration.database.impl.DataBaseAccessImpl; +import com.sun.net.httpserver.BasicAuthenticator; + +public class CustomBasicAuthenticator extends BasicAuthenticator { + private static final String CODE = "CODE"; + private static final String NAME = "NAME"; + private static final String SURNAME = "SURNAME"; + private static final String PASSWORD = "PASSWORD"; + private static final String APP_ROLE_CODE = "APPLICATION_ROLE_CODE"; + + public CustomBasicAuthenticator(String context, DataSource dataSource) { + super(context); + } + + @Override + public boolean checkCredentials(String username, String password) { + List> results = this.doQuery(username, password); + + if (results.isEmpty()) { + return false; + } else { + return true; + } + } + + + protected List> doQuery(String username, String password) { + final DataBaseAccess dataBaseAccess = new DataBaseAccessImpl(); + return dataBaseAccess.executeQuery("SELECT * FROM ACCOUNT WHERE CODE = ? AND PASSWORD = ?", + answer -> + { + final List> result = new ArrayList<>(); + while (answer.next()) { + final Map row = new HashMap<>(); + row.put(CODE, answer.getString(CODE)); + row.put(NAME, answer.getString(NAME)); + row.put(SURNAME, answer.getString(SURNAME)); + row.put(PASSWORD, answer.getString(PASSWORD)); + row.put(APP_ROLE_CODE, answer.getString(APP_ROLE_CODE)); + result.add(row); + } + + return result; + }, + preparedStatement -> { + preparedStatement.setString(1, username); + preparedStatement.setString(2, password); + }); + } +} diff --git a/src/main/java/com/prueba/core/context/security/handle/SessionHandle.java b/src/main/java/com/prueba/core/context/security/handle/SessionHandle.java new file mode 100644 index 0000000..29832b7 --- /dev/null +++ b/src/main/java/com/prueba/core/context/security/handle/SessionHandle.java @@ -0,0 +1,57 @@ +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.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + + +public class SessionHandle implements HttpHandler { + private static final String COOKIE_HEADER = "Cookie"; + private static final String LOGIN_PAGE = "http://localhost:8080/app/login/login.html?serviceName=http://localhost:8080"; + + private final Map sessions = new ConcurrentHashMap<>(); + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + final Headers headers = httpExchange.getRequestHeaders(); + final String cookieValue = headers.getFirst(COOKIE_HEADER); + + if (cookieValue != null) { + final UUID uuid = UUID.fromString(cookieValue); + final SessionInfo sessionInfo = sessions.get(uuid); + if (sessionInfo != null) { + LocalDateTime currentDateTime = LocalDateTime.now(); + if (sessionInfo.getLastSessionTime().plusMinutes(5).compareTo(currentDateTime) > 0) { + // Call next handler + + final SessionInfo newSessionInfo = new SessionInfo(sessionInfo.getUsername(), LocalDateTime.now()); + sessions.put(uuid, newSessionInfo); + } else { + this.doRedirec(httpExchange); + } + } else { + this.doRedirec(httpExchange); + } + } else { + this.doRedirec(httpExchange); + } + + httpExchange.close(); + } + + protected void doRedirec(HttpExchange httpExchange) throws IOException { + URI requestURI = httpExchange.getRequestURI(); + String requestURIString = requestURI.toString(); + Headers responseHeaders = httpExchange.getResponseHeaders(); + responseHeaders.add("Location", LOGIN_PAGE + requestURIString); + httpExchange.sendResponseHeaders(302, 0); + } +} diff --git a/src/main/java/com/prueba/core/context/security/persistence/SessionInfo.java b/src/main/java/com/prueba/core/context/security/persistence/SessionInfo.java new file mode 100644 index 0000000..c0aa0f2 --- /dev/null +++ b/src/main/java/com/prueba/core/context/security/persistence/SessionInfo.java @@ -0,0 +1,21 @@ +package com.prueba.core.context.security.persistence; + +import java.time.LocalDateTime; + +public class SessionInfo { + private final String username; + private final LocalDateTime lastSessionTime; + + public SessionInfo(String username, LocalDateTime lastSessionTime) { + this.username = username; + this.lastSessionTime = lastSessionTime; + } + + public String getUsername() { + return username; + } + public LocalDateTime getLastSessionTime() { + return lastSessionTime; + } + +} 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 9d2c7fe..fbcd65a 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 @@ -1,16 +1,27 @@ -package com.prueba.core.web.application.context; +package com.prueba.core.context.web.application; import javax.sql.DataSource; import com.prueba.core.context.ApplicationContext; 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.SessionHandle; +import com.sun.net.httpserver.HttpHandler; -public class ApplicationWebContext implements ApplicationContext { +public class ApplicationWebContext implements ApplicationContext { + public static final String WEB_CONTEXT = "/app/pages/"; + private final DataSource dataSource; + private final LiquibaseContext liquibaseContext; + private final HttpHandler webHttpHandler; private ApplicationWebContext() { this.dataSource = DoDataSourceContext.getInstance().getDataSource(); + this.liquibaseContext = new LiquibaseContext(dataSource); + this.liquibaseContext.init(); + this.webHttpHandler = new SessionHandle(); + } private static class ApplicationWebContextHolder { @@ -25,5 +36,9 @@ public class ApplicationWebContext implements ApplicationContext { public DataSource getDataSource() { return this.dataSource; } - -} + + @Override + public HttpHandler getWebHandler() { + return this.webHttpHandler; + } +} diff --git a/src/test/java/com/prueba/core/context/ApplicationContextIntegrationTest.java b/src/test/java/com/prueba/core/context/ApplicationContextIntegrationTest.java index 5b1e09a..58be66e 100644 --- a/src/test/java/com/prueba/core/context/ApplicationContextIntegrationTest.java +++ b/src/test/java/com/prueba/core/context/ApplicationContextIntegrationTest.java @@ -4,19 +4,35 @@ import static org.junit.Assert.assertNotNull; import javax.sql.DataSource; +import org.junit.Before; import org.junit.Test; -import com.prueba.core.web.application.context.ApplicationWebContext; +import com.prueba.core.context.web.application.ApplicationWebContext; + +import com.sun.net.httpserver.HttpHandler; public class ApplicationContextIntegrationTest { + private ApplicationContext context; + + @Before + public void init() { + this.context = ApplicationWebContext.getInstance(); + } @Test - public void whenGetDataSourceThenReturnCreatedDataSource() { - final ApplicationContext context = ApplicationWebContext.getInstance(); - - final DataSource dataSource = context.getDataSource(); + public void whenGetDataSourceThenReturnCreatedDataSource() { + final DataSource dataSource = this.context.getDataSource(); assertNotNull(dataSource); } + + @Test + public void whenGetWebHanderThenReturnCreatedWebHandler() { + + final HttpHandler webHandler = this.context.getWebHandler(); + + assertNotNull(webHandler); + } + } diff --git a/src/test/java/com/prueba/core/context/security/handle/SessionHandleTest.java b/src/test/java/com/prueba/core/context/security/handle/SessionHandleTest.java new file mode 100644 index 0000000..62b6b6f --- /dev/null +++ b/src/test/java/com/prueba/core/context/security/handle/SessionHandleTest.java @@ -0,0 +1,14 @@ +package com.prueba.core.context.security.handle; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class SessionHandleTest { + + @Test + public void test() { + fail("Not yet implemented"); + } + +} diff --git a/src/test/java/com/prueba/core/context/security/persistence/SessionInfoTest.java b/src/test/java/com/prueba/core/context/security/persistence/SessionInfoTest.java new file mode 100644 index 0000000..f4affc0 --- /dev/null +++ b/src/test/java/com/prueba/core/context/security/persistence/SessionInfoTest.java @@ -0,0 +1,21 @@ +package com.prueba.core.context.security.persistence; + +import static org.junit.Assert.*; + +import java.time.LocalDateTime; + +import org.junit.Test; + +public class SessionInfoTest { + private static final String USERNAME = "GUMARTINM"; + private static final LocalDateTime LAST_SESSION = LocalDateTime.now(); + + @Test + public void shouldCallGetters() { + SessionInfo sessionInfo = new SessionInfo(USERNAME, LAST_SESSION); + + assertEquals(USERNAME, sessionInfo.getUsername()); + assertEquals(LAST_SESSION, sessionInfo.getLastSessionTime()); + } + +} -- 2.1.4