Initial commit.
This commit is contained in:
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
nbproject/private/
|
||||||
|
build/
|
||||||
|
nbbuild/
|
||||||
|
dist/
|
||||||
|
nbdist/
|
||||||
|
.nb-gradle/
|
||||||
74
pom.xml
Normal file
74
pom.xml
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>org.codiki</groupId>
|
||||||
|
<artifactId>codiki</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>codiki</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.0.0.RELEASE</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- <dependency> -->
|
||||||
|
<!-- <groupId>org.springframework.boot</groupId> -->
|
||||||
|
<!-- <artifactId>spring-boot-starter-security</artifactId> -->
|
||||||
|
<!-- </dependency> -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.mindrot/jbcrypt -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mindrot</groupId>
|
||||||
|
<artifactId>jbcrypt</artifactId>
|
||||||
|
<version>0.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
||||||
14
src/main/java/org/codiki/CodikiApplication.java
Normal file
14
src/main/java/org/codiki/CodikiApplication.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package org.codiki;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
public class CodikiApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(CodikiApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/main/java/org/codiki/config/JpaConfiguration.java
Normal file
42
src/main/java/org/codiki/config/JpaConfiguration.java
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package org.codiki.config;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||||
|
import org.springframework.boot.jdbc.DataSourceBuilder;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EntityScan("org.codiki")
|
||||||
|
@EnableTransactionManagement
|
||||||
|
@EnableJpaRepositories("org.codiki")
|
||||||
|
@PropertySource("classpath:application.properties")
|
||||||
|
public class JpaConfiguration {
|
||||||
|
|
||||||
|
@Value("${spring.datasource.driverClassName}")
|
||||||
|
private String driverClassName;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.url}")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.username}")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.password}")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@Bean(name="dataSource")
|
||||||
|
public DataSource getDataSource() {
|
||||||
|
return DataSourceBuilder.create()
|
||||||
|
.username(username)
|
||||||
|
.password(password)
|
||||||
|
.url(url)
|
||||||
|
.driverClassName(driverClassName)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
103
src/main/java/org/codiki/core/AbstractFilter.java
Normal file
103
src/main/java/org/codiki/core/AbstractFilter.java
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
package org.codiki.core;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.codiki.security.Route;
|
||||||
|
import org.codiki.utils.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for all filters of the application.<br/>
|
||||||
|
* <br/>
|
||||||
|
* The children classes have to implements the method
|
||||||
|
* {@link AbstractFilter#getClass()} to set the URLs filtered (with all or some
|
||||||
|
* http methods), and the method
|
||||||
|
* {@link AbstractFilter#filter(HttpServletRequest, ServletResponse, FilterChain)}
|
||||||
|
* to define the filter processing.
|
||||||
|
*
|
||||||
|
* @author Takiguchi
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AbstractFilter implements Filter {
|
||||||
|
|
||||||
|
/** Regex url path prefix for method {@link this#isRequestFiltered(String)}. */
|
||||||
|
private static final String PREFIX_URL_PATH = "https?:\\/\\/.*(:\\d{0,5})?";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of routes which will be processed by the filter.
|
||||||
|
*
|
||||||
|
* @return The routes.
|
||||||
|
*/
|
||||||
|
protected abstract List<Route> getRoutes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter actions for its processing.
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* The http request.
|
||||||
|
* @param response
|
||||||
|
* The response.
|
||||||
|
* @param chain
|
||||||
|
* The chain.
|
||||||
|
*/
|
||||||
|
protected abstract void filter(HttpServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||||
|
|
||||||
|
if(isRequestFiltered(httpRequest.getRequestURL().toString(), httpRequest.getMethod())) {
|
||||||
|
filter(httpRequest, response, chain);
|
||||||
|
} else {
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the url is allowed with the given method in parameters.
|
||||||
|
*
|
||||||
|
* @param pUrlRequest
|
||||||
|
* The url request.
|
||||||
|
* @param pMethodRequest
|
||||||
|
* 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 result = false;
|
||||||
|
|
||||||
|
for(final Route route : getRoutes()) {
|
||||||
|
/*
|
||||||
|
* 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) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
103
src/main/java/org/codiki/entities/dto/UserDAO.java
Normal file
103
src/main/java/org/codiki/entities/dto/UserDAO.java
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
package org.codiki.entities.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.codiki.entities.persistence.Role;
|
||||||
|
import org.codiki.entities.persistence.User;
|
||||||
|
|
||||||
|
public class UserDAO {
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String image;
|
||||||
|
|
||||||
|
private Date inscriptionDate;
|
||||||
|
|
||||||
|
private Role role;
|
||||||
|
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
public UserDAO() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserDAO(final User pUser) {
|
||||||
|
key = pUser.getKey();
|
||||||
|
name = pUser.getName();
|
||||||
|
email = pUser.getEmail();
|
||||||
|
image = pUser.getImage();
|
||||||
|
inscriptionDate = pUser.getInscriptionDate();
|
||||||
|
role = pUser.getRole();
|
||||||
|
token = pUser.getToken().getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImage() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImage(String image) {
|
||||||
|
this.image = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getInscriptionDate() {
|
||||||
|
return inscriptionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInscriptionDate(Date inscriptionDate) {
|
||||||
|
this.inscriptionDate = inscriptionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Role getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRole(Role role) {
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(String token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
}
|
||||||
78
src/main/java/org/codiki/entities/persistence/Category.java
Normal file
78
src/main/java/org/codiki/entities/persistence/Category.java
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package org.codiki.entities.persistence;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Inheritance;
|
||||||
|
import javax.persistence.InheritanceType;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="category")
|
||||||
|
@Inheritance(strategy = InheritanceType.JOINED)
|
||||||
|
public class Category implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Attributes */
|
||||||
|
/* ******************* */
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Relations */
|
||||||
|
/* ******************* */
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "creator_id")
|
||||||
|
protected User creator;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "mainCategory")
|
||||||
|
private List<SubCategory> listSubCategories;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "category")
|
||||||
|
protected List<Post> listPosts;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Getters & Setters */
|
||||||
|
/* ******************* */
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
if(this.id != null) {
|
||||||
|
throw new IllegalAccessError("It's not allowed to rewrite the id entity.");
|
||||||
|
}
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getCreator() {
|
||||||
|
return creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreator(User creator) {
|
||||||
|
this.creator = creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SubCategory> getListSubCategories() {
|
||||||
|
return listSubCategories;
|
||||||
|
}
|
||||||
|
}
|
||||||
102
src/main/java/org/codiki/entities/persistence/Comment.java
Normal file
102
src/main/java/org/codiki/entities/persistence/Comment.java
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package org.codiki.entities.persistence;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="comment")
|
||||||
|
public class Comment implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Attributes */
|
||||||
|
/* ******************* */
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
@Column(name = "creation_date")
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date creationDate;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Relations */
|
||||||
|
/* ******************* */
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "author")
|
||||||
|
private User author;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "comment")
|
||||||
|
private List<CommentHistory> history;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Getters & Setters */
|
||||||
|
/* ******************* */
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
if(this.id != null) {
|
||||||
|
throw new IllegalAccessError("It's not allowed to rewrite the id entity.");
|
||||||
|
}
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreationDate() {
|
||||||
|
return creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreationDate(Date creationDate) {
|
||||||
|
this.creationDate = creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthor(User author) {
|
||||||
|
this.author = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CommentHistory> getHistory() {
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHistory(List<CommentHistory> history) {
|
||||||
|
this.history = history;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package org.codiki.entities.persistence;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="comment_history")
|
||||||
|
public class CommentHistory implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Attributes */
|
||||||
|
/* ******************* */
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Relations */
|
||||||
|
/* ******************* */
|
||||||
|
@Column(name = "update_date")
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date updateDate;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "comment_id")
|
||||||
|
private Comment comment;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Getters & Setters */
|
||||||
|
/* ******************* */
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
if(this.id != null) {
|
||||||
|
throw new IllegalAccessError("It's not allowed to rewrite the id entity.");
|
||||||
|
}
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getUpdateDate() {
|
||||||
|
return updateDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdateDate(Date updateDate) {
|
||||||
|
this.updateDate = updateDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Comment getComment() {
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setComment(Comment comment) {
|
||||||
|
this.comment = comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
72
src/main/java/org/codiki/entities/persistence/Image.java
Normal file
72
src/main/java/org/codiki/entities/persistence/Image.java
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package org.codiki.entities.persistence;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="image")
|
||||||
|
public class Image implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Attributes */
|
||||||
|
/* ******************* */
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String link;
|
||||||
|
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date date;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "user_id")
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Getters & Setters */
|
||||||
|
/* ******************* */
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLink() {
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLink(String link) {
|
||||||
|
this.link = link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(Date date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
177
src/main/java/org/codiki/entities/persistence/Post.java
Normal file
177
src/main/java/org/codiki/entities/persistence/Post.java
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
package org.codiki.entities.persistence;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
import org.codiki.utils.DateUtils;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="post")
|
||||||
|
public class Post implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** Number of character that compose the text extract. */
|
||||||
|
private static final short EXTRACT_LENGTH = 250;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Attributes */
|
||||||
|
/* ******************* */
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
@Column(length = 250)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private String image;
|
||||||
|
|
||||||
|
@Column(name = "creation_date")
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date creationDate;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Relations */
|
||||||
|
/* ******************* */
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "creator_id")
|
||||||
|
private User author;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "category_id")
|
||||||
|
private Category category;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "post", cascade = CascadeType.REMOVE)
|
||||||
|
private List<PostHistory> history;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Constructors */
|
||||||
|
/* ******************* */
|
||||||
|
public Post() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Getters & Setters */
|
||||||
|
/* ******************* */
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
if(this.id != null) {
|
||||||
|
throw new IllegalAccessError("It's not allowed to rewrite the id entity.");
|
||||||
|
}
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImage() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImage(String image) {
|
||||||
|
this.image = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreationDate() {
|
||||||
|
return creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreationDate(Date creationDate) {
|
||||||
|
this.creationDate = creationDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCreationDateStr() {
|
||||||
|
if(creationDate == null) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return DateUtils.format(creationDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTextExtract() {
|
||||||
|
String extract = text;
|
||||||
|
|
||||||
|
if(extract != null && extract.length() > EXTRACT_LENGTH) {
|
||||||
|
extract = extract.substring(0, EXTRACT_LENGTH) + "...";
|
||||||
|
}
|
||||||
|
|
||||||
|
return extract;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getAuthor() {
|
||||||
|
return author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthor(User author) {
|
||||||
|
this.author = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Category getCategory() {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategory(Category category) {
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PostHistory> getHistory() {
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHistory(List<PostHistory> history) {
|
||||||
|
this.history = history;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package org.codiki.entities.persistence;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="post_history")
|
||||||
|
public class PostHistory implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
@Column(name = "update_date")
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date updateDate;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "post_id")
|
||||||
|
private Post post;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
if(this.id != null) {
|
||||||
|
throw new IllegalAccessError("It's not allowed to rewrite the id entity.");
|
||||||
|
}
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getUpdateDate() {
|
||||||
|
return updateDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdateDate(Date updateDate) {
|
||||||
|
this.updateDate = updateDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Post getPost() {
|
||||||
|
return post;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPost(Post post) {
|
||||||
|
this.post = post;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
38
src/main/java/org/codiki/entities/persistence/Role.java
Normal file
38
src/main/java/org/codiki/entities/persistence/Role.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package org.codiki.entities.persistence;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="role")
|
||||||
|
public class Role implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package org.codiki.entities.persistence;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "sub_category")
|
||||||
|
public class SubCategory extends Category {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Relations */
|
||||||
|
/* ******************* */
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "main_category")
|
||||||
|
private Category mainCategory;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Getters & Setters */
|
||||||
|
/* ******************* */
|
||||||
|
public Category getMainCategory() {
|
||||||
|
return mainCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMainCategory(Category mainCategory) {
|
||||||
|
this.mainCategory = mainCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Post> getListPosts() {
|
||||||
|
return listPosts;
|
||||||
|
}
|
||||||
|
}
|
||||||
188
src/main/java/org/codiki/entities/persistence/User.java
Normal file
188
src/main/java/org/codiki/entities/persistence/User.java
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
package org.codiki.entities.persistence;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.CascadeType;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.SequenceGenerator;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
|
import org.codiki.entities.security.Token;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name="`user`")
|
||||||
|
public class User implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Attributes */
|
||||||
|
/* ******************* */
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="user_id_seq")
|
||||||
|
@SequenceGenerator(name="user_id_seq", sequenceName="user_id_seq", allocationSize=1)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String image;
|
||||||
|
|
||||||
|
@Column(name = "inscription_date")
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private Date inscriptionDate;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Relations */
|
||||||
|
/* ******************* */
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "role_id")
|
||||||
|
private Role role;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "author")
|
||||||
|
private List<Post> listPosts;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "author")
|
||||||
|
private List<Comment> listComments;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
|
||||||
|
private List<Image> listImages;
|
||||||
|
|
||||||
|
/** Authentication token. */
|
||||||
|
private transient Token token;
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Constructors */
|
||||||
|
/* ******************* */
|
||||||
|
public User() {
|
||||||
|
super();
|
||||||
|
token = new Token();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ******************* */
|
||||||
|
/* Getters & Setters */
|
||||||
|
/* ******************* */
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
if(this.id != null) {
|
||||||
|
throw new IllegalAccessError("It's not allowed to rewrite the id entity.");
|
||||||
|
}
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImage() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImage(String image) {
|
||||||
|
this.image = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getInscriptionDate() {
|
||||||
|
return inscriptionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInscriptionDate(Date inscriptionDate) {
|
||||||
|
this.inscriptionDate = inscriptionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Role getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRole(Role role) {
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Post> getListPosts() {
|
||||||
|
return listPosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListPosts(List<Post> listPosts) {
|
||||||
|
this.listPosts = listPosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Comment> getListComments() {
|
||||||
|
return listComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListComments(List<Comment> listComments) {
|
||||||
|
this.listComments = listComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Image> getListImages() {
|
||||||
|
return listImages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addImage(final Image pImage) {
|
||||||
|
if(listImages == null) {
|
||||||
|
listImages = new ArrayList<>();
|
||||||
|
}
|
||||||
|
listImages.add(pImage);
|
||||||
|
|
||||||
|
if(pImage.getUser() == null) {
|
||||||
|
pImage.setUser(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListImages(List<Image> listImages) {
|
||||||
|
this.listImages = listImages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Token getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
82
src/main/java/org/codiki/entities/security/Token.java
Normal file
82
src/main/java/org/codiki/entities/security/Token.java
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package org.codiki.entities.security;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
public class Token {
|
||||||
|
/** The metric in which the validation delay is defined. */
|
||||||
|
private static final int METRIC = Calendar.MINUTE;
|
||||||
|
/** Number of {@link METRIC} after that the token become invalid. */
|
||||||
|
private static final int DELAY = 30;
|
||||||
|
|
||||||
|
/** The Constant BITS_NUMBER. */
|
||||||
|
private static final int BITS_NUMBER = 130;
|
||||||
|
/** The Constant RADIX. */
|
||||||
|
private static final int RADIX = 32;
|
||||||
|
|
||||||
|
/** The value. */
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Last access date. For each request to the server, this date is consulted
|
||||||
|
* and if the valid delay is ok, this date must be updated.
|
||||||
|
*/
|
||||||
|
private Calendar lastAccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new token.
|
||||||
|
*/
|
||||||
|
public Token() {
|
||||||
|
super();
|
||||||
|
value = new BigInteger(BITS_NUMBER, new SecureRandom()).toString(RADIX);
|
||||||
|
lastAccess = Calendar.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value.
|
||||||
|
*
|
||||||
|
* @return the value
|
||||||
|
*/
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the last access date.
|
||||||
|
*
|
||||||
|
* @return the last access date
|
||||||
|
*/
|
||||||
|
public Calendar getLastAccess() {
|
||||||
|
return lastAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the last access date.
|
||||||
|
*/
|
||||||
|
public void setLastAccess() {
|
||||||
|
lastAccess = Calendar.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate if the token is still valid.<br/>
|
||||||
|
* A token is valid is its {@link Token#lastAccess} is after the current
|
||||||
|
* date minus the {@link Token#DELAY} {@link Token#METRIC}.<br/>
|
||||||
|
* <br/>
|
||||||
|
* Example:<br/>
|
||||||
|
* {@link Token#DELAY} = 30 and {@link Token#METRIC} =
|
||||||
|
* {@link Calendar#MINUTE}.<br/>
|
||||||
|
* A token is valid only on the 30 minutes after its
|
||||||
|
* {@link Token#lastAccess}.<br/>
|
||||||
|
* If the current date-time minus the 30 minutes is before the
|
||||||
|
* {@link Token#lastAccess}, the token is still valid.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the token is still valid, {@code false}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isValid() {
|
||||||
|
final Calendar lastTimeValidation = Calendar.getInstance();
|
||||||
|
lastTimeValidation.add(METRIC, -DELAY);
|
||||||
|
return lastAccess.getTime().after(lastTimeValidation.getTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/main/java/org/codiki/login/LoginController.java
Normal file
37
src/main/java/org/codiki/login/LoginController.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
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.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/account")
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
private static final String HEADER_TOKEN = "token";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenService tokenService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LoginService loginService;
|
||||||
|
|
||||||
|
@PostMapping("/login")
|
||||||
|
public UserDAO login(@RequestBody UserDAO pUser, HttpServletResponse response) {
|
||||||
|
return loginService.checkCredentials(response, pUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/logout")
|
||||||
|
public void logout(HttpServletRequest pRequest) {
|
||||||
|
tokenService.removeUser(pRequest.getHeader(HEADER_TOKEN));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
50
src/main/java/org/codiki/login/LoginService.java
Normal file
50
src/main/java/org/codiki/login/LoginService.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package org.codiki.login;
|
||||||
|
|
||||||
|
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.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class LoginService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenService tokenService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the user credentials and generate him a token if they are correct.
|
||||||
|
*
|
||||||
|
* @param pUser
|
||||||
|
* The user sent from client.
|
||||||
|
* @return The user populated with the generated token.
|
||||||
|
* @throws AuthenticationException
|
||||||
|
* If the credentials are wrong.
|
||||||
|
*/
|
||||||
|
public UserDAO checkCredentials(HttpServletResponse pResponse, UserDAO pUser) {
|
||||||
|
UserDAO result = null;
|
||||||
|
|
||||||
|
Optional<User> user = userRepository.findByEmail(pUser.getEmail());
|
||||||
|
|
||||||
|
if(user.isPresent() && StringUtils.compareHash(pUser.getPassword(), user.get().getPassword())) {
|
||||||
|
tokenService.addUser(user.get());
|
||||||
|
result = new UserDAO(user.get());
|
||||||
|
} else {
|
||||||
|
pResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
13
src/main/java/org/codiki/repositories/UserRepository.java
Normal file
13
src/main/java/org/codiki/repositories/UserRepository.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package org.codiki.repositories;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.codiki.entities.persistence.User;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface UserRepository extends CrudRepository<User, Long> {
|
||||||
|
Optional<User> findByEmail(@Param("email") final String pEmail);
|
||||||
|
}
|
||||||
35
src/main/java/org/codiki/security/AuthenticationFilter.java
Normal file
35
src/main/java/org/codiki/security/AuthenticationFilter.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package org.codiki.security;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.codiki.core.AbstractFilter;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||||
|
public class AuthenticationFilter extends AbstractFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Route> getRoutes() {
|
||||||
|
return Arrays.asList(
|
||||||
|
new Route("\\/api\\/account\\/.*")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void filter(HttpServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
|
System.out.println("Token : " + request.getHeader("token"));
|
||||||
|
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
69
src/main/java/org/codiki/security/Route.java
Normal file
69
src/main/java/org/codiki/security/Route.java
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package org.codiki.security;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route for filter matching.
|
||||||
|
*
|
||||||
|
* @author Takiguchi
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instanciate a vierge route.
|
||||||
|
*/
|
||||||
|
public Route() {
|
||||||
|
super();
|
||||||
|
url = "";
|
||||||
|
method = Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instanciate a route for all http methods.
|
||||||
|
*
|
||||||
|
* @param pUrl
|
||||||
|
* The regex to match urls.
|
||||||
|
*/
|
||||||
|
public Route(final String pUrl) {
|
||||||
|
this();
|
||||||
|
this.url = pUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instanciate a route for methods given in parameters
|
||||||
|
*
|
||||||
|
* @param pUrl
|
||||||
|
* The regex to match urls.
|
||||||
|
* @param pMethod
|
||||||
|
* The http method to match. Use a {@link Optional#empty()} to match
|
||||||
|
* all methods.
|
||||||
|
*/
|
||||||
|
public Route(final String pUrl, final HttpMethod pMethod) {
|
||||||
|
this(pUrl);
|
||||||
|
this.method = Optional.of(pMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<HttpMethod> getMethod() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMethod(HttpMethod method) {
|
||||||
|
this.method = Optional.of(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
106
src/main/java/org/codiki/security/TokenService.java
Normal file
106
src/main/java/org/codiki/security/TokenService.java
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package org.codiki.security;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.codiki.entities.persistence.User;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class TokenService {
|
||||||
|
/** Map of connected users. */
|
||||||
|
private static final Map<String, User> connectedUsers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
connectedUsers = new TreeMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the token matches to a user session, and if it is still valid.
|
||||||
|
*
|
||||||
|
* @param pToken
|
||||||
|
* The token to check.
|
||||||
|
* @return {@code true} if the token is still valid, {@code false}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isUserConnected(final String pToken) {
|
||||||
|
boolean result = false;
|
||||||
|
|
||||||
|
if (pToken != null && connectedUsers.containsKey(pToken)) {
|
||||||
|
if (connectedUsers.get(pToken).getToken().isValid()) {
|
||||||
|
result = true;
|
||||||
|
} else {
|
||||||
|
connectedUsers.remove(pToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear all the expired sessions
|
||||||
|
clearExpiredUsers();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove from the connected users map all the elements which their token is
|
||||||
|
* expired.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unlikely-arg-type")
|
||||||
|
private void clearExpiredUsers() {
|
||||||
|
connectedUsers.entrySet().stream().forEach(user -> {
|
||||||
|
if(!user.getValue().getToken().isValid()) {
|
||||||
|
connectedUsers.remove(user).getKey();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the user to the connected users map.
|
||||||
|
*
|
||||||
|
* @param pUser
|
||||||
|
* The user to add.
|
||||||
|
*/
|
||||||
|
public void addUser(final User pUser) {
|
||||||
|
if(connectedUsers.get(pUser.getToken().getValue()) == null) {
|
||||||
|
connectedUsers.put(pUser.getToken().getValue(), pUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the user token last access date in the token service.
|
||||||
|
*
|
||||||
|
* @param pToken
|
||||||
|
* The user token.
|
||||||
|
*/
|
||||||
|
public void refreshUserToken(final String pToken) {
|
||||||
|
final User user = connectedUsers.get(pToken);
|
||||||
|
if(user != null) {
|
||||||
|
user.getToken().setLastAccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the user to the connected users map.
|
||||||
|
*
|
||||||
|
* @param pUser
|
||||||
|
* The user to remove.
|
||||||
|
*/
|
||||||
|
public void removeUser(final User pUser) {
|
||||||
|
removeUser(pUser.getToken().getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the user associated to the token given in parameters, from the
|
||||||
|
* connected users map.
|
||||||
|
*
|
||||||
|
* @param pToken
|
||||||
|
* The user to delete token.
|
||||||
|
*/
|
||||||
|
public void removeUser(final String pToken) {
|
||||||
|
if(pToken != null && connectedUsers.containsKey(pToken)) {
|
||||||
|
connectedUsers.remove(pToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/main/java/org/codiki/utils/DateUtils.java
Normal file
35
src/main/java/org/codiki/utils/DateUtils.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package org.codiki.utils;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class DateUtils {
|
||||||
|
public static final String FORMAT_DEFAULT = "dd/MM/yyyy HH:mm:ss";
|
||||||
|
|
||||||
|
public static Date parseDate(String pSource, String pPattern) throws ParseException {
|
||||||
|
Date result = null;
|
||||||
|
if (pSource != null && !pSource.isEmpty()) {
|
||||||
|
DateFormat formatter = getSimpleDateFormat(pPattern);
|
||||||
|
formatter.setLenient(false);
|
||||||
|
result = formatter.parse(pSource);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String format(Date pDate, String pPattern) {
|
||||||
|
return getSimpleDateFormat(pPattern).format(pDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String format(Date pDate) {
|
||||||
|
return getSimpleDateFormat(FORMAT_DEFAULT).format(pDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SimpleDateFormat getSimpleDateFormat(String pPattern) {
|
||||||
|
SimpleDateFormat result = new SimpleDateFormat(pPattern, Locale.FRENCH);
|
||||||
|
result.setLenient(false);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
82
src/main/java/org/codiki/utils/RegexUtils.java
Normal file
82
src/main/java/org/codiki/utils/RegexUtils.java
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package org.codiki.utils;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public final class RegexUtils {
|
||||||
|
|
||||||
|
private static final String EMAIL_REGEX = "^.*@.*\\..{2,}$";
|
||||||
|
private static final String LOWER_LETTERS_REGEX = ".*[a-z].*";
|
||||||
|
private static final String UPPER_LETTERS_REGEX = ".*[A-Z].*";
|
||||||
|
private static final String NUMBER_REGEX = ".*[0-9].*";
|
||||||
|
private static final String SPECIAL_CHAR_REGEX = ".*\\W.*";
|
||||||
|
private static final String NUMBER_ONLY_REGEX = "^[0-9]+$";
|
||||||
|
|
||||||
|
// La portée "package" permet à la classe StringUtils d'utiliser les patterns
|
||||||
|
// suivants :
|
||||||
|
static final Pattern EMAIL_PATTERN;
|
||||||
|
static final Pattern LOWER_LETTERS_PATTERN;
|
||||||
|
static final Pattern UPPER_LETTERS_PATTERN;
|
||||||
|
static final Pattern NUMBER_PATTERN;
|
||||||
|
static final Pattern SPECIAL_CHAR_PATTERN;
|
||||||
|
static final Pattern NUMBER_ONLY_PATTERN;
|
||||||
|
|
||||||
|
static {
|
||||||
|
EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX);
|
||||||
|
LOWER_LETTERS_PATTERN = Pattern.compile(LOWER_LETTERS_REGEX);
|
||||||
|
UPPER_LETTERS_PATTERN = Pattern.compile(UPPER_LETTERS_REGEX);
|
||||||
|
NUMBER_PATTERN = Pattern.compile(NUMBER_REGEX);
|
||||||
|
SPECIAL_CHAR_PATTERN = Pattern.compile(SPECIAL_CHAR_REGEX);
|
||||||
|
NUMBER_ONLY_PATTERN = Pattern.compile(NUMBER_ONLY_REGEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chekcs if {@code pString} corresponds to an email address.
|
||||||
|
*
|
||||||
|
* @param pString
|
||||||
|
* The string which should be an email address.
|
||||||
|
* @return {@code true} if {@link pString} corresponds to an email address,
|
||||||
|
* {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean isEmail(final String pString) {
|
||||||
|
return EMAIL_PATTERN.matcher(pString).find();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the sequences of {@code pString} matched by the {@code pRegex}
|
||||||
|
* with the {@code pReplacingString}.
|
||||||
|
*
|
||||||
|
* @param pString
|
||||||
|
* The string to update.
|
||||||
|
* @param pRegex
|
||||||
|
* The regex to match the sentences to replace.
|
||||||
|
* @param pReplacingString
|
||||||
|
* The string to replace the sentences which match with the
|
||||||
|
* regex.
|
||||||
|
* @return The new string.
|
||||||
|
*/
|
||||||
|
public static String replaceSequence(final String pString,
|
||||||
|
final String pRegex, final String pReplacingString) {
|
||||||
|
return Pattern.compile(pRegex).matcher(pString)
|
||||||
|
.replaceAll(pReplacingString);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if {@code pString} corresponds to a number.
|
||||||
|
*
|
||||||
|
* @param pString
|
||||||
|
* The string which should be a number.
|
||||||
|
* @return {@code true} if {@code pString} corresponds to a number,
|
||||||
|
* {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean isNumber(final String pString) {
|
||||||
|
return NUMBER_ONLY_PATTERN.matcher(pString).find();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getGroup(final String regex, final int numeroGroupe, final String chaine) {
|
||||||
|
final Pattern pattern = Pattern.compile(regex);
|
||||||
|
final Matcher matcher = pattern.matcher(chaine);
|
||||||
|
matcher.find();
|
||||||
|
return matcher.group(numeroGroupe);
|
||||||
|
}
|
||||||
|
}
|
||||||
93
src/main/java/org/codiki/utils/StringUtils.java
Normal file
93
src/main/java/org/codiki/utils/StringUtils.java
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
package org.codiki.utils;
|
||||||
|
|
||||||
|
import org.mindrot.jbcrypt.BCrypt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic methods about {@link String} class.
|
||||||
|
*
|
||||||
|
* @author takiguchi
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class StringUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate if {@code pString} is null or just composed of spaces.
|
||||||
|
*
|
||||||
|
* @param pString
|
||||||
|
* The string to test.
|
||||||
|
* @return {@code true} if {@code pString} is null or just composed of
|
||||||
|
* spaces, {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean isNull(final String chaine) {
|
||||||
|
return chaine == null || chaine.trim().length() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash the password given into parameters.
|
||||||
|
*
|
||||||
|
* @param pPassword The password to hash.
|
||||||
|
* @return The password hashed.
|
||||||
|
*/
|
||||||
|
public static String hashPassword(final String pPassword) {
|
||||||
|
return hashString(pPassword, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String hashString(final String pString, final int pSalt) {
|
||||||
|
return BCrypt.hashpw(pString, BCrypt.gensalt(pSalt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare the password and the hashed string given into parameters.
|
||||||
|
*
|
||||||
|
* @param pPassword
|
||||||
|
* The password to compare to the hashed string.
|
||||||
|
* @param pHashToCompare
|
||||||
|
* The hashed string to compare to the password.
|
||||||
|
* @return {@code true} if the password matches to the hashed string.
|
||||||
|
*/
|
||||||
|
public static boolean compareHash(final String pPassword, final String pHashToCompare) {
|
||||||
|
return BCrypt.checkpw(pPassword, pHashToCompare);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concatenate the parameters to form just one single string.
|
||||||
|
*
|
||||||
|
* @param pArgs
|
||||||
|
* The strings to concatenate.
|
||||||
|
* @return The parameters concatenated.
|
||||||
|
*/
|
||||||
|
public static String concat(final Object... pArgs) {
|
||||||
|
final StringBuilder result = new StringBuilder();
|
||||||
|
for (final Object arg : pArgs) {
|
||||||
|
result.append(arg);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String printStrings(final String... pStrings) {
|
||||||
|
final StringBuilder result = new StringBuilder();
|
||||||
|
for (int i = 0 ; i < pStrings.length ; i++) {
|
||||||
|
result.append(pStrings[i]);
|
||||||
|
if(i < pStrings.length - 1) {
|
||||||
|
result.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean containLowercase(final String pString) {
|
||||||
|
return RegexUtils.LOWER_LETTERS_PATTERN.matcher(pString).find();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean containUppercase(final String pString) {
|
||||||
|
return RegexUtils.UPPER_LETTERS_PATTERN.matcher(pString).find();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean containNumber(final String pString) {
|
||||||
|
return RegexUtils.NUMBER_PATTERN.matcher(pString).find();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean containSpecialChar(final String pString) {
|
||||||
|
return RegexUtils.SPECIAL_CHAR_PATTERN.matcher(pString).find();
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/main/resources/application.properties
Normal file
15
src/main/resources/application.properties
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#server.error.whitelabel.enabled=false
|
||||||
|
spring.datasource.driverClassName=org.postgresql.Driver
|
||||||
|
spring.datasource.url=jdbc:postgresql://localhost:5432/codiki
|
||||||
|
spring.datasource.username=codiki
|
||||||
|
spring.datasource.password=P@ssword
|
||||||
|
|
||||||
|
# Disable feature detection by this undocumented parameter. Check the org.hibernate.engine.jdbc.internal.JdbcServiceImpl.configure method for more details.
|
||||||
|
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
|
||||||
|
|
||||||
|
# Because detection is disabled you have to set correct dialect by hand.
|
||||||
|
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
|
||||||
|
|
||||||
|
logging.level.org.hibernate=DEBUG
|
||||||
|
|
||||||
|
cors.enabled=false
|
||||||
72
src/test/java/org/codiki/core/AbstractFilterTest.java
Normal file
72
src/test/java/org/codiki/core/AbstractFilterTest.java
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package org.codiki.core;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.codiki.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;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class AbstractFilterTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that simplify the test mocks for the method {@link AbstractFilter#getRoutes()}.
|
||||||
|
*
|
||||||
|
* @author Takiguchi
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class TestFilter extends AbstractFilter {
|
||||||
|
public List<Route> routes;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Route> getRoutes() {
|
||||||
|
return routes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void filter(HttpServletRequest request, ServletResponse response, FilterChain chain)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tested class object */
|
||||||
|
private AbstractFilter filter = new TestFilter();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_isRequestFiltered_true() {
|
||||||
|
((TestFilter) filter).routes = Arrays.asList(new Route("toto", HttpMethod.GET));
|
||||||
|
|
||||||
|
Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "GET"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_isRequestFiltered_true_without_httpMethod() {
|
||||||
|
((TestFilter) filter).routes = Arrays.asList(new Route("toto"));
|
||||||
|
|
||||||
|
Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "GET"));
|
||||||
|
Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "POST"));
|
||||||
|
Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "PUT"));
|
||||||
|
Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "DELETE"));
|
||||||
|
Assert.assertTrue(filter.isRequestFiltered("http://localhost/toto", "DumbThing"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_isRequestFiltered_false() {
|
||||||
|
((TestFilter) filter).routes = Arrays.asList(new Route("toto", HttpMethod.POST));
|
||||||
|
|
||||||
|
Assert.assertFalse(filter.isRequestFiltered("http://localhost/toto", "GET"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user