Packages moving and test of security layer.

This commit is contained in:
Florian
2018-03-16 23:37:33 +01:00
parent c587ff09a8
commit 3f9f3d5ad1
25 changed files with 132 additions and 56 deletions

View File

@@ -11,9 +11,11 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.codiki.security.Route;
import org.codiki.utils.StringUtils;
import org.codiki.core.security.Route;
import org.codiki.core.utils.StringUtils;
import org.springframework.http.HttpMethod;
/**
* Base class for all filters of the application.<br/>
@@ -54,7 +56,7 @@ public abstract class AbstractFilter implements Filter {
* @param chain
* The chain.
*/
protected abstract void filter(HttpServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
protected abstract void filter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
@@ -62,7 +64,7 @@ public abstract class AbstractFilter implements Filter {
HttpServletRequest httpRequest = (HttpServletRequest) request;
if(isRequestFiltered(httpRequest.getRequestURL().toString(), httpRequest.getMethod())) {
filter(httpRequest, response, chain);
filter(httpRequest, (HttpServletResponse) response, chain);
} else {
chain.doFilter(request, response);
}
@@ -71,14 +73,14 @@ public abstract class AbstractFilter implements Filter {
/**
* Check if the url is allowed with the given method in parameters.
*
* @param pUrlRequest
* @param pRequestUrl
* The url request.
* @param pMethodRequest
* @param pRequestMethod
* The http method of the request.
* @return {@code true} if the url is allowed with the method, {@code false}
* otherwise.
*/
boolean isRequestFiltered(final String pUrlRequest, final String pMethodRequest) {
boolean isRequestFiltered(final String pRequestUrl, final String pRequestMethod) {
boolean result = false;
for(final Route route : getRoutes()) {
@@ -86,9 +88,31 @@ public abstract class AbstractFilter implements Filter {
* Check urls matching, and if the method of the route isn't set, all methods
* are allowed. Otherwise, we check the methods too.
*/
result = Pattern.matches(StringUtils.concat(PREFIX_URL_PATH, route.getUrl()), pUrlRequest)
&& (!route.getMethod().isPresent() || pMethodRequest.equals(route.getMethod().get().toString()));
if(result) {
if(Pattern.matches(StringUtils.concat(PREFIX_URL_PATH, route.getUrl()), pRequestUrl)) {
if(!route.getMethod().isPresent() || isMethodFiltered(route, pRequestMethod)) {
result = true;
break;
}
}
}
return result;
}
/**
* Checks if the route do filter the method in parameters.
*
* @param pRoute
* The registered route.
* @param pRequestMethod
* The http method to check with the registered route.
*/
boolean isMethodFiltered(final Route pRoute, final String pRequestMethod) {
boolean result = false;
for(final HttpMethod routeMethod : pRoute.getMethod().get()) {
if(routeMethod.name().equals(pRequestMethod)) {
result = true;
break;
}
}

View File

@@ -1,4 +1,4 @@
package org.codiki.config;
package org.codiki.core.config;
import javax.sql.DataSource;

View File

@@ -1,9 +1,9 @@
package org.codiki.entities.dto;
package org.codiki.core.entities.dto;
import java.util.Date;
import org.codiki.entities.persistence.Role;
import org.codiki.entities.persistence.User;
import org.codiki.core.entities.persistence.Role;
import org.codiki.core.entities.persistence.User;
public class UserDAO {

View File

@@ -1,4 +1,4 @@
package org.codiki.entities.persistence;
package org.codiki.core.entities.persistence;
import java.io.Serializable;
import java.util.List;

View File

@@ -1,4 +1,4 @@
package org.codiki.entities.persistence;
package org.codiki.core.entities.persistence;
import java.io.Serializable;
import java.util.Date;

View File

@@ -1,4 +1,4 @@
package org.codiki.entities.persistence;
package org.codiki.core.entities.persistence;
import java.io.Serializable;
import java.util.Date;

View File

@@ -1,4 +1,4 @@
package org.codiki.entities.persistence;
package org.codiki.core.entities.persistence;
import java.io.Serializable;
import java.util.Date;

View File

@@ -1,4 +1,4 @@
package org.codiki.entities.persistence;
package org.codiki.core.entities.persistence;
import java.io.Serializable;
import java.util.Date;
@@ -18,7 +18,7 @@ import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.codiki.utils.DateUtils;
import org.codiki.core.utils.DateUtils;
@Entity
@Table(name="post")

View File

@@ -1,4 +1,4 @@
package org.codiki.entities.persistence;
package org.codiki.core.entities.persistence;
import java.io.Serializable;
import java.util.Date;

View File

@@ -1,4 +1,4 @@
package org.codiki.entities.persistence;
package org.codiki.core.entities.persistence;
import java.io.Serializable;

View File

@@ -1,4 +1,4 @@
package org.codiki.entities.persistence;
package org.codiki.core.entities.persistence;
import java.util.List;

View File

@@ -1,4 +1,4 @@
package org.codiki.entities.persistence;
package org.codiki.core.entities.persistence;
import java.io.Serializable;
import java.util.ArrayList;
@@ -20,7 +20,7 @@ import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.codiki.entities.security.Token;
import org.codiki.core.entities.security.Token;
@Entity
@Table(name="`user`")

View File

@@ -1,4 +1,4 @@
package org.codiki.entities.security;
package org.codiki.core.entities.security;
import java.math.BigInteger;
import java.security.SecureRandom;

View File

@@ -0,0 +1,10 @@
package org.codiki.core.repositories;
import org.codiki.core.entities.persistence.Post;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface PostRepository extends CrudRepository<Post, Long> {
}

View File

@@ -1,8 +1,8 @@
package org.codiki.repositories;
package org.codiki.core.repositories;
import java.util.Optional;
import org.codiki.entities.persistence.User;
import org.codiki.core.entities.persistence.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

View File

@@ -1,4 +1,4 @@
package org.codiki.security;
package org.codiki.core.security;
import java.io.IOException;
import java.util.Arrays;
@@ -8,8 +8,10 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.codiki.core.AbstractFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@@ -18,18 +20,25 @@ import org.springframework.stereotype.Component;
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AuthenticationFilter extends AbstractFilter {
@Autowired
private TokenService tokenService;
@Override
protected List<Route> getRoutes() {
return Arrays.asList(
new Route("\\/api\\/account\\/.*")
new Route("\\/api\\/posts.*")
);
}
@Override
protected void filter(HttpServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
protected void filter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("Token : " + request.getHeader("token"));
if(tokenService.isUserConnected(request.getHeader("token"))) {
chain.doFilter(request, response);
} else {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}
}

View File

@@ -1,5 +1,7 @@
package org.codiki.security;
package org.codiki.core.security;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.springframework.http.HttpMethod;
@@ -14,7 +16,7 @@ public class Route {
/** The regex to match urls. */
private String url;
/** The http method to match. Use a {@link Optional#empty()} to match all methods. */
private Optional<HttpMethod> method;
private Optional<List<HttpMethod>> method;
/**
* Instanciate a vierge route.
@@ -45,9 +47,9 @@ public class Route {
* The http method to match. Use a {@link Optional#empty()} to match
* all methods.
*/
public Route(final String pUrl, final HttpMethod pMethod) {
public Route(final String pUrl, final HttpMethod... pMethods) {
this(pUrl);
this.method = Optional.of(pMethod);
this.method = Optional.of(Arrays.asList(pMethods));
}
public String getUrl() {
@@ -58,12 +60,12 @@ public class Route {
this.url = url;
}
public Optional<HttpMethod> getMethod() {
public Optional<List<HttpMethod>> getMethod() {
return method;
}
public void setMethod(HttpMethod method) {
this.method = Optional.of(method);
public void setMethod(HttpMethod pMethods) {
this.method = Optional.of(Arrays.asList(pMethods));
}
}

View File

@@ -1,9 +1,9 @@
package org.codiki.security;
package org.codiki.core.security;
import java.util.Map;
import java.util.TreeMap;
import org.codiki.entities.persistence.User;
import org.codiki.core.entities.persistence.User;
import org.springframework.stereotype.Service;
@Service

View File

@@ -1,4 +1,4 @@
package org.codiki.utils;
package org.codiki.core.utils;
import java.text.DateFormat;
import java.text.ParseException;

View File

@@ -1,4 +1,4 @@
package org.codiki.utils;
package org.codiki.core.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

View File

@@ -1,4 +1,4 @@
package org.codiki.utils;
package org.codiki.core.utils;
import org.mindrot.jbcrypt.BCrypt;

View File

@@ -3,8 +3,8 @@ package org.codiki.login;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.codiki.entities.dto.UserDAO;
import org.codiki.security.TokenService;
import org.codiki.core.entities.dto.UserDAO;
import org.codiki.core.security.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

View File

@@ -5,11 +5,11 @@ import java.util.Optional;
import javax.naming.AuthenticationException;
import javax.servlet.http.HttpServletResponse;
import org.codiki.entities.dto.UserDAO;
import org.codiki.entities.persistence.User;
import org.codiki.repositories.UserRepository;
import org.codiki.security.TokenService;
import org.codiki.utils.StringUtils;
import org.codiki.core.entities.dto.UserDAO;
import org.codiki.core.entities.persistence.User;
import org.codiki.core.repositories.UserRepository;
import org.codiki.core.security.TokenService;
import org.codiki.core.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

View File

@@ -0,0 +1,21 @@
package org.codiki.posts;
import org.codiki.core.entities.persistence.Post;
import org.codiki.core.repositories.PostRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/posts")
public class PostController {
@Autowired
private PostRepository postRepository;
@GetMapping
public Iterable<Post> getAll() {
return postRepository.findAll();
}
}

View File

@@ -6,15 +6,13 @@ import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.codiki.security.Route;
import org.codiki.core.security.Route;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.http.HttpMethod;
@@ -36,7 +34,7 @@ public class AbstractFilterTest {
}
@Override
protected void filter(HttpServletRequest request, ServletResponse response, FilterChain chain)
protected void filter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
// Do nothing
}
@@ -69,4 +67,16 @@ public class AbstractFilterTest {
Assert.assertFalse(filter.isRequestFiltered("http://localhost/toto", "GET"));
}
@Test
public void test_isRequestFiltered_severalHttpMethods() {
((TestFilter) filter).routes = Arrays.asList(new Route("toto", HttpMethod.GET, HttpMethod.POST));
Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "GET"));
Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "POST"));
Assert.assertFalse(filter.isRequestFiltered("http://localhost/toto", "PUT"));
Assert.assertFalse(filter.isRequestFiltered("http://localhost/toto", "DELETE"));
Assert.assertFalse(filter.isRequestFiltered("http://localhost/toto", "DumbThing"));
}
}