diff --git a/batch-files/redis-cache/start-local-redis-stack.bat b/batch-files/redis-cache/start-local-redis-stack.bat
new file mode 100644
index 00000000..57bb43a5
--- /dev/null
+++ b/batch-files/redis-cache/start-local-redis-stack.bat
@@ -0,0 +1 @@
+docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
\ No newline at end of file
diff --git a/code/gms-backend/pom.xml b/code/gms-backend/pom.xml
index d3cc71eb..594cf43b 100644
--- a/code/gms-backend/pom.xml
+++ b/code/gms-backend/pom.xml
@@ -1,657 +1,667 @@
-
- 4.0.0
-
- io.github.gms
- give-my-secret
- 1.0.0-SNAPSHOT
-
- gms-backend
-
- 21
- 21
- 21
- UTF-8
- gms-app
- 3.2.0
- 32.0.0-jre
- 3.0.0-M4
- 9.8.1
-
- 5.8.2
- 4.6.1
- 0.8.11
- false
- 0.90
- peter-szrnka
- https://sonarcloud.io
- **/enums/**,
- **/abstraction/**,
- **/dto/**,
- **/model/**,
- **/config/**,
- **/entity/**,
- **/util/**,
- **/exception/**,
- **/types/**,
- **/event/**,
- **/*Entity.java,
- **/*Application.java
-
- true
-
-
-
- szrnka.peter@gmail.com
- Péter Szrnka
- https://github.com/peter-szrnka
-
- Architect
- Technical lead
- Developer
-
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-dependencies
- ${spring-boot.version}
- pom
- import
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.yaml
- snakeyaml
-
-
-
-
- org.springframework.boot
- spring-boot-starter-security
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
-
- org.springframework.boot
- spring-boot-starter-data-ldap
-
-
- org.springframework.boot
- spring-boot-starter-aop
-
-
- org.springframework.boot
- spring-boot-starter-cache
-
-
- org.springframework.boot
- spring-boot-starter-data-redis
-
-
- jakarta.persistence
- jakarta.persistence-api
-
-
- jakarta.servlet
- jakarta.servlet-api
-
-
+
+ 4.0.0
+
+ io.github.gms
+ give-my-secret
+ 1.0.0-SNAPSHOT
+
+ gms-backend
+
+ 21
+ 21
+ 21
+ UTF-8
+ gms-app
+ 3.2.0
+ 32.0.0-jre
+ 3.0.0-M4
+ 9.22.3
+
+ 5.9.2
+ 5.2.0
+ 0.8.9
+ false
+ 0.90
+ peter-szrnka
+ https://sonarcloud.io
+ **/enums/**,
+ **/abstraction/**,
+ **/dto/**,
+ **/model/**,
+ **/config/**,
+ **/entity/**,
+ **/util/**,
+ **/exception/**,
+ **/types/**,
+ **/event/**,
+ **/*Entity.java,
+ **/*Application.java
+
+ true
+
+
+
+ szrnka.peter@gmail.com
+ Péter Szrnka
+ https://github.com/peter-szrnka
+
+ Architect
+ Technical lead
+ Developer
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.yaml
+ snakeyaml
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-data-ldap
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+ org.springframework.boot
+ spring-boot-starter-cache
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+ jakarta.persistence
+ jakarta.persistence-api
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+
+
ch.qos.logback
logback-classic
1.4.12
-
- ch.qos.logback
- logback-core
- 1.4.12
-
-
-
- org.springframework.ldap
- spring-ldap-core
- 3.2.0
-
-
- com.unboundid
- unboundid-ldapsdk
- 6.0.10
-
-
- org.springframework.boot
- spring-boot-devtools
- true
- runtime
-
-
- org.springframework
- spring-context-indexer
- true
-
-
-
- org.mariadb.jdbc
- mariadb-java-client
-
-
- com.mysql
- mysql-connector-j
-
+
+ ch.qos.logback
+ logback-core
+ 1.4.12
+
+
+
+ org.springframework.ldap
+ spring-ldap-core
+ 3.2.0
+
+
+ com.unboundid
+ unboundid-ldapsdk
+ 6.0.10
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+ runtime
+
+
+ org.springframework
+ spring-context-indexer
+ true
+
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+
+
+ com.mysql
+ mysql-connector-j
+
-
- org.postgresql
- postgresql
-
-
- com.microsoft.sqlserver
- mssql-jdbc
-
-
- com.oracle.database.jdbc
- ojdbc10
- 19.16.0.0
-
-
- org.flywaydb
- flyway-core
- ${flyway.version}
-
-
- org.flywaydb
- flyway-mysql
- ${flyway.version}
-
-
- org.flywaydb
- flyway-sqlserver
- ${flyway.version}
-
-
-
- org.yaml
- snakeyaml
- 2.0
-
-
- org.bouncycastle
- bcprov-jdk18on
- 1.76
-
-
- org.bouncycastle
- bcpkix-jdk18on
- 1.76
-
-
- io.jsonwebtoken
- jjwt-api
- 0.11.1
-
-
- io.jsonwebtoken
- jjwt-impl
- 0.11.1
- runtime
-
-
- io.jsonwebtoken
- jjwt-jackson
- 0.11.1
- runtime
-
-
- org.projectlombok
- lombok
- 1.18.30
-
-
- com.google.guava
- guava
- ${guava.version}
-
-
- dev.samstevens.totp
- totp
- 1.7.1
-
-
-
- com.h2database
- h2
- test
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.junit.jupiter
- junit-jupiter-engine
- ${junit.jupiter.version}
- test
-
-
- org.junit.jupiter
- junit-jupiter-api
- ${junit.jupiter.version}
- test
-
-
- org.junit.jupiter
- junit-jupiter-params
- ${junit.jupiter.version}
- test
-
-
- org.mockito
- mockito-core
- ${mockito.version}
- test
-
-
- org.mockito
- mockito-junit-jupiter
- ${mockito.version}
- test
-
-
- org.mockito
- mockito-inline
- ${mockito.version}
- test
-
-
- org.assertj
- assertj-core
- test
-
-
-
-
- default
-
- true
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
-
- ${java.version}
-
- -parameters
-
-
-
-
- org.apache.maven.plugins
- maven-checkstyle-plugin
- 3.1.1
-
- UTF-8
- src/main/resources/checkstyle.xml
- true
- true
- true
- true
- true
- true
-
-
-
- validate
- clean
-
- check
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
- ${spring-boot.version}
-
-
- build-info
-
- build-info
-
-
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- ${maven-surefire-plugin.version}
-
- !IntegrationTest,!SecurityTest
-
-
-
-
-
-
- codecov
-
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- ${maven-surefire-plugin.version}
-
- true
-
-
-
- org.jacoco
- jacoco-maven-plugin
- ${jacoco-maven-plugin.version}
-
- ${skip.jacoco-check-execution}
-
- **/*Application.class
- **/**/DemoDataProviderService.class
- **/Abstract*.class
- **/**/*Exception.class
- **/TestDataProviderService.class
- **/model/*.class
- **/config/*.class
- **/dto/*.class
- **/enums/*.class
- **/entity/*.class
- **/types/*.class
- **/event/*.class
-
-
-
-
-
- prepare-agent
-
-
-
- jacoco-report
- package
-
- report
-
-
-
- jacoco-check
- test
-
- check
-
-
- ${skip.jacoco-check-execution}
-
-
- BUNDLE
-
-
- INSTRUCTION
- COVEREDRATIO
- ${test.minimum.coverage}
-
-
- BRANCH
- COVEREDRATIO
- ${test.minimum.coverage}
-
-
-
-
-
-
-
-
-
-
-
-
- mutation-test
-
- false
-
-
-
-
- org.pitest
- pitest-maven
- 1.7.3
-
-
- pit-report
- test
-
- mutationCoverage
-
-
-
-
-
- org.pitest
- pitest-junit5-plugin
- 0.15
-
-
-
- 95
- 95
- 2
-
- io.github.gms.*
-
-
- io.github.gms.*
-
-
- *.*Application
- *.*Config
- *.*Dto
- *.*Entity
- *.config.*
- *.dto.*
- *.entity.*
- *.enums.*
- *.event.*
- *.exception.*
- *.model.*
- *.repository.*
-
-
- io.github.gms.**IntegrationTest
-
-
- java.util.logging
- org.apache.log4j
- org.slf4j
- org.apache.commons.logging
-
-
-
-
-
-
-
- build-prod
-
- false
-
-
- gms-app
-
-
-
- maven-resources-plugin
- 3.0.2
-
-
- copy-javascript-resources
- prepare-package
-
- copy-resources
-
-
- ${basedir}/target/classes/static
-
-
- ${basedir}/../gms-frontend/dist/gms-frontend
- false
-
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
- ${spring-boot.version}
-
- io.github.gms.GmsApplication
-
-
-
-
- repackage
-
-
-
- build-info
-
- build-info
-
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
- 3.1.0
-
-
-
-
-
- build-prod-docker-image-local
-
- false
-
-
- gms-app
-
-
- maven-resources-plugin
- 3.0.2
-
-
- copy-javascript-resources
- prepare-package
-
- copy-resources
-
-
- ${basedir}/target/classes/static
-
-
- ${basedir}/../gms-frontend/dist/gms-frontend
- false
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
-
- ${java.version}
-
-
-
- io.github.gms
- gms-frontend
- 0.0.1-SNAPSHOT
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
- ${spring-boot.version}
-
- io.github.gms.GmsApplication
-
-
-
-
- repackage
-
-
-
- build-info
-
- build-info
-
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
- 3.1.0
-
-
- org.apache.maven.plugins
- maven-surefire-plugin
- ${maven-surefire-plugin.version}
-
- true
-
-
-
- com.spotify
- dockerfile-maven-plugin
-
- false
- gms-app-local
- latest
- gms-app-local
-
- target/${project.build.finalName}.jar
-
-
-
-
- default
-
- build
-
-
-
-
-
-
-
-
+
+ org.postgresql
+ postgresql
+
+
+ com.microsoft.sqlserver
+ mssql-jdbc
+
+
+ com.oracle.database.jdbc
+ ojdbc10
+ 19.18.0.0
+
+
+ org.flywaydb
+ flyway-core
+ ${flyway.version}
+
+
+ org.flywaydb
+ flyway-mysql
+ ${flyway.version}
+
+
+ org.flywaydb
+ flyway-sqlserver
+ ${flyway.version}
+
+
+
+ org.yaml
+ snakeyaml
+ 2.0
+
+
+ org.bouncycastle
+ bcprov-jdk18on
+ 1.76
+
+
+ org.bouncycastle
+ bcpkix-jdk18on
+ 1.76
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.5
+ runtime
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+
+
+ com.google.guava
+ guava
+ ${guava.version}
+
+
+ dev.samstevens.totp
+ totp
+ 1.7.1
+
+
+ com.beust
+ jcommander
+
+
+
+
+ com.beust
+ jcommander
+ 1.82
+
+
+
+ com.h2database
+ h2
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.jupiter.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.jupiter.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ ${junit.jupiter.version}
+ test
+
+
+ org.mockito
+ mockito-core
+ ${mockito.version}
+ test
+
+
+ org.mockito
+ mockito-junit-jupiter
+ ${mockito.version}
+ test
+
+
+ org.mockito
+ mockito-inline
+ ${mockito.version}
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+
+
+ default
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+
+ ${java.version}
+
+ -parameters
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 3.1.1
+
+ UTF-8
+ src/main/resources/checkstyle.xml
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+ validate
+ clean
+
+ check
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+ build-info
+
+ build-info
+
+
+
+
+
+
+
+
+
+ codecov
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+ true
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco-maven-plugin.version}
+
+ ${skip.jacoco-check-execution}
+
+ **/*Application.class
+ **/**/DemoDataProviderService.class
+ **/Abstract*.class
+ **/**/*Exception.class
+ **/TestDataProviderService.class
+ **/model/*.class
+ **/config/*.class
+ **/dto/*.class
+ **/enums/*.class
+ **/entity/*.class
+ **/types/*.class
+ **/event/*.class
+
+
+
+
+
+ prepare-agent
+
+
+
+ jacoco-report
+ package
+
+ report
+
+
+
+ jacoco-check
+ test
+
+ check
+
+
+ ${skip.jacoco-check-execution}
+
+
+ BUNDLE
+
+
+ INSTRUCTION
+ COVEREDRATIO
+ ${test.minimum.coverage}
+
+
+ BRANCH
+ COVEREDRATIO
+ ${test.minimum.coverage}
+
+
+
+
+
+
+
+
+
+
+
+
+ mutation-test
+
+ false
+
+
+
+
+ org.pitest
+ pitest-maven
+ 1.14.1
+
+
+ pit-report
+ test
+
+ mutationCoverage
+
+
+
+
+
+ org.pitest
+ pitest-junit5-plugin
+ 0.15
+
+
+
+ 95
+ 95
+ 2
+
+ io.github.gms.**.*
+
+
+ io.github.gms.**.*Test
+
+
+ *.*Application
+ *.*Config
+ *.*Dto
+ *.*Entity
+ *.config.*
+ *.dto.*
+ *.entity.*
+ *.enums.*
+ *.event.*
+ *.exception.*
+ *.model.*
+ *.repository.*
+
+
+ io.github.gms.**.*IntegrationTest
+
+
+
+
+
+
+
+ build-prod
+
+ false
+
+
+ gms-app
+
+
+
+ maven-resources-plugin
+ 3.0.2
+
+
+ copy-javascript-resources
+ prepare-package
+
+ copy-resources
+
+
+ ${basedir}/target/classes/static
+
+
+ ${basedir}/../gms-frontend/dist/gms-frontend
+ false
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+ io.github.gms.GmsApplication
+
+
+
+
+ repackage
+
+
+
+ build-info
+
+ build-info
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.1.0
+
+
+
+
+
+ build-prod-docker-image-local
+
+ false
+
+
+ gms-app
+
+
+ maven-resources-plugin
+ 3.0.2
+
+
+ copy-javascript-resources
+ prepare-package
+
+ copy-resources
+
+
+ ${basedir}/target/classes/static
+
+
+ ${basedir}/../gms-frontend/dist/gms-frontend
+ false
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ ${java.version}
+
+
+
+ io.github.gms
+ gms-frontend
+ 0.0.1-SNAPSHOT
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+ io.github.gms.GmsApplication
+
+
+
+
+ repackage
+
+
+
+ build-info
+
+ build-info
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.1.0
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+ true
+
+
+
+ com.spotify
+ dockerfile-maven-plugin
+
+ false
+ gms-app-local
+ latest
+ gms-app-local
+
+ target/${project.build.finalName}.jar
+
+
+
+
+ default
+
+ build
+
+
+
+
+
+
+
+
diff --git a/code/gms-backend/src/main/java/io/github/gms/GmsApplication.java b/code/gms-backend/src/main/java/io/github/gms/GmsApplication.java
index 3e0f00b4..3cd60152 100644
--- a/code/gms-backend/src/main/java/io/github/gms/GmsApplication.java
+++ b/code/gms-backend/src/main/java/io/github/gms/GmsApplication.java
@@ -3,6 +3,7 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration;
+import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
/**
@@ -13,7 +14,8 @@
*/
@SpringBootApplication(exclude = {
LdapRepositoriesAutoConfiguration.class,
- JacksonAutoConfiguration.class
+ JacksonAutoConfiguration.class,
+ RedisAutoConfiguration.class
})
public class GmsApplication {
diff --git a/code/gms-backend/src/main/java/io/github/gms/GmsExceptionHandler.java b/code/gms-backend/src/main/java/io/github/gms/GmsExceptionHandler.java
index 8dcaebe0..59fd65cb 100644
--- a/code/gms-backend/src/main/java/io/github/gms/GmsExceptionHandler.java
+++ b/code/gms-backend/src/main/java/io/github/gms/GmsExceptionHandler.java
@@ -1,26 +1,21 @@
package io.github.gms;
-import java.time.Clock;
-import java.time.ZonedDateTime;
-
+import com.google.common.base.Throwables;
+import io.github.gms.common.dto.ErrorResponseDto;
+import io.github.gms.common.enums.MdcParameter;
+import io.github.gms.common.exception.GmsException;
+import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MissingRequestHeaderException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.bind.annotation.ResponseStatus;
-import org.springframework.web.method.HandlerMethod;
-import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
-
-import com.google.common.base.Throwables;
+import org.springframework.web.context.request.WebRequest;
-import io.github.gms.common.dto.ErrorResponseDto;
-import io.github.gms.common.enums.MdcParameter;
-import io.github.gms.common.exception.GmsException;
-import jakarta.servlet.http.HttpServletRequest;
-import lombok.extern.slf4j.Slf4j;
+import java.time.Clock;
+import java.time.ZonedDateTime;
/**
* @author Peter Szrnka
@@ -28,7 +23,7 @@
*/
@Slf4j
@ControllerAdvice
-public class GmsExceptionHandler extends ResponseEntityExceptionHandler {
+public class GmsExceptionHandler {
private final Clock clock;
@@ -37,28 +32,32 @@ public GmsExceptionHandler(Clock clock) {
}
@ExceptionHandler(GmsException.class)
- @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
- public @ResponseBody ErrorResponseDto handleOtherException(HttpServletRequest request, HandlerMethod handlerMethod, GmsException ex) {
+ public ResponseEntity handleOtherException(GmsException ex, WebRequest request) {
log.error("GmsException handled", ex);
- return new ErrorResponseDto(Throwables.getRootCause(ex).getMessage(), MDC.get(MdcParameter.CORRELATION_ID.getDisplayName()), ZonedDateTime.now(clock));
+ return getResponse(ex, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(AccessDeniedException.class)
- @ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "Access forbidden")
- public @ResponseBody ErrorResponseDto handleOtherException(HttpServletRequest request, HandlerMethod handlerMethod, AccessDeniedException ex) {
- return new ErrorResponseDto(Throwables.getRootCause(ex).getMessage(), MDC.get(MdcParameter.CORRELATION_ID.getDisplayName()), ZonedDateTime.now(clock));
+ public ResponseEntity handleOtherException(AccessDeniedException ex, WebRequest request) {
+ return getResponse(ex, HttpStatus.FORBIDDEN);
}
@ExceptionHandler(MissingRequestHeaderException.class)
- @ResponseStatus(value = HttpStatus.BAD_REQUEST)
- public @ResponseBody ErrorResponseDto handleOtherException(HttpServletRequest request, HandlerMethod handlerMethod, MissingRequestHeaderException ex) {
- return new ErrorResponseDto(Throwables.getRootCause(ex).getMessage(), MDC.get(MdcParameter.CORRELATION_ID.getDisplayName()), ZonedDateTime.now(clock));
+ public ResponseEntity handleOtherException(MissingRequestHeaderException ex, WebRequest request) {
+ return getResponse(ex, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Exception.class)
- @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
- public @ResponseBody ErrorResponseDto handleOtherException(HttpServletRequest request, HandlerMethod handlerMethod, Exception ex) {
+ public ResponseEntity handleOtherException(Exception ex, WebRequest request) {
log.error("Exception handled", ex);
- return new ErrorResponseDto(Throwables.getRootCause(ex).getMessage(), MDC.get(MdcParameter.CORRELATION_ID.getDisplayName()), ZonedDateTime.now(clock));
+ return getResponse(ex, HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+
+ private ResponseEntity getResponse(Exception ex, HttpStatus httpStatus) {
+ return new ResponseEntity<>(new ErrorResponseDto(
+ Throwables.getRootCause(ex).getMessage(),
+ MDC.get(MdcParameter.CORRELATION_ID.getDisplayName()),
+ ZonedDateTime.now(clock)
+ ), httpStatus);
}
}
\ No newline at end of file
diff --git a/code/gms-backend/src/main/java/io/github/gms/auth/config/SecurityConfig.java b/code/gms-backend/src/main/java/io/github/gms/auth/config/SecurityConfig.java
index c5140d5c..7e276511 100644
--- a/code/gms-backend/src/main/java/io/github/gms/auth/config/SecurityConfig.java
+++ b/code/gms-backend/src/main/java/io/github/gms/auth/config/SecurityConfig.java
@@ -1,9 +1,12 @@
package io.github.gms.auth.config;
-import static io.github.gms.common.util.Constants.PASSWORD_ENCODER;
-
-import java.util.List;
-
+import dev.samstevens.totp.code.CodeGenerator;
+import dev.samstevens.totp.code.CodeVerifier;
+import dev.samstevens.totp.code.DefaultCodeGenerator;
+import dev.samstevens.totp.code.DefaultCodeVerifier;
+import dev.samstevens.totp.time.SystemTimeProvider;
+import dev.samstevens.totp.time.TimeProvider;
+import io.github.gms.common.filter.SecureHeaderInitializerFilter;
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -28,13 +31,9 @@
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import dev.samstevens.totp.code.CodeGenerator;
-import dev.samstevens.totp.code.CodeVerifier;
-import dev.samstevens.totp.code.DefaultCodeGenerator;
-import dev.samstevens.totp.code.DefaultCodeVerifier;
-import dev.samstevens.totp.time.SystemTimeProvider;
-import dev.samstevens.totp.time.TimeProvider;
-import io.github.gms.common.filter.SecureHeaderInitializerFilter;
+import java.util.List;
+
+import static io.github.gms.common.util.Constants.PASSWORD_ENCODER;
/**
* @author Peter Szrnka
diff --git a/code/gms-backend/src/main/java/io/github/gms/common/config/RedisCacheConfig.java b/code/gms-backend/src/main/java/io/github/gms/common/config/RedisCacheConfig.java
index cb412233..247d556a 100644
--- a/code/gms-backend/src/main/java/io/github/gms/common/config/RedisCacheConfig.java
+++ b/code/gms-backend/src/main/java/io/github/gms/common/config/RedisCacheConfig.java
@@ -1,6 +1,7 @@
package io.github.gms.common.config;
import io.github.gms.common.config.cache.ApiCacheKeyGenerator;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.CacheManager;
@@ -13,6 +14,7 @@
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
@@ -31,6 +33,17 @@
@ConditionalOnProperty(name = "config.cache.redis.enabled", havingValue = "true")
public class RedisCacheConfig {
+ @Value("${config.cache.redis.host}")
+ private String host;
+
+ @Value("${config.cache.redis.port}")
+ private Integer port;
+
+ @Bean
+ public LettuceConnectionFactory lettuceConnectionFactory() {
+ return new LettuceConnectionFactory(host, port);
+ }
+
@Primary
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
diff --git a/code/gms-backend/src/main/java/io/github/gms/common/filter/SecureHeaderInitializerFilter.java b/code/gms-backend/src/main/java/io/github/gms/common/filter/SecureHeaderInitializerFilter.java
index 02a62a9a..84584632 100644
--- a/code/gms-backend/src/main/java/io/github/gms/common/filter/SecureHeaderInitializerFilter.java
+++ b/code/gms-backend/src/main/java/io/github/gms/common/filter/SecureHeaderInitializerFilter.java
@@ -1,21 +1,6 @@
package io.github.gms.common.filter;
-import java.io.IOException;
-import java.util.Set;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.slf4j.MDC;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.HttpStatus;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
import com.google.common.collect.Sets;
-
import io.github.gms.auth.AuthorizationService;
import io.github.gms.auth.model.AuthorizationResponse;
import io.github.gms.common.enums.JwtConfigType;
@@ -28,6 +13,19 @@
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import java.io.IOException;
+import java.util.Set;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* A custom Spring filter used to authorize user by parsing JWT token.
diff --git a/code/gms-backend/src/main/resources/application.properties b/code/gms-backend/src/main/resources/application.properties
index 157b6b72..49b23a27 100644
--- a/code/gms-backend/src/main/resources/application.properties
+++ b/code/gms-backend/src/main/resources/application.properties
@@ -65,5 +65,6 @@ spring.flyway.locations=classpath:db/${SELECTED_DB}/migration
# Cache (Redis)
config.cache.redis.enabled=${ENABLE_REDIS_CACHE:false}
-spring.redis.host=${REDIS_HOST}
-spring.redis.port=${REDIS_PORT}
\ No newline at end of file
+spring.data.redis.repositories.enabled=${ENABLE_REDIS_CACHE:false}
+config.cache.redis.host=${REDIS_HOST}
+config.cache.redis.port=${REDIS_PORT}
\ No newline at end of file
diff --git a/code/gms-backend/src/test/java/io/github/gms/GmsExceptionHandlerTest.java b/code/gms-backend/src/test/java/io/github/gms/GmsExceptionHandlerTest.java
index a96a44a4..3599a8f3 100644
--- a/code/gms-backend/src/test/java/io/github/gms/GmsExceptionHandlerTest.java
+++ b/code/gms-backend/src/test/java/io/github/gms/GmsExceptionHandlerTest.java
@@ -1,35 +1,33 @@
package io.github.gms;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.lang.reflect.Method;
-import java.time.Clock;
-import java.time.Instant;
-import java.time.ZoneOffset;
-
+import io.github.gms.abstraction.AbstractUnitTest;
+import io.github.gms.common.dto.ErrorResponseDto;
+import io.github.gms.common.enums.MdcParameter;
+import io.github.gms.common.exception.GmsException;
import org.jboss.logging.MDC;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.core.MethodParameter;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MissingRequestHeaderException;
-import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.context.request.WebRequest;
-import io.github.gms.abstraction.AbstractUnitTest;
-import io.github.gms.common.dto.ErrorResponseDto;
-import io.github.gms.common.enums.MdcParameter;
-import io.github.gms.common.exception.GmsException;
-import jakarta.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneOffset;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
/**
* @author Peter Szrnka
* @since 1.0
*/
-@Disabled
class GmsExceptionHandlerTest extends AbstractUnitTest {
private static final String CORRELATION_ID = "CORRELATION_ID";
@@ -48,64 +46,66 @@ public void setup() {
@Test
void shouldHandleGmsException() {
// arrange
- HttpServletRequest request = mock(HttpServletRequest.class);
- HandlerMethod handlerMethod = mock(HandlerMethod.class);
+ WebRequest webRequest = mock(WebRequest.class);
// act
- ErrorResponseDto response = handler.handleOtherException(request, handlerMethod, new GmsException("Oops!"));
+ ResponseEntity response = handler.handleOtherException(new GmsException("Oops!"), webRequest);
// assert
assertNotNull(response);
- assertEquals(CORRELATION_ID, response.getCorrelationId());
- assertEquals("Oops!", response.getMessage());
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
+ assertNotNull(response.getBody());
+ assertEquals(CORRELATION_ID, response.getBody().getCorrelationId());
+ assertEquals("Oops!", response.getBody().getMessage());
}
@Test
void shouldHandleAccessDeniedException() {
// arrange
- HttpServletRequest request = mock(HttpServletRequest.class);
- HandlerMethod handlerMethod = mock(HandlerMethod.class);
+ WebRequest webRequest = mock(WebRequest.class);
// act
- ErrorResponseDto response = handler.handleOtherException(request, handlerMethod,
- new AccessDeniedException("Oops!"));
+ ResponseEntity response = handler.handleOtherException(new AccessDeniedException("Oops!"), webRequest);
// assert
assertNotNull(response);
- assertEquals(CORRELATION_ID, response.getCorrelationId());
- assertEquals("Oops!", response.getMessage());
+ assertEquals(HttpStatus.FORBIDDEN, response.getStatusCode());
+ assertNotNull(response.getBody());
+ assertEquals(CORRELATION_ID, response.getBody().getCorrelationId());
+ assertEquals("Oops!", response.getBody().getMessage());
}
@Test
void shouldHandleOtherException() {
// arrange
- HttpServletRequest request = mock(HttpServletRequest.class);
- HandlerMethod handlerMethod = mock(HandlerMethod.class);
+ WebRequest webRequest = mock(WebRequest.class);
// act
- ErrorResponseDto response = handler.handleOtherException(request, handlerMethod, new RuntimeException("Oops!"));
+ ResponseEntity response = handler.handleOtherException(new RuntimeException("Oops!"), webRequest);
// assert
assertNotNull(response);
- assertEquals(CORRELATION_ID, response.getCorrelationId());
- assertEquals("Oops!", response.getMessage());
+ assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode());
+ assertNotNull(response.getBody());
+ assertEquals(CORRELATION_ID, response.getBody().getCorrelationId());
+ assertEquals("Oops!", response.getBody().getMessage());
}
@Test
void shouldHandleMissingRequestHeaderException() {
// arrange
- HttpServletRequest request = mock(HttpServletRequest.class);
- HandlerMethod handlerMethod = mock(HandlerMethod.class);
Method mockMethod = mock(Method.class);
MethodParameter mockMethodParameter = new MethodParameter(mockMethod, -1, 2);
+ WebRequest webRequest = mock(WebRequest.class);
// act
- ErrorResponseDto response = handler.handleOtherException(request, handlerMethod,
- new MissingRequestHeaderException("x-api-key", mockMethodParameter));
+ ResponseEntity response = handler.handleOtherException(new MissingRequestHeaderException("x-api-key", mockMethodParameter), webRequest);
// assert
assertNotNull(response);
- assertEquals(CORRELATION_ID, response.getCorrelationId());
- assertEquals("Required request header 'x-api-key' for method parameter type Object is not present", response.getMessage());
+ assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
+ assertNotNull(response.getBody());
+ assertEquals(CORRELATION_ID, response.getBody().getCorrelationId());
+ assertEquals("Required request header 'x-api-key' for method parameter type Object is not present", response.getBody().getMessage());
}
}
diff --git a/code/gms-backend/src/test/java/io/github/gms/abstraction/AbstractIntegrationTest.java b/code/gms-backend/src/test/java/io/github/gms/abstraction/AbstractIntegrationTest.java
index d56b0777..9b94d477 100644
--- a/code/gms-backend/src/test/java/io/github/gms/abstraction/AbstractIntegrationTest.java
+++ b/code/gms-backend/src/test/java/io/github/gms/abstraction/AbstractIntegrationTest.java
@@ -1,7 +1,12 @@
package io.github.gms.abstraction;
-import static io.github.gms.common.util.Constants.CONFIG_AUTH_TYPE_DB;
-
+import io.github.gms.auth.model.GmsUserDetails;
+import io.github.gms.secure.repository.ApiKeyRepository;
+import io.github.gms.secure.repository.KeystoreRepository;
+import io.github.gms.secure.repository.SecretRepository;
+import io.github.gms.secure.repository.UserRepository;
+import io.github.gms.secure.service.JwtService;
+import io.github.gms.util.TestUtils;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -13,13 +18,7 @@
import org.springframework.test.context.ActiveProfiles;
import org.springframework.web.client.RestTemplate;
-import io.github.gms.auth.model.GmsUserDetails;
-import io.github.gms.secure.repository.ApiKeyRepository;
-import io.github.gms.secure.repository.KeystoreRepository;
-import io.github.gms.secure.repository.SecretRepository;
-import io.github.gms.secure.repository.UserRepository;
-import io.github.gms.secure.service.JwtService;
-import io.github.gms.util.TestUtils;
+import static io.github.gms.common.util.Constants.CONFIG_AUTH_TYPE_DB;
/**
* @author Peter Szrnka
diff --git a/code/gms-backend/src/test/java/io/github/gms/api/controller/ApiIntegrationTest.java b/code/gms-backend/src/test/java/io/github/gms/api/controller/ApiIntegrationTest.java
index 73cc4006..b8e7b8e0 100644
--- a/code/gms-backend/src/test/java/io/github/gms/api/controller/ApiIntegrationTest.java
+++ b/code/gms-backend/src/test/java/io/github/gms/api/controller/ApiIntegrationTest.java
@@ -4,6 +4,7 @@
import io.github.gms.secure.repository.KeystoreAliasRepository;
import io.github.gms.util.DemoData;
import io.github.gms.util.TestUtils;
+import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
@@ -12,12 +13,14 @@
import java.util.Map;
+import static io.github.gms.util.TestConstants.TAG_INTEGRATION_TEST;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Peter Szrnka
* @since 1.0
*/
+@Tag(TAG_INTEGRATION_TEST)
class ApiIntegrationTest extends AbstractIntegrationTest {
@Autowired