Compare commits
34 Commits
3baea70356
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a1a0e373f | ||
|
|
d5df8f5d32 | ||
|
|
1df0ebee5c | ||
|
|
ce9f10acb9 | ||
|
|
001a83e75a | ||
|
|
277bcadb5d | ||
|
|
b836112ba5 | ||
|
|
180d431f8d | ||
| cca133d67c | |||
| 1385dc56a1 | |||
| 1d0cc270e3 | |||
| dd653cb525 | |||
| 97af2628fb | |||
| 34a5231081 | |||
| 753ed4f49f | |||
| 01f3096e60 | |||
| 1aee1eeb30 | |||
| 7f26fcc109 | |||
| 1ddb628b27 | |||
| 46662ac553 | |||
| f46c619be3 | |||
| 9361640f4c | |||
| 2527d3490f | |||
| 2a213c831a | |||
| 45c50924bc | |||
| b43358f071 | |||
| b4bbefff46 | |||
| da7ea66d3e | |||
| d7dee35d6e | |||
| 2cc188540b | |||
| 06b112305b | |||
| e89a7d4bff | |||
| 83c9b53330 | |||
| 36c8f3b22f |
@@ -1,4 +1,4 @@
|
|||||||
FROM eclipse-temurin:21
|
FROM eclipse-temurin:25
|
||||||
|
|
||||||
COPY target/swiss*.jar swiss-backend.jar
|
COPY target/swiss*.jar swiss-backend.jar
|
||||||
|
|
||||||
|
|||||||
3
Jenkinsfile
vendored
3
Jenkinsfile
vendored
@@ -5,6 +5,9 @@ pipeline {
|
|||||||
disableConcurrentBuilds()
|
disableConcurrentBuilds()
|
||||||
}
|
}
|
||||||
agent any
|
agent any
|
||||||
|
tools {
|
||||||
|
jdk 'JDK 25'
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
agent {
|
agent {
|
||||||
|
|||||||
33
TODO
33
TODO
@@ -5,3 +5,36 @@ https://bootify.io/spring-security/rest-api-spring-security-with-jwt.html
|
|||||||
https://access.crunchydata.com/documentation/postgres-operator/latest/tutorials/cluster-management/update-cluster
|
https://access.crunchydata.com/documentation/postgres-operator/latest/tutorials/cluster-management/update-cluster
|
||||||
|
|
||||||
Token refresh
|
Token refresh
|
||||||
|
|
||||||
|
|
||||||
|
db update:
|
||||||
|
|
||||||
|
round.is_finals_round
|
||||||
|
koppeltabel eventgroup_teams
|
||||||
|
tournament.active
|
||||||
|
|
||||||
|
set search_path to swiss;
|
||||||
|
|
||||||
|
ALTER TABLE match
|
||||||
|
ADD counter_id bigint;
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
ALTER TABLE round
|
||||||
|
ADD is_finals_round boolean;
|
||||||
|
|
||||||
|
ALTER TABLE round
|
||||||
|
ADD is_final_round boolean DEFAULT (false);
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
ALTER TABLE tournament_player
|
||||||
|
ADD counting boolean;
|
||||||
|
|
||||||
|
ALTER TABLE tournament_player
|
||||||
|
ADD counts bigint;
|
||||||
|
|
||||||
|
UPDATE tournament_player SET counting = false;
|
||||||
|
UPDATE tournament_player SET counts = 0;
|
||||||
|
|
||||||
|
tournament_player.substitute_id + constraint
|
||||||
338
pom.xml
338
pom.xml
@@ -1,185 +1,183 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.3.4</version>
|
<version>3.5.6</version>
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>nl.connected-it</groupId>
|
<groupId>nl.connected-it</groupId>
|
||||||
<artifactId>swiss-backend</artifactId>
|
<artifactId>swiss-backend</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<name>swiss-backend</name>
|
<name>swiss-backend</name>
|
||||||
<description>Swiss Backend</description>
|
<description>Swiss Backend</description>
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>21</java.version>
|
<java.version>25</java.version>
|
||||||
<maven.compiler.source>21</maven.compiler.source>
|
<maven.compiler.source>25</maven.compiler.source>
|
||||||
<maven.compiler.target>21</maven.compiler.target>
|
<maven.compiler.target>25</maven.compiler.target>
|
||||||
<mapstruct.version>1.6.0.RC1</mapstruct.version>
|
</properties>
|
||||||
</properties>
|
<dependencies>
|
||||||
<dependencies>
|
<dependency>
|
||||||
<dependency>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
</dependency>
|
||||||
</dependency>
|
<dependency>
|
||||||
<dependency>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
</dependency>
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-security</artifactId>
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.auth0</groupId>
|
<groupId>com.auth0</groupId>
|
||||||
<artifactId>java-jwt</artifactId>
|
<artifactId>java-jwt</artifactId>
|
||||||
<version>4.4.0</version>
|
<version>4.5.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-hibernate5-jakarta</artifactId>
|
||||||
|
<version>2.20.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</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-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.flywaydb</groupId>
|
||||||
|
<artifactId>flyway-core</artifactId>
|
||||||
|
<version>11.13.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.flywaydb</groupId>
|
||||||
|
<artifactId>flyway-database-postgresql</artifactId>
|
||||||
|
<version>11.13.2</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
|
||||||
<artifactId>jackson-datatype-hibernate5-jakarta</artifactId>
|
|
||||||
<version>2.17.2</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.h2database</groupId>
|
|
||||||
<artifactId>h2</artifactId>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-security</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-validation</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.postgresql</groupId>
|
|
||||||
<artifactId>postgresql</artifactId>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.flywaydb</groupId>
|
|
||||||
<artifactId>flyway-core</artifactId>
|
|
||||||
<version>10.18.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.flywaydb</groupId>
|
|
||||||
<artifactId>flyway-database-postgresql</artifactId>
|
|
||||||
<version>10.18.0</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<!-- <optional>true</optional>-->
|
<!-- <optional>true</optional>-->
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.security</groupId>
|
<groupId>org.springframework.security</groupId>
|
||||||
<artifactId>spring-security-test</artifactId>
|
<artifactId>spring-security-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.hibernate.orm.tooling</groupId>
|
<groupId>org.hibernate.orm.tooling</groupId>
|
||||||
<artifactId>hibernate-enhance-maven-plugin</artifactId>
|
<artifactId>hibernate-enhance-maven-plugin</artifactId>
|
||||||
<version>${hibernate.version}</version>
|
<version>6.6.31.Final</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>enhance</id>
|
<id>enhance</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>enhance</goal>
|
<goal>enhance</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<enableLazyInitialization>true</enableLazyInitialization>
|
<enableLazyInitialization>true</enableLazyInitialization>
|
||||||
<enableDirtyTracking>true</enableDirtyTracking>
|
<enableDirtyTracking>true</enableDirtyTracking>
|
||||||
<enableAssociationManagement>true</enableAssociationManagement>
|
<enableAssociationManagement>true</enableAssociationManagement>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
<dependencies>
|
||||||
<plugin>
|
<dependency>
|
||||||
<groupId>org.graalvm.buildtools</groupId>
|
<groupId>net.bytebuddy</groupId>
|
||||||
<artifactId>native-maven-plugin</artifactId>
|
<artifactId>byte-buddy</artifactId>
|
||||||
</plugin>
|
<version>1.17.7</version>
|
||||||
<plugin>
|
</dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
</dependencies>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
</plugin>
|
||||||
<configuration>
|
<plugin>
|
||||||
<excludes>
|
<groupId>org.graalvm.buildtools</groupId>
|
||||||
<exclude>
|
<artifactId>native-maven-plugin</artifactId>
|
||||||
<groupId>org.projectlombok</groupId>
|
</plugin>
|
||||||
<artifactId>lombok</artifactId>
|
<plugin>
|
||||||
</exclude>
|
<groupId>org.springframework.boot</groupId>
|
||||||
</excludes>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
</configuration>
|
<configuration>
|
||||||
</plugin>
|
<excludes>
|
||||||
<plugin>
|
<exclude>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>3.13.0</version>
|
</exclude>
|
||||||
<configuration>
|
</excludes>
|
||||||
<source>21</source>
|
</configuration>
|
||||||
<target>21</target>
|
</plugin>
|
||||||
<annotationProcessorPaths>
|
<plugin>
|
||||||
<path>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<groupId>org.projectlombok</groupId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<artifactId>lombok</artifactId>
|
<version>3.14.1</version>
|
||||||
<version>${lombok.version}</version>
|
<configuration>
|
||||||
</path>
|
<source>25</source>
|
||||||
<!--
|
<target>25</target>
|
||||||
<path>
|
<annotationProcessorPaths>
|
||||||
<groupId>org.projectlombok</groupId>
|
<path>
|
||||||
<artifactId>lombok-mapstruct-binding</artifactId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<version>0.2.0</version>
|
<artifactId>lombok</artifactId>
|
||||||
</path>
|
<version>${lombok.version}</version>
|
||||||
<path>
|
</path>
|
||||||
<groupId>org.mapstruct</groupId>
|
</annotationProcessorPaths>
|
||||||
<artifactId>mapstruct-processor</artifactId>
|
</configuration>
|
||||||
<version>${mapstruct.version}</version>
|
</plugin>
|
||||||
</path>
|
<plugin>
|
||||||
-->
|
<groupId>org.flywaydb</groupId>
|
||||||
</annotationProcessorPaths>
|
<artifactId>flyway-maven-plugin</artifactId>
|
||||||
</configuration>
|
<version>11.13.2</version>
|
||||||
</plugin>
|
<configuration>
|
||||||
<plugin>
|
<url>jdbc:postgresql://localhost:5432/swiss?currentSchema=swiss</url>
|
||||||
<groupId>org.flywaydb</groupId>
|
<user>postgres</user>
|
||||||
<artifactId>flyway-maven-plugin</artifactId>
|
<password>postgres</password>
|
||||||
<version>10.18.0</version>
|
</configuration>
|
||||||
<configuration>
|
</plugin>
|
||||||
<url>jdbc:postgresql://localhost:5432/swiss?currentSchema=swiss</url>
|
</plugins>
|
||||||
<user>postgres</user>
|
|
||||||
<password>postgres</password>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
|
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
44
src/main/java/nl/connectedit/swiss/auth/AuthController.java
Normal file
44
src/main/java/nl/connectedit/swiss/auth/AuthController.java
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package nl.connectedit.swiss.auth;
|
||||||
|
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
|
||||||
|
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||||
|
import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
|
||||||
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@CrossOrigin
|
||||||
|
@RequestMapping("/api/auth")
|
||||||
|
public class AuthController {
|
||||||
|
|
||||||
|
private final JwtEncoder encoder;
|
||||||
|
|
||||||
|
public AuthController(JwtEncoder encoder) {
|
||||||
|
this.encoder = encoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public String auth(Authentication authentication) {
|
||||||
|
Instant now = Instant.now();
|
||||||
|
long expiry = 36000L;
|
||||||
|
String scope = authentication.getAuthorities().stream()
|
||||||
|
.map(GrantedAuthority::getAuthority)
|
||||||
|
.collect(Collectors.joining(","));
|
||||||
|
JwtClaimsSet claims = JwtClaimsSet.builder()
|
||||||
|
.issuer("self")
|
||||||
|
.issuedAt(now)
|
||||||
|
.expiresAt(now.plusSeconds(expiry))
|
||||||
|
.subject(authentication.getName())
|
||||||
|
.claim("scope", scope)
|
||||||
|
.build();
|
||||||
|
return this.encoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
9
src/main/java/nl/connectedit/swiss/auth/Roles.java
Normal file
9
src/main/java/nl/connectedit/swiss/auth/Roles.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package nl.connectedit.swiss.auth;
|
||||||
|
|
||||||
|
public final class Roles {
|
||||||
|
|
||||||
|
public static final String USER = "USER";
|
||||||
|
|
||||||
|
private Roles() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
|
||||||
import org.springframework.context.annotation.Profile;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
|
||||||
import org.springframework.security.authentication.BadCredentialsException;
|
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@ConditionalOnExpression("${security}")
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@CrossOrigin
|
|
||||||
public class AuthenticationController {
|
|
||||||
|
|
||||||
private final JwtUserDetailsService jwtUserDetailsService;
|
|
||||||
|
|
||||||
private final AuthenticationManager authenticationManager;
|
|
||||||
|
|
||||||
private final JwtTokenService jwtTokenService;
|
|
||||||
|
|
||||||
@PostMapping("/authenticate")
|
|
||||||
public AuthenticationResponse authenticate(@RequestBody @Valid final AuthenticationRequest authenticationRequest) {
|
|
||||||
try {
|
|
||||||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
|
|
||||||
authenticationRequest.getUsername(), authenticationRequest.getPassword()));
|
|
||||||
} catch (final BadCredentialsException ex) {
|
|
||||||
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
final UserDetails userDetails = jwtUserDetailsService.loadUserByUsername(authenticationRequest.getUsername());
|
|
||||||
final AuthenticationResponse authenticationResponse = new AuthenticationResponse();
|
|
||||||
authenticationResponse.setAccessToken(jwtTokenService.generateToken(userDetails));
|
|
||||||
authenticationResponse.setUsername(authenticationRequest.getUsername());
|
|
||||||
return authenticationResponse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import jakarta.validation.constraints.Size;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class AuthenticationRequest {
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Size(max = 255)
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Size(max = 255)
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class AuthenticationResponse {
|
|
||||||
|
|
||||||
private String accessToken;
|
|
||||||
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class Client {
|
|
||||||
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
private String hash;
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
import org.springframework.util.DigestUtils;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Repository
|
|
||||||
public class ClientRepository {
|
|
||||||
|
|
||||||
private static final String hash = "$2a$12$FjsFqFTorg0sXCiSISFS3.xvSCzmAATIcA7wh5w8WtQ7eYZC.H4UW";
|
|
||||||
|
|
||||||
Optional<Client> findByLogin(String username) {
|
|
||||||
if (username.equals("bcholten")) {
|
|
||||||
var client = new Client();
|
|
||||||
client.setId(1L);
|
|
||||||
client.setHash(hash);
|
|
||||||
return Optional.of(client);
|
|
||||||
} else {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import jakarta.servlet.FilterChain;
|
|
||||||
import jakarta.servlet.ServletException;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
|
||||||
import org.springframework.context.annotation.Profile;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@ConditionalOnExpression("${security}")
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class JwtRequestFilter extends OncePerRequestFilter {
|
|
||||||
|
|
||||||
private final JwtTokenService jwtTokenService;
|
|
||||||
|
|
||||||
private final JwtUserDetailsService jwtUserDetailsService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
|
|
||||||
final FilterChain chain) throws IOException, ServletException {
|
|
||||||
// look for Bearer auth header
|
|
||||||
final String header = request.getHeader(HttpHeaders.AUTHORIZATION);
|
|
||||||
if (header == null || !header.startsWith("Bearer ")) {
|
|
||||||
chain.doFilter(request, response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String token = header.substring(7);
|
|
||||||
final String username = jwtTokenService.validateTokenAndGetUsername(token);
|
|
||||||
if (username == null) {
|
|
||||||
// validation failed or token expired
|
|
||||||
chain.doFilter(request, response);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set user details on spring security context
|
|
||||||
final JwtUserDetails userDetails = jwtUserDetailsService.loadUserByUsername(username);
|
|
||||||
final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
|
||||||
userDetails, null, userDetails.getAuthorities());
|
|
||||||
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
|
||||||
|
|
||||||
// continue with authenticated user
|
|
||||||
chain.doFilter(request, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
|
||||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
|
||||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
||||||
|
|
||||||
import static org.springframework.security.config.Customizer.withDefaults;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@ConditionalOnExpression("${security}")
|
|
||||||
@EnableWebSecurity
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class JwtSecurityConfig {
|
|
||||||
|
|
||||||
private final JwtRequestFilter jwtRequestFilter;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
BCryptPasswordEncoder passwordEncoder() {
|
|
||||||
return new BCryptPasswordEncoder();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public AuthenticationManager authenticationManager(
|
|
||||||
final AuthenticationConfiguration authenticationConfiguration) throws Exception {
|
|
||||||
return authenticationConfiguration.getAuthenticationManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public SecurityFilterChain configure(final HttpSecurity http) throws Exception {
|
|
||||||
return http.cors(withDefaults())
|
|
||||||
.csrf((csrf) -> csrf.disable())
|
|
||||||
.authorizeHttpRequests((authorize) -> authorize
|
|
||||||
.requestMatchers("/", "/authenticate", "/testdata").permitAll()
|
|
||||||
.anyRequest().hasAuthority(UserRoles.ROLE_USER))
|
|
||||||
.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
|
||||||
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public WebMvcConfigurer corsConfigurer() {
|
|
||||||
return new WebMvcConfigurer() {
|
|
||||||
@Override
|
|
||||||
public void addCorsMappings(CorsRegistry registry) {
|
|
||||||
registry.addMapping("/**")
|
|
||||||
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import com.auth0.jwt.JWT;
|
|
||||||
import com.auth0.jwt.JWTVerifier;
|
|
||||||
import com.auth0.jwt.algorithms.Algorithm;
|
|
||||||
import com.auth0.jwt.exceptions.JWTVerificationException;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.security.interfaces.RSAPrivateKey;
|
|
||||||
import java.security.interfaces.RSAPublicKey;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
@ConditionalOnExpression("${security}")
|
|
||||||
public class JwtTokenService {
|
|
||||||
|
|
||||||
private static final Duration JWT_TOKEN_VALIDITY = Duration.ofDays(7);
|
|
||||||
|
|
||||||
private final Algorithm rsa256;
|
|
||||||
private final JWTVerifier verifier;
|
|
||||||
|
|
||||||
public JwtTokenService(@Value("classpath:certs/public.pem") final RSAPublicKey publicKey,
|
|
||||||
@Value("classpath:certs/private.pem") final RSAPrivateKey privateKey) {
|
|
||||||
this.rsa256 = Algorithm.RSA256(publicKey, privateKey);
|
|
||||||
this.verifier = JWT.require(this.rsa256).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String generateToken(final UserDetails userDetails) {
|
|
||||||
final Instant now = Instant.now();
|
|
||||||
return JWT.create()
|
|
||||||
.withSubject(userDetails.getUsername())
|
|
||||||
.withIssuer("app")
|
|
||||||
.withIssuedAt(now)
|
|
||||||
.withExpiresAt(now.plusMillis(JWT_TOKEN_VALIDITY.toMillis()))
|
|
||||||
.sign(this.rsa256);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String validateTokenAndGetUsername(final String token) {
|
|
||||||
try {
|
|
||||||
return verifier.verify(token).getSubject();
|
|
||||||
} catch (final JWTVerificationException verificationEx) {
|
|
||||||
// log.warn("token invalid: {}", verificationEx.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
import org.springframework.security.core.userdetails.User;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class JwtUserDetails extends User {
|
|
||||||
|
|
||||||
public final Long id;
|
|
||||||
|
|
||||||
public JwtUserDetails(final Long id, final String username, final String hash,
|
|
||||||
final Collection<? extends GrantedAuthority> authorities) {
|
|
||||||
super(username, hash, authorities);
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class JwtUserDetailsService implements UserDetailsService {
|
|
||||||
|
|
||||||
private final ClientRepository clientRepository;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JwtUserDetails loadUserByUsername(final String username) {
|
|
||||||
final Client client = clientRepository.findByLogin(username).orElseThrow(
|
|
||||||
() -> new UsernameNotFoundException("User " + username + " not found"));
|
|
||||||
final List<SimpleGrantedAuthority> roles = Collections.singletonList(new SimpleGrantedAuthority(UserRoles.ROLE_USER));
|
|
||||||
return new JwtUserDetails(client.getId(), username, client.getHash(), roles);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class LoginCredentialsDto {
|
|
||||||
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
private String ipAddres;
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class UserDto {
|
|
||||||
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
private String token;
|
|
||||||
|
|
||||||
private String refreshToken;
|
|
||||||
|
|
||||||
private String ipAddress;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package nl.connectedit.swiss.authentication;
|
|
||||||
|
|
||||||
public class UserRoles {
|
|
||||||
|
|
||||||
public static final String USER = "USER";
|
|
||||||
public static final String ROLE_USER = "ROLE_" + USER;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,26 +1,148 @@
|
|||||||
package nl.connectedit.swiss.config;
|
package nl.connectedit.swiss.config;
|
||||||
|
|
||||||
|
import com.nimbusds.jose.jwk.JWK;
|
||||||
|
import com.nimbusds.jose.jwk.JWKSet;
|
||||||
|
import com.nimbusds.jose.jwk.RSAKey;
|
||||||
|
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
|
||||||
|
import com.nimbusds.jose.jwk.source.JWKSource;
|
||||||
|
import com.nimbusds.jose.proc.SecurityContext;
|
||||||
import jakarta.servlet.DispatcherType;
|
import jakarta.servlet.DispatcherType;
|
||||||
|
import nl.connectedit.swiss.auth.Roles;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
|
||||||
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
|
import org.springframework.security.core.userdetails.User;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||||
|
import org.springframework.security.oauth2.jwt.JwtEncoder;
|
||||||
|
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||||
|
import org.springframework.security.oauth2.jwt.NimbusJwtEncoder;
|
||||||
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
|
||||||
|
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
|
||||||
|
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
|
||||||
|
import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler;
|
||||||
|
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.CorsConfigurationSource;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
|
||||||
//@Configuration
|
import java.security.interfaces.RSAPrivateKey;
|
||||||
//@EnableWebSecurity
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
|
|
||||||
// @Bean
|
private final RSAPublicKey key;
|
||||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
private final RSAPrivateKey priv;
|
||||||
|
|
||||||
|
public SecurityConfig(@Value("${jwt.public.key}") RSAPublicKey key,
|
||||||
|
@Value("${jwt.private.key}") RSAPrivateKey priv) {
|
||||||
|
this.key = key;
|
||||||
|
this.priv = priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.csrf(AbstractHttpConfigurer::disable)
|
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
|
||||||
.authorizeHttpRequests(auth -> auth.anyRequest().permitAll());
|
.csrf(csrf -> csrf.ignoringRequestMatchers("/api/auth"))
|
||||||
// .authorizeHttpRequests(request -> {
|
.authorizeHttpRequests(authorize -> authorize
|
||||||
// request.dispatcherTypeMatchers(DispatcherType.FORWARD).permitAll();
|
// Allow OPTIONS requests for CORS preflight
|
||||||
// request.requestMatchers("/error").permitAll();
|
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
||||||
// });
|
// Allow POST to /api/auth without JWT (Basic Auth will still be required)
|
||||||
|
.requestMatchers(HttpMethod.POST, "/api/auth").permitAll()
|
||||||
|
// All other requests require authentication
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
)
|
||||||
|
.httpBasic(Customizer.withDefaults())
|
||||||
|
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
|
||||||
|
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||||
|
.exceptionHandling(exceptions -> exceptions
|
||||||
|
.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
|
||||||
|
.accessDeniedHandler(new BearerTokenAccessDeniedHandler())
|
||||||
|
);
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CorsConfigurationSource corsConfigurationSource() {
|
||||||
|
CorsConfiguration configuration = new CorsConfiguration();
|
||||||
|
|
||||||
|
// Allow your Angular app's origin(s)
|
||||||
|
configuration.setAllowedOrigins(Arrays.asList(
|
||||||
|
"http://localhost:4200",
|
||||||
|
"http://localhost:8080",
|
||||||
|
// Add your production URL here when deploying
|
||||||
|
"https://badminton-toernooi.nl",
|
||||||
|
"https://test.badminton-toernooi.nl"
|
||||||
|
));
|
||||||
|
|
||||||
|
configuration.setAllowedMethods(Arrays.asList(
|
||||||
|
"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"
|
||||||
|
));
|
||||||
|
|
||||||
|
configuration.setAllowedHeaders(Arrays.asList(
|
||||||
|
"Authorization",
|
||||||
|
"Content-Type",
|
||||||
|
"Accept"
|
||||||
|
));
|
||||||
|
|
||||||
|
configuration.setAllowCredentials(true);
|
||||||
|
configuration.setMaxAge(3600L);
|
||||||
|
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
source.registerCorsConfiguration("/**", configuration);
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
UserDetailsService users() {
|
||||||
|
return new InMemoryUserDetailsManager(
|
||||||
|
User.withUsername("bcholten")
|
||||||
|
.password(passwordEncoder().encode("bcholten"))
|
||||||
|
.roles(Roles.USER)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
JwtDecoder jwtDecoder() {
|
||||||
|
return NimbusJwtDecoder.withPublicKey(this.key).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
JwtEncoder jwtEncoder() {
|
||||||
|
JWK jwk = new RSAKey.Builder(this.key).privateKey(this.priv).build();
|
||||||
|
JWKSource<SecurityContext> jwks = new ImmutableJWKSet<>(new JWKSet(jwk));
|
||||||
|
return new NimbusJwtEncoder(jwks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JwtAuthenticationConverter jwtAuthenticationConverter() {
|
||||||
|
JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
|
||||||
|
// Remove the SCOPE_ prefix
|
||||||
|
grantedAuthoritiesConverter.setAuthorityPrefix("");
|
||||||
|
|
||||||
|
JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
|
||||||
|
jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
|
||||||
|
return jwtAuthenticationConverter;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package nl.connectedit.swiss.controller;
|
package nl.connectedit.swiss.controller;
|
||||||
|
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import nl.connectedit.swiss.auth.Roles;
|
||||||
import nl.connectedit.swiss.domain.entity.Player;
|
import nl.connectedit.swiss.domain.entity.Player;
|
||||||
import nl.connectedit.swiss.dto.PlayerDto;
|
import nl.connectedit.swiss.dto.PlayerDto;
|
||||||
import nl.connectedit.swiss.mapper.PlayerMapper;
|
import nl.connectedit.swiss.mapper.PlayerMapper;
|
||||||
@@ -12,6 +14,7 @@ import java.util.List;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@CrossOrigin
|
@CrossOrigin
|
||||||
|
@RolesAllowed(Roles.USER)
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PlayerController {
|
public class PlayerController {
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package nl.connectedit.swiss.controller;
|
package nl.connectedit.swiss.controller;
|
||||||
|
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import nl.connectedit.swiss.auth.Roles;
|
||||||
import nl.connectedit.swiss.domain.TournamentStatus;
|
import nl.connectedit.swiss.domain.TournamentStatus;
|
||||||
import nl.connectedit.swiss.dto.TournamentRegistrationDto;
|
import nl.connectedit.swiss.dto.TournamentRegistrationDto;
|
||||||
import nl.connectedit.swiss.mapper.TournamentPlayerRegistrationMapper;
|
import nl.connectedit.swiss.mapper.TournamentPlayerRegistrationMapper;
|
||||||
@@ -20,6 +22,7 @@ import java.util.List;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@CrossOrigin
|
@CrossOrigin
|
||||||
|
@RolesAllowed(Roles.USER)
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class RegistrationController {
|
public class RegistrationController {
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ package nl.connectedit.swiss.controller;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
import nl.connectedit.swiss.auth.Roles;
|
||||||
import nl.connectedit.swiss.domain.*;
|
import nl.connectedit.swiss.domain.*;
|
||||||
import nl.connectedit.swiss.domain.entity.Player;
|
import nl.connectedit.swiss.domain.entity.Player;
|
||||||
import nl.connectedit.swiss.domain.entity.Registration;
|
import nl.connectedit.swiss.domain.entity.Registration;
|
||||||
@@ -39,6 +41,7 @@ import static nl.connectedit.swiss.domain.PlayerStrength.*;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@CrossOrigin
|
@CrossOrigin
|
||||||
|
@RolesAllowed(Roles.USER)
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class TestController {
|
public class TestController {
|
||||||
|
|
||||||
@@ -95,7 +98,7 @@ public class TestController {
|
|||||||
var eventIdHE = tournament.getEvents().stream().filter(event -> event.getType().equals("HE")).findFirst().get().getId();
|
var eventIdHE = tournament.getEvents().stream().filter(event -> event.getType().equals("HE")).findFirst().get().getId();
|
||||||
var eventIdDE = tournament.getEvents().stream().filter(event -> event.getType().equals("DE")).findFirst().get().getId();
|
var eventIdDE = tournament.getEvents().stream().filter(event -> event.getType().equals("DE")).findFirst().get().getId();
|
||||||
|
|
||||||
for (var player : getPlayers()) {
|
for (var player : getPlayers().subList(0, 31)) {
|
||||||
var tournamentRegistrationDto = new TournamentRegistrationDto();
|
var tournamentRegistrationDto = new TournamentRegistrationDto();
|
||||||
tournamentRegistrationDto.setId(tournament.getId());
|
tournamentRegistrationDto.setId(tournament.getId());
|
||||||
var eventRegistrationDto = new EventRegistrationDto();
|
var eventRegistrationDto = new EventRegistrationDto();
|
||||||
@@ -162,12 +165,13 @@ public class TestController {
|
|||||||
|
|
||||||
private TournamentDto getTournament() {
|
private TournamentDto getTournament() {
|
||||||
var tournamentDto = new TournamentDto();
|
var tournamentDto = new TournamentDto();
|
||||||
tournamentDto.setName("Testtoernooi");
|
tournamentDto.setName("Testtoernooi aangemaakt op " + LocalDate.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy")));
|
||||||
tournamentDto.setDate("14-12-2024");
|
tournamentDto.setDate("14-12-2024");
|
||||||
tournamentDto.setStatus("UPCOMING");
|
tournamentDto.setStatus("UPCOMING");
|
||||||
tournamentDto.setMaxEvents(2L);
|
tournamentDto.setMaxEvents(2L);
|
||||||
tournamentDto.setCourts(9L);
|
tournamentDto.setCourts(9L);
|
||||||
tournamentDto.setCostsPerEvent(List.of(6f, 10f, 0f));
|
tournamentDto.setCostsPerEvent(List.of(6f, 10f, 0f));
|
||||||
|
tournamentDto.setActive(true);
|
||||||
return tournamentDto;
|
return tournamentDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package nl.connectedit.swiss.controller;
|
package nl.connectedit.swiss.controller;
|
||||||
|
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import nl.connectedit.swiss.auth.Roles;
|
||||||
import nl.connectedit.swiss.domain.TournamentStatus;
|
import nl.connectedit.swiss.domain.TournamentStatus;
|
||||||
import nl.connectedit.swiss.domain.entity.Tournament;
|
import nl.connectedit.swiss.domain.entity.Tournament;
|
||||||
import nl.connectedit.swiss.dto.ResultDto;
|
import nl.connectedit.swiss.dto.ResultDto;
|
||||||
import nl.connectedit.swiss.dto.TournamentDto;
|
import nl.connectedit.swiss.dto.TournamentDto;
|
||||||
|
import nl.connectedit.swiss.dto.TournamentPlayerSubstitutionDto;
|
||||||
import nl.connectedit.swiss.dto.TournamentValidationDto;
|
import nl.connectedit.swiss.dto.TournamentValidationDto;
|
||||||
import nl.connectedit.swiss.mapper.TournamentMapper;
|
import nl.connectedit.swiss.mapper.TournamentMapper;
|
||||||
import nl.connectedit.swiss.mapper.TournamentValidationMapper;
|
import nl.connectedit.swiss.mapper.TournamentValidationMapper;
|
||||||
@@ -19,179 +22,208 @@ import java.util.Objects;
|
|||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@CrossOrigin
|
@CrossOrigin
|
||||||
|
@RolesAllowed(Roles.USER)
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class TournamentController {
|
public class TournamentController {
|
||||||
|
|
||||||
private final TournamentService tournamentService;
|
private final TournamentService tournamentService;
|
||||||
|
|
||||||
private final TournamentMapper tournamentMapper;
|
private final TournamentMapper tournamentMapper;
|
||||||
|
|
||||||
private final TournamentValidationService tournamentValidationService;
|
private final TournamentValidationService tournamentValidationService;
|
||||||
|
|
||||||
private final TournamentValidationMapper tournamentValidationMapper;
|
private final TournamentValidationMapper tournamentValidationMapper;
|
||||||
|
|
||||||
private final TournamentDivideService tournamentDivideService;
|
private final TournamentDivideService tournamentDivideService;
|
||||||
|
|
||||||
private final TournamentDrawService tournamentDrawService;
|
private final TournamentDrawService tournamentDrawService;
|
||||||
|
|
||||||
private final TournamentPlayService tournamentPlayService;
|
private final TournamentPlayService tournamentPlayService;
|
||||||
|
|
||||||
@GetMapping("/tournaments")
|
@GetMapping("/tournaments")
|
||||||
public ResponseEntity<List<TournamentDto>> getTournaments(@RequestParam(value = "status", required = false) TournamentStatus status) {
|
public ResponseEntity<List<TournamentDto>> getTournaments(@RequestParam(value = "status", required = false) TournamentStatus status) {
|
||||||
List<Tournament> tournaments;
|
List<Tournament> tournaments;
|
||||||
|
|
||||||
if (Objects.nonNull(status)) {
|
if (Objects.nonNull(status)) {
|
||||||
tournaments = tournamentService.findAllTournamentsWithStatus(status);
|
tournaments = tournamentService.findAllTournamentsWithStatus(status);
|
||||||
} else {
|
} else {
|
||||||
tournaments = tournamentService.findAllTournaments();
|
tournaments = tournamentService.findAllTournaments();
|
||||||
}
|
|
||||||
|
|
||||||
return ResponseEntity.ok(tournaments
|
|
||||||
.stream()
|
|
||||||
.map(tournamentMapper::toDto)
|
|
||||||
.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/tournaments/{id}")
|
return ResponseEntity.ok(tournaments
|
||||||
@Transactional
|
.stream()
|
||||||
public ResponseEntity<TournamentDto> getTournament(@PathVariable Long id) {
|
.map(tournamentMapper::toDto)
|
||||||
var tournament = tournamentService.findTournamentById(id);
|
.toList());
|
||||||
|
}
|
||||||
|
|
||||||
if (tournament == null) {
|
@GetMapping("/tournaments/{id}")
|
||||||
return ResponseEntity.notFound().build();
|
@Transactional
|
||||||
}
|
public ResponseEntity<TournamentDto> getTournament(@PathVariable Long id) {
|
||||||
|
var tournament = tournamentService.findTournamentById(id);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournament));
|
if (tournament == null) {
|
||||||
|
return ResponseEntity.notFound().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments")
|
return ResponseEntity.ok(tournamentMapper.toDto(tournament));
|
||||||
public ResponseEntity<TournamentDto> createTournament(@RequestBody TournamentDto tournamentDto) {
|
}
|
||||||
Tournament tournament;
|
|
||||||
try {
|
@PostMapping("/tournaments")
|
||||||
tournament = tournamentMapper.toEntity(tournamentDto);
|
public ResponseEntity<TournamentDto> createTournament(@RequestBody TournamentDto tournamentDto) {
|
||||||
} catch (NullPointerException | DateTimeParseException e) {
|
Tournament tournament;
|
||||||
return ResponseEntity.badRequest().build();
|
try {
|
||||||
}
|
tournament = tournamentMapper.toEntity(tournamentDto);
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentService.saveTournament(tournament)));
|
} catch (NullPointerException | DateTimeParseException e) {
|
||||||
|
return ResponseEntity.badRequest().build();
|
||||||
}
|
}
|
||||||
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentService.saveTournament(tournament)));
|
||||||
|
}
|
||||||
|
|
||||||
@PutMapping("/tournaments/{id}")
|
@PutMapping("/tournaments/{id}")
|
||||||
public ResponseEntity<TournamentDto> updateTournament(@PathVariable Long id, @RequestBody TournamentDto tournamentDto) {
|
public ResponseEntity<TournamentDto> updateTournament(@PathVariable Long id, @RequestBody TournamentDto tournamentDto) {
|
||||||
var newTournament = tournamentMapper.toEntity(tournamentDto);
|
var newTournament = tournamentMapper.toEntity(tournamentDto);
|
||||||
var tournament = tournamentService.updateTournament(id, newTournament);
|
var tournament = tournamentService.updateTournament(id, newTournament);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournament));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournament));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/tournaments/{id}/validate")
|
@GetMapping("/tournaments/{id}/validate")
|
||||||
public ResponseEntity<TournamentValidationDto> validateTournament(@PathVariable Long id) {
|
public ResponseEntity<TournamentValidationDto> validateTournament(@PathVariable Long id) {
|
||||||
var tournament = tournamentService.findTournamentById(id);
|
var tournament = tournamentService.findTournamentById(id);
|
||||||
|
|
||||||
var tournamentValidation = tournamentValidationService.validate(tournament);
|
var tournamentValidation = tournamentValidationService.validate(tournament);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentValidationMapper.toDto(tournamentValidation));
|
return ResponseEntity.ok(tournamentValidationMapper.toDto(tournamentValidation));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments/{id}/divide")
|
@PostMapping("/tournaments/{id}/divide")
|
||||||
public ResponseEntity<TournamentDto> divideTournamentNew(@PathVariable Long id) {
|
public ResponseEntity<TournamentDto> divideTournamentNew(@PathVariable Long id) {
|
||||||
var tournament = tournamentService.findTournamentById(id);
|
var tournament = tournamentService.findTournamentById(id);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentDivideService.divide(tournament)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentDivideService.divide(tournament)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/tournaments/{id}/divide/clear")
|
@PostMapping("/tournaments/{id}/divide/clear")
|
||||||
public ResponseEntity<TournamentDto> clearTournamentDivision(@PathVariable Long id) {
|
public ResponseEntity<TournamentDto> clearTournamentDivision(@PathVariable Long id) {
|
||||||
var tournament = tournamentService.findTournamentById(id);
|
var tournament = tournamentService.findTournamentById(id);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentDivideService.clear(tournament)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentDivideService.clear(tournament)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments/{id}/draw")
|
@PostMapping("/tournaments/{id}/draw")
|
||||||
public ResponseEntity<TournamentDto> drawTournament(@PathVariable Long id) {
|
public ResponseEntity<TournamentDto> drawTournament(@PathVariable Long id) {
|
||||||
var tournament = tournamentService.findTournamentById(id);
|
var tournament = tournamentService.findTournamentById(id);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentDrawService.draw(tournament)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentDrawService.draw(tournament)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments/{id}/draw/clear")
|
@PostMapping("/tournaments/{id}/draw/clear")
|
||||||
public ResponseEntity<TournamentDto> clearTournamentDraw(@PathVariable Long id) {
|
public ResponseEntity<TournamentDto> clearTournamentDraw(@PathVariable Long id) {
|
||||||
var tournament = tournamentService.findTournamentById(id);
|
var tournament = tournamentService.findTournamentById(id);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentDrawService.clear(tournament)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentDrawService.clear(tournament)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments/{tournamentId}/rounds/{roundId}/start")
|
@PostMapping("/tournaments/{tournamentId}/rounds/{roundId}/start")
|
||||||
public ResponseEntity<TournamentDto> startRound(@PathVariable Long tournamentId, @PathVariable Long roundId) {
|
public ResponseEntity<TournamentDto> startRound(@PathVariable Long tournamentId, @PathVariable Long roundId) {
|
||||||
var tournament = tournamentService.findTournamentById(tournamentId);
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.startRound(tournament, roundId)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.startRound(tournament, roundId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments/{tournamentId}/rounds/{roundId}/finish")
|
@PostMapping("/tournaments/{tournamentId}/rounds/{roundId}/finish")
|
||||||
public ResponseEntity<TournamentDto> finishRound(@PathVariable Long tournamentId, @PathVariable Long roundId) {
|
public ResponseEntity<TournamentDto> finishRound(@PathVariable Long tournamentId, @PathVariable Long roundId) {
|
||||||
var tournament = tournamentService.findTournamentById(tournamentId);
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.finishRound(tournament, roundId)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.finishRound(tournament, roundId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments/{tournamentId}/groups/{groupId}/finish")
|
@PostMapping("/tournaments/{tournamentId}/groups/{groupId}/finish")
|
||||||
public ResponseEntity<TournamentDto> finishGroup(@PathVariable Long tournamentId, @PathVariable Long groupId) {
|
public ResponseEntity<TournamentDto> finishGroup(@PathVariable Long tournamentId, @PathVariable Long groupId) {
|
||||||
var tournament = tournamentService.findTournamentById(tournamentId);
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.finishGroup(tournament, groupId)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.finishGroup(tournament, groupId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments/{tournamentId}/groups/{groupId}/reopen")
|
@PostMapping("/tournaments/{tournamentId}/groups/{groupId}/reopen")
|
||||||
public ResponseEntity<TournamentDto> reopenGroup(@PathVariable Long tournamentId, @PathVariable Long groupId) {
|
public ResponseEntity<TournamentDto> reopenGroup(@PathVariable Long tournamentId, @PathVariable Long groupId) {
|
||||||
var tournament = tournamentService.findTournamentById(tournamentId);
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.reopenGroup(tournament, groupId)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.reopenGroup(tournament, groupId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments/{tournamentId}/groups/{groupId}/new")
|
@PostMapping("/tournaments/{tournamentId}/groups/{groupId}/new")
|
||||||
public ResponseEntity<TournamentDto> newRound(@PathVariable Long tournamentId, @PathVariable Long groupId) {
|
public ResponseEntity<TournamentDto> newRound(@PathVariable Long tournamentId, @PathVariable Long groupId) {
|
||||||
var tournament = tournamentService.findTournamentById(tournamentId);
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.newRound(tournament, groupId)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.newRound(tournament, groupId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments/{tournamentId}/matches/{matchId}/start/{court}")
|
@PostMapping("/tournaments/{tournamentId}/matches/{matchId}/start")
|
||||||
public ResponseEntity<TournamentDto> startMatch(@PathVariable Long tournamentId, @PathVariable Long matchId, @PathVariable Long court) {
|
public ResponseEntity<TournamentDto> startMatch(@PathVariable Long tournamentId,
|
||||||
var tournament = tournamentService.findTournamentById(tournamentId);
|
@PathVariable Long matchId,
|
||||||
|
@RequestParam("court") Long court,
|
||||||
|
@RequestParam("counter") Long counter) {
|
||||||
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.startMatch(tournament, matchId, court)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.startMatch(tournament, matchId, court, counter)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments/{tournamentId}/matches/{matchId}/stop")
|
@PostMapping("/tournaments/{tournamentId}/matches/{matchId}/stop")
|
||||||
public ResponseEntity<TournamentDto> stopMatch(@PathVariable Long tournamentId, @PathVariable Long matchId) {
|
public ResponseEntity<TournamentDto> stopMatch(@PathVariable Long tournamentId, @PathVariable Long matchId) {
|
||||||
var tournament = tournamentService.findTournamentById(tournamentId);
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.stopMatch(tournament, matchId)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.stopMatch(tournament, matchId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/tournaments/{tournamentId}/matches/{matchId}")
|
@PostMapping("/tournaments/{tournamentId}/matches/{matchId}")
|
||||||
public ResponseEntity<TournamentDto> saveResult(@PathVariable Long tournamentId, @PathVariable Long matchId, @RequestBody ResultDto resultDto) {
|
public ResponseEntity<TournamentDto> saveResult(@PathVariable Long tournamentId,
|
||||||
var tournament = tournamentService.findTournamentById(tournamentId);
|
@PathVariable Long matchId,
|
||||||
|
@RequestBody ResultDto resultDto) {
|
||||||
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.saveResult(tournament, matchId, resultDto)));
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.saveResult(tournament, matchId, resultDto)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping("/tournaments/{tournamentId}/players/{playerId}/paid/{paid}")
|
@PatchMapping("/tournaments/{tournamentId}/players/{playerId}/paid/{paid}")
|
||||||
public ResponseEntity<Void> updatePaid(@PathVariable Long tournamentId, @PathVariable Long playerId, @PathVariable Boolean paid) {
|
public ResponseEntity<Void> updatePaid(@PathVariable Long tournamentId,
|
||||||
var tournament = tournamentService.findTournamentById(tournamentId);
|
@PathVariable Long playerId,
|
||||||
|
@PathVariable Boolean paid) {
|
||||||
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
tournamentPlayService.updatePaid(tournament, playerId, paid);
|
tournamentPlayService.updatePaid(tournament, playerId, paid);
|
||||||
|
|
||||||
return ResponseEntity.noContent().build();
|
return ResponseEntity.noContent().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping("/tournaments/{tournamentId}/players/{playerId}/present/{present}")
|
@PatchMapping("/tournaments/{tournamentId}/players/{playerId}/present/{present}")
|
||||||
public ResponseEntity<Void> updatePresent(@PathVariable Long tournamentId, @PathVariable Long playerId, @PathVariable Boolean present) {
|
public ResponseEntity<Void> updatePresent(@PathVariable Long tournamentId,
|
||||||
var tournament = tournamentService.findTournamentById(tournamentId);
|
@PathVariable Long playerId,
|
||||||
|
@PathVariable Boolean present) {
|
||||||
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
tournamentPlayService.updatePresent(tournament, playerId, present);
|
tournamentPlayService.updatePresent(tournament, playerId, present);
|
||||||
|
|
||||||
|
return ResponseEntity.noContent().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/tournaments/{tournamentId}/players/{playerId}/substitutions")
|
||||||
|
public ResponseEntity<TournamentDto> substitutePlayer(@PathVariable Long tournamentId,
|
||||||
|
@PathVariable Long playerId,
|
||||||
|
@RequestBody TournamentPlayerSubstitutionDto[] substitutions) {
|
||||||
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.playerSubstitutions(tournament, playerId, substitutions)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/tournaments/{tournamentId}/matches/{matchId}/update")
|
||||||
|
public ResponseEntity<TournamentDto> updateCounter(@PathVariable Long tournamentId,
|
||||||
|
@PathVariable Long matchId,
|
||||||
|
@RequestParam("counter") Long counter) {
|
||||||
|
var tournament = tournamentService.findTournamentById(tournamentId);
|
||||||
|
|
||||||
|
return ResponseEntity.ok(tournamentMapper.toDto(tournamentPlayService.updateCounter(tournament, matchId, counter)));
|
||||||
|
}
|
||||||
|
|
||||||
return ResponseEntity.noContent().build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package nl.connectedit.swiss.dto;
|
package nl.connectedit.swiss.domain;
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
@@ -27,8 +27,7 @@ public class Event extends AbstractEntity {
|
|||||||
private Tournament tournament;
|
private Tournament tournament;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
||||||
// @Builder.Default
|
private List<Registration> registrations;
|
||||||
private List<Registration> registrations;// = new ArrayList<>();
|
|
||||||
|
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private Status status;
|
private Status status;
|
||||||
@@ -37,7 +36,7 @@ public class Event extends AbstractEntity {
|
|||||||
private EventType type;
|
private EventType type;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
||||||
private List<Group> groups;// = new ArrayList<>();
|
private List<Group> groups;
|
||||||
|
|
||||||
public static List<Event> getBlankEventSet(Tournament tournament) {
|
public static List<Event> getBlankEventSet(Tournament tournament) {
|
||||||
return Arrays.stream(EventType.values())
|
return Arrays.stream(EventType.values())
|
||||||
|
|||||||
@@ -31,9 +31,14 @@ public class Group extends AbstractEntity {
|
|||||||
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||||
@OrderBy("name")
|
@OrderBy("name")
|
||||||
private List<Round> rounds;// = new ArrayList<>();
|
private List<Round> rounds;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)
|
||||||
private List<Team> teams;// = new ArrayList<>();
|
@JoinTable(
|
||||||
|
name = "eventgroup_teams",
|
||||||
|
joinColumns = @JoinColumn(name = "group_id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "teams_id")
|
||||||
|
)
|
||||||
|
private List<Team> teams = new ArrayList<>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,11 @@ public class Match extends AbstractEntity {
|
|||||||
|
|
||||||
private Long court;
|
private Long court;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Player counter;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
||||||
private List<Game> games;// = new ArrayList<>();
|
private List<Game> games;
|
||||||
|
|
||||||
private LocalDateTime startTime;
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
|
|||||||
@@ -28,12 +28,15 @@ public class Round extends AbstractEntity {
|
|||||||
private Status status;
|
private Status status;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
||||||
private List<Match> matches;// = new ArrayList<>();
|
@OrderBy("id")
|
||||||
|
private List<Match> matches;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
@OneToMany(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
|
||||||
private List<Team> quit;// = new ArrayList<>();
|
private List<Team> quit;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
private Team drawnOut;
|
private Team drawnOut;
|
||||||
|
|
||||||
|
private Boolean isFinalsRound = Boolean.FALSE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package nl.connectedit.swiss.domain.entity;
|
|||||||
|
|
||||||
import jakarta.annotation.Nullable;
|
import jakarta.annotation.Nullable;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@@ -17,8 +19,8 @@ public class Team extends AbstractEntity {
|
|||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToMany(mappedBy = "teams", fetch = FetchType.LAZY)
|
||||||
private Group group;
|
private List<Group> groups = new ArrayList<>();
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
private Player player1;
|
private Player player1;
|
||||||
|
|||||||
@@ -28,4 +28,16 @@ public class TournamentPlayer extends AbstractEntity {
|
|||||||
private boolean paid;
|
private boolean paid;
|
||||||
|
|
||||||
private boolean present;
|
private boolean present;
|
||||||
|
|
||||||
|
private boolean counting;
|
||||||
|
|
||||||
|
private Long counts = 0L;
|
||||||
|
|
||||||
|
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||||
|
private List<TournamentPlayerSubstitution> substitutions;
|
||||||
|
|
||||||
|
public void incrementCounts() {
|
||||||
|
this.counts++;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package nl.connectedit.swiss.domain.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TournamentPlayerSubstitution extends AbstractEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
// @ManyToMany(mappedBy = "substitutions", fetch = FetchType.LAZY)
|
||||||
|
// private List<TournamentPlayer> tournamentPlayer;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Event event;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private TournamentPlayer substitute;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -29,4 +29,6 @@ public class MatchDto extends AbstractDto {
|
|||||||
private LocalDateTime endTime;
|
private LocalDateTime endTime;
|
||||||
|
|
||||||
private Long court;
|
private Long court;
|
||||||
|
|
||||||
|
private PlayerDto counter;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,4 +23,7 @@ public class RoundDto extends AbstractDto {
|
|||||||
|
|
||||||
private StandingsDto standings;
|
private StandingsDto standings;
|
||||||
|
|
||||||
|
private Boolean isFinalsRound;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package nl.connectedit.swiss.dto;
|
|||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import nl.connectedit.swiss.domain.entity.TournamentPlayerSubstitution;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -31,4 +32,12 @@ public class TournamentDto extends AbstractDto {
|
|||||||
|
|
||||||
private Boolean active;
|
private Boolean active;
|
||||||
|
|
||||||
|
private List<TournamentPlayerSubstitutionDto> substitutions;
|
||||||
|
|
||||||
|
private List<Long> playersPlaying;
|
||||||
|
|
||||||
|
private List<Long> playersCounting;
|
||||||
|
|
||||||
|
private List<Long> playersAvailable;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import java.util.List;
|
|||||||
@Setter
|
@Setter
|
||||||
public class TournamentPlayerDto extends AbstractDto {
|
public class TournamentPlayerDto extends AbstractDto {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
private Long playerId;
|
private Long playerId;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
@@ -20,4 +22,10 @@ public class TournamentPlayerDto extends AbstractDto {
|
|||||||
|
|
||||||
private Boolean present;
|
private Boolean present;
|
||||||
|
|
||||||
|
private Boolean counting;
|
||||||
|
|
||||||
|
private Long counts;
|
||||||
|
|
||||||
|
private List<TournamentPlayerSubstitutionDto> substitutions;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package nl.connectedit.swiss.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TournamentPlayerSubstitutionDto extends AbstractDto {
|
||||||
|
|
||||||
|
private Long substitutionId;
|
||||||
|
|
||||||
|
private String event;
|
||||||
|
|
||||||
|
// private TournamentPlayerDto substitute;
|
||||||
|
private Long substitute;
|
||||||
|
}
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
package nl.connectedit.swiss.mapper;
|
package nl.connectedit.swiss.mapper;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import nl.connectedit.swiss.domain.EventType;
|
||||||
import nl.connectedit.swiss.domain.Status;
|
import nl.connectedit.swiss.domain.Status;
|
||||||
import nl.connectedit.swiss.domain.entity.Event;
|
import nl.connectedit.swiss.domain.entity.Event;
|
||||||
import nl.connectedit.swiss.domain.EventType;
|
import nl.connectedit.swiss.domain.entity.Group;
|
||||||
import nl.connectedit.swiss.dto.EventDto;
|
import nl.connectedit.swiss.dto.EventDto;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class EventMapper implements DtoMapper<Event, EventDto>, EntityMapper<EventDto, Event> {
|
public class EventMapper implements DtoMapper<Event, EventDto>, EntityMapper<EventDto, Event> {
|
||||||
@@ -56,6 +59,7 @@ public class EventMapper implements DtoMapper<Event, EventDto>, EntityMapper<Eve
|
|||||||
eventDto.setGroups(
|
eventDto.setGroups(
|
||||||
event.getGroups()
|
event.getGroups()
|
||||||
.stream()
|
.stream()
|
||||||
|
.sorted(Comparator.comparing(Group::getName))
|
||||||
.map(groupMapper::toDto)
|
.map(groupMapper::toDto)
|
||||||
.toList()
|
.toList()
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ public class MatchMapper implements DtoMapper<Match, MatchDto> {
|
|||||||
|
|
||||||
private final GameMapper gameMapper;
|
private final GameMapper gameMapper;
|
||||||
|
|
||||||
|
private final PlayerMapper playerMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MatchDto toDto(Match match) {
|
public MatchDto toDto(Match match) {
|
||||||
var matchDto = new MatchDto();
|
var matchDto = new MatchDto();
|
||||||
@@ -25,6 +27,9 @@ public class MatchMapper implements DtoMapper<Match, MatchDto> {
|
|||||||
matchDto.setStartTime(match.getStartTime());
|
matchDto.setStartTime(match.getStartTime());
|
||||||
matchDto.setEndTime(match.getEndTime());
|
matchDto.setEndTime(match.getEndTime());
|
||||||
matchDto.setCourt(match.getCourt());
|
matchDto.setCourt(match.getCourt());
|
||||||
|
if (match.getCounter() != null) {
|
||||||
|
matchDto.setCounter(playerMapper.toDto(match.getCounter()));
|
||||||
|
}
|
||||||
|
|
||||||
if (match.getGames() != null) {
|
if (match.getGames() != null) {
|
||||||
matchDto.setGames(
|
matchDto.setGames(
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package nl.connectedit.swiss.mapper;
|
package nl.connectedit.swiss.mapper;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import nl.connectedit.swiss.domain.entity.Group;
|
|
||||||
import nl.connectedit.swiss.domain.entity.Round;
|
import nl.connectedit.swiss.domain.entity.Round;
|
||||||
import nl.connectedit.swiss.domain.entity.Team;
|
import nl.connectedit.swiss.domain.entity.Team;
|
||||||
import nl.connectedit.swiss.dto.RoundDto;
|
import nl.connectedit.swiss.dto.RoundDto;
|
||||||
import nl.connectedit.swiss.service.StandingsService;
|
import nl.connectedit.swiss.service.StandingsService;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class RoundMapper {
|
public class RoundMapper {
|
||||||
@@ -45,6 +45,8 @@ public class RoundMapper {
|
|||||||
var standings = standingsService.getStandings(roundsForStandings, teamsForStandings);
|
var standings = standingsService.getStandings(roundsForStandings, teamsForStandings);
|
||||||
roundDto.setStandings(standingsMapper.toDto(standings));
|
roundDto.setStandings(standingsMapper.toDto(standings));
|
||||||
|
|
||||||
|
roundDto.setIsFinalsRound(round.getIsFinalsRound());
|
||||||
|
|
||||||
return roundDto;
|
return roundDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package nl.connectedit.swiss.mapper;
|
package nl.connectedit.swiss.mapper;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import nl.connectedit.swiss.domain.StandingsEntry;
|
||||||
|
import nl.connectedit.swiss.dto.StandingsDto;
|
||||||
|
import nl.connectedit.swiss.dto.StandingsEntryDto;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import nl.connectedit.swiss.dto.StandingsDto;
|
|
||||||
import nl.connectedit.swiss.dto.StandingsEntry;
|
|
||||||
import nl.connectedit.swiss.dto.StandingsEntryDto;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
|||||||
@@ -1,83 +1,186 @@
|
|||||||
package nl.connectedit.swiss.mapper;
|
package nl.connectedit.swiss.mapper;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import nl.connectedit.swiss.domain.EventType;
|
||||||
|
import nl.connectedit.swiss.domain.Status;
|
||||||
|
import nl.connectedit.swiss.domain.TournamentStatus;
|
||||||
|
import nl.connectedit.swiss.domain.entity.*;
|
||||||
|
import nl.connectedit.swiss.dto.TournamentDto;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import lombok.RequiredArgsConstructor;
|
import java.util.Comparator;
|
||||||
import nl.connectedit.swiss.domain.entity.Tournament;
|
import java.util.List;
|
||||||
import nl.connectedit.swiss.domain.TournamentStatus;
|
import java.util.stream.Collectors;
|
||||||
import nl.connectedit.swiss.domain.entity.TournamentPlayer;
|
|
||||||
import nl.connectedit.swiss.dto.TournamentDto;
|
|
||||||
import nl.connectedit.swiss.dto.TournamentPlayerDto;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class TournamentMapper implements DtoMapper<Tournament, TournamentDto>, EntityMapper<TournamentDto, Tournament> {
|
public class TournamentMapper implements DtoMapper<Tournament, TournamentDto>, EntityMapper<TournamentDto, Tournament> {
|
||||||
|
|
||||||
private final EventMapper eventMapper;
|
private final EventMapper eventMapper;
|
||||||
|
|
||||||
private final TournamentPlayerMapper tournamentPlayerMapper;
|
private final TournamentPlayerMapper tournamentPlayerMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tournament toEntity(TournamentDto tournamentDto) {
|
public Tournament toEntity(TournamentDto tournamentDto) {
|
||||||
Tournament tournament = new Tournament();
|
Tournament tournament = new Tournament();
|
||||||
tournament.setId(tournamentDto.getId());
|
tournament.setId(tournamentDto.getId());
|
||||||
tournament.setName(tournamentDto.getName());
|
tournament.setName(tournamentDto.getName());
|
||||||
tournament.setDate(LocalDate.parse(tournamentDto.getDate(), DateTimeFormatter.ofPattern("dd-MM-yyyy")));
|
tournament.setDate(LocalDate.parse(tournamentDto.getDate(), DateTimeFormatter.ofPattern("dd-MM-yyyy")));
|
||||||
tournament.setStatus(
|
tournament.setStatus(
|
||||||
Arrays.stream(TournamentStatus.values())
|
Arrays.stream(TournamentStatus.values())
|
||||||
.filter(ts -> ts.getText().equals(tournamentDto.getStatus()))
|
.filter(ts -> ts.getText().equals(tournamentDto.getStatus()))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(TournamentStatus.UPCOMING)
|
.orElse(TournamentStatus.UPCOMING)
|
||||||
);
|
);
|
||||||
tournament.setActive(tournamentDto.getActive());
|
tournament.setActive(tournamentDto.getActive());
|
||||||
tournament.setMaxEvents(tournamentDto.getMaxEvents());
|
tournament.setMaxEvents(tournamentDto.getMaxEvents());
|
||||||
tournament.setCostsPerEvent(tournamentDto.getCostsPerEvent());
|
tournament.setCostsPerEvent(tournamentDto.getCostsPerEvent());
|
||||||
tournament.setCourts(tournamentDto.getCourts());
|
tournament.setCourts(tournamentDto.getCourts());
|
||||||
|
|
||||||
return tournament;
|
return tournament;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TournamentDto toDto(Tournament tournament) {
|
||||||
|
TournamentDto tournamentDto = new TournamentDto();
|
||||||
|
tournamentDto.setId(tournament.getId());
|
||||||
|
tournamentDto.setName(tournament.getName());
|
||||||
|
tournamentDto.setDate(tournament.getDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy")));
|
||||||
|
tournamentDto.setStatus(tournament.getStatus().name());
|
||||||
|
tournamentDto.setActive(tournament.getActive());
|
||||||
|
tournamentDto.setEvents(
|
||||||
|
tournament.getEvents()
|
||||||
|
.stream()
|
||||||
|
.sorted(Comparator.comparing(Event::getType))
|
||||||
|
.map(eventMapper::toDto)
|
||||||
|
.toList()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (tournament.getTournamentPlayers() != null) {
|
||||||
|
var tournamentPlayers = tournament.getTournamentPlayers();
|
||||||
|
|
||||||
|
tournamentPlayers.sort(Comparator.comparing((TournamentPlayer tournamentPlayer) -> tournamentPlayer.getPlayer().getLastName())
|
||||||
|
.thenComparing((TournamentPlayer tournamentPlayer) -> tournamentPlayer.getPlayer().getFirstName()));
|
||||||
|
|
||||||
|
tournamentDto.setTournamentPlayers(tournamentPlayers
|
||||||
|
.stream()
|
||||||
|
.map(tournamentPlayerMapper::toDto)
|
||||||
|
.toList()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
tournamentDto.setMaxEvents(tournament.getMaxEvents() == null ? 2L : tournament.getMaxEvents());
|
||||||
public TournamentDto toDto(Tournament tournament) {
|
|
||||||
TournamentDto tournamentDto = new TournamentDto();
|
|
||||||
tournamentDto.setId(tournament.getId());
|
|
||||||
tournamentDto.setName(tournament.getName());
|
|
||||||
tournamentDto.setDate(tournament.getDate().format(DateTimeFormatter.ofPattern("dd-MM-yyyy")));
|
|
||||||
tournamentDto.setStatus(tournament.getStatus().name());
|
|
||||||
tournamentDto.setActive(tournament.getActive());
|
|
||||||
tournamentDto.setEvents(
|
|
||||||
tournament.getEvents()
|
|
||||||
.stream()
|
|
||||||
.map(eventMapper::toDto)
|
|
||||||
.toList()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (tournament.getTournamentPlayers() != null) {
|
if (tournament.getCostsPerEvent() == null || tournament.getCostsPerEvent().isEmpty()) {
|
||||||
var tournamentPlayers = tournament.getTournamentPlayers();
|
tournamentDto.setCostsPerEvent(List.of(0f, 0f, 0f));
|
||||||
|
} else {
|
||||||
tournamentPlayers.sort(Comparator.comparing((TournamentPlayer tournamentPlayer) -> tournamentPlayer.getPlayer().getLastName())
|
tournamentDto.setCostsPerEvent(tournament.getCostsPerEvent());
|
||||||
.thenComparing((TournamentPlayer tournamentPlayer) -> tournamentPlayer.getPlayer().getFirstName()));
|
|
||||||
|
|
||||||
tournamentDto.setTournamentPlayers(tournamentPlayers
|
|
||||||
.stream()
|
|
||||||
.map(tournamentPlayerMapper::toDto)
|
|
||||||
.toList()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
tournamentDto.setMaxEvents(tournament.getMaxEvents() == null ? 2L : tournament.getMaxEvents());
|
|
||||||
|
|
||||||
if (tournament.getCostsPerEvent() == null || tournament.getCostsPerEvent().isEmpty()) {
|
|
||||||
tournamentDto.setCostsPerEvent(List.of(0f, 0f, 0f));
|
|
||||||
} else {
|
|
||||||
tournamentDto.setCostsPerEvent(tournament.getCostsPerEvent());
|
|
||||||
}
|
|
||||||
|
|
||||||
tournamentDto.setCourts(tournament.getCourts() == null ? 1L : tournament.getCourts());
|
|
||||||
|
|
||||||
return tournamentDto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tournamentDto.setCourts(tournament.getCourts() == null ? 1L : tournament.getCourts());
|
||||||
|
|
||||||
|
tournamentDto.setPlayersCounting(getPlayersCounting(tournament));
|
||||||
|
tournamentDto.setPlayersPlaying(getPlayersPlaying(tournament));
|
||||||
|
tournamentDto.setPlayersAvailable(getPlayersAvailable(tournament));
|
||||||
|
|
||||||
|
return tournamentDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Long> getPlayersCounting(Tournament tournament) {
|
||||||
|
var playersCounting = new ArrayList<Long>();
|
||||||
|
|
||||||
|
for (var event : tournament.getEvents()) {
|
||||||
|
if (event.getGroups() != null) {
|
||||||
|
for (var group : event.getGroups()) {
|
||||||
|
if (group.getRounds() != null) {
|
||||||
|
for (var round : group.getRounds()) {
|
||||||
|
for (var match : round.getMatches()) {
|
||||||
|
if (match.getStatus() == Status.IN_PROGRESS && match.getCounter() != null) {
|
||||||
|
var counter = getTournamentPlayerFromPlayerId(tournament, match.getCounter().getId());
|
||||||
|
if (counter != null) {
|
||||||
|
playersCounting.add(counter.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return playersCounting;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Long> getPlayersPlaying(Tournament tournament) {
|
||||||
|
var playersPlaying = new ArrayList<Long>();
|
||||||
|
|
||||||
|
for (var event : tournament.getEvents()) {
|
||||||
|
if (event.getGroups() != null) {
|
||||||
|
for (var group : event.getGroups()) {
|
||||||
|
if (group.getRounds() != null) {
|
||||||
|
for (var round : group.getRounds()) {
|
||||||
|
for (var match : round.getMatches()) {
|
||||||
|
if (match.getStatus() == Status.IN_PROGRESS) {
|
||||||
|
playersPlaying.addAll(getPlayersInMatch(tournament, match));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return playersPlaying;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Long> getPlayersAvailable(Tournament tournament) {
|
||||||
|
if (tournament.getTournamentPlayers() == null) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
var playersAvailable = tournament.getTournamentPlayers()
|
||||||
|
.stream()
|
||||||
|
.map(TournamentPlayer::getId)
|
||||||
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
|
|
||||||
|
playersAvailable.removeAll(getPlayersCounting(tournament));
|
||||||
|
playersAvailable.removeAll(getPlayersPlaying(tournament));
|
||||||
|
|
||||||
|
return playersAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Long> getPlayersInMatch(Tournament tournament, Match match) {
|
||||||
|
var playersInMatch = new ArrayList<Long>();
|
||||||
|
playersInMatch.add(getPlayerOrSubstitute(tournament, match.getTeam1().getPlayer1(), match.getType()).getId());
|
||||||
|
playersInMatch.add(getPlayerOrSubstitute(tournament, match.getTeam2().getPlayer1(), match.getType()).getId());
|
||||||
|
if (match.getType().isDoublesEvent()) {
|
||||||
|
playersInMatch.add(getPlayerOrSubstitute(tournament, match.getTeam1().getPlayer2(), match.getType()).getId());
|
||||||
|
playersInMatch.add(getPlayerOrSubstitute(tournament, match.getTeam2().getPlayer2(), match.getType()).getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return playersInMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TournamentPlayer getPlayerOrSubstitute(Tournament tournament, Player player, EventType type) {
|
||||||
|
var tournamentPlayer = getTournamentPlayerFromPlayerId(tournament, player.getId());
|
||||||
|
for (var substitution : tournamentPlayer.getSubstitutions()) {
|
||||||
|
if (substitution.getEvent().getType() == type && substitution.getSubstitute() != null) {
|
||||||
|
return substitution.getSubstitute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tournamentPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TournamentPlayer getTournamentPlayerFromPlayerId(Tournament tournament, Long playerId) {
|
||||||
|
for (var tournamentPlayer : tournament.getTournamentPlayers()) {
|
||||||
|
if (tournamentPlayer.getPlayer().getId().equals(playerId)) {
|
||||||
|
return tournamentPlayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,10 @@ package nl.connectedit.swiss.mapper;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import nl.connectedit.swiss.domain.entity.Team;
|
import nl.connectedit.swiss.domain.entity.Team;
|
||||||
import nl.connectedit.swiss.domain.entity.TournamentPlayer;
|
import nl.connectedit.swiss.domain.entity.TournamentPlayer;
|
||||||
|
import nl.connectedit.swiss.domain.entity.TournamentPlayerSubstitution;
|
||||||
import nl.connectedit.swiss.dto.TeamDto;
|
import nl.connectedit.swiss.dto.TeamDto;
|
||||||
import nl.connectedit.swiss.dto.TournamentPlayerDto;
|
import nl.connectedit.swiss.dto.TournamentPlayerDto;
|
||||||
|
import nl.connectedit.swiss.dto.TournamentPlayerSubstitutionDto;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -13,17 +15,37 @@ import java.util.ArrayList;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class TournamentPlayerMapper implements DtoMapper<TournamentPlayer, TournamentPlayerDto> {
|
public class TournamentPlayerMapper implements DtoMapper<TournamentPlayer, TournamentPlayerDto> {
|
||||||
|
|
||||||
private final PlayerMapper playerMapper;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TournamentPlayerDto toDto(TournamentPlayer tournamentPlayer) {
|
public TournamentPlayerDto toDto(TournamentPlayer tournamentPlayer) {
|
||||||
var tournamentPlayerDto = new TournamentPlayerDto();
|
var tournamentPlayerDto = new TournamentPlayerDto();
|
||||||
|
tournamentPlayerDto.setId(tournamentPlayer.getId());
|
||||||
tournamentPlayerDto.setPlayerId(tournamentPlayer.getPlayer().getId());
|
tournamentPlayerDto.setPlayerId(tournamentPlayer.getPlayer().getId());
|
||||||
tournamentPlayerDto.setName(tournamentPlayer.getPlayer().getFullName());
|
tournamentPlayerDto.setName(tournamentPlayer.getPlayer().getFullName());
|
||||||
tournamentPlayerDto.setEvents(new ArrayList<>(tournamentPlayer.getEvents()));
|
tournamentPlayerDto.setEvents(new ArrayList<>(tournamentPlayer.getEvents()));
|
||||||
tournamentPlayerDto.setPaid(tournamentPlayer.isPaid());
|
tournamentPlayerDto.setPaid(tournamentPlayer.isPaid());
|
||||||
tournamentPlayerDto.setPresent(tournamentPlayer.isPresent());
|
tournamentPlayerDto.setPresent(tournamentPlayer.isPresent());
|
||||||
|
tournamentPlayerDto.setCounting(tournamentPlayer.isCounting());
|
||||||
|
tournamentPlayerDto.setCounts(tournamentPlayer.getCounts());
|
||||||
|
if (tournamentPlayer.getSubstitutions() != null) {
|
||||||
|
tournamentPlayerDto.setSubstitutions(
|
||||||
|
tournamentPlayer.getSubstitutions()
|
||||||
|
.stream()
|
||||||
|
.map(this::mapSubstitution)
|
||||||
|
.toList());
|
||||||
|
}
|
||||||
|
|
||||||
return tournamentPlayerDto;
|
return tournamentPlayerDto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TournamentPlayerSubstitutionDto mapSubstitution(TournamentPlayerSubstitution tournamentPlayerSubstitution) {
|
||||||
|
var tournamentPlayerSubstitutionDto = new TournamentPlayerSubstitutionDto();
|
||||||
|
tournamentPlayerSubstitutionDto.setSubstitutionId(tournamentPlayerSubstitution.getId());
|
||||||
|
tournamentPlayerSubstitutionDto.setEvent(tournamentPlayerSubstitution.getEvent().getType().name());
|
||||||
|
if (tournamentPlayerSubstitution.getSubstitute() != null) {
|
||||||
|
// tournamentPlayerSubstitutionDto.setSubstitute(toDto(tournamentPlayerSubstitution.getSubstitute()));
|
||||||
|
tournamentPlayerSubstitutionDto.setSubstitute(tournamentPlayerSubstitution.getSubstitute().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return tournamentPlayerSubstitutionDto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
package nl.connectedit.swiss.service;
|
package nl.connectedit.swiss.service;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import nl.connectedit.swiss.domain.entity.Player;
|
import nl.connectedit.swiss.domain.entity.*;
|
||||||
import nl.connectedit.swiss.domain.entity.Registration;
|
|
||||||
import nl.connectedit.swiss.domain.entity.Tournament;
|
|
||||||
import nl.connectedit.swiss.dto.EventRegistrationDto;
|
import nl.connectedit.swiss.dto.EventRegistrationDto;
|
||||||
import nl.connectedit.swiss.repository.RegistrationRepository;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -23,6 +20,7 @@ public class RegistrationService {
|
|||||||
|
|
||||||
if (!eventRegistration.isRegistered()) { // remove any existing registration
|
if (!eventRegistration.isRegistered()) { // remove any existing registration
|
||||||
event.getRegistrations().removeIf(registration -> registration.getPlayer().equals(player));
|
event.getRegistrations().removeIf(registration -> registration.getPlayer().equals(player));
|
||||||
|
removeEventFromTournamentPlayer(tournament, player, event);
|
||||||
} else {
|
} else {
|
||||||
var optionalExistingPlayerRegistration = event.getRegistrations().stream()
|
var optionalExistingPlayerRegistration = event.getRegistrations().stream()
|
||||||
.filter(registration -> registration.getPlayer().equals(player))
|
.filter(registration -> registration.getPlayer().equals(player))
|
||||||
@@ -32,14 +30,15 @@ public class RegistrationService {
|
|||||||
newRegistration.setTournament(tournament);
|
newRegistration.setTournament(tournament);
|
||||||
newRegistration.setEvent(event);
|
newRegistration.setEvent(event);
|
||||||
newRegistration.setPlayer(player);
|
newRegistration.setPlayer(player);
|
||||||
if (eventRegistration.getPartner() != null){
|
if (eventRegistration.getPartner() != null) {
|
||||||
var partner = playerService.findPlayerById(eventRegistration.getPartner());
|
var partner = playerService.findPlayerById(eventRegistration.getPartner());
|
||||||
newRegistration.setPartner(partner);
|
newRegistration.setPartner(partner);
|
||||||
}
|
}
|
||||||
event.addRegistration(newRegistration);
|
event.addRegistration(newRegistration);
|
||||||
|
addEventToTournamentPlayer(tournament, player, event);
|
||||||
} else { // change existing registration
|
} else { // change existing registration
|
||||||
var existingPlayerRegistration = optionalExistingPlayerRegistration.get();
|
var existingPlayerRegistration = optionalExistingPlayerRegistration.get();
|
||||||
if (eventRegistration.getPartner() != null){
|
if (eventRegistration.getPartner() != null) {
|
||||||
var partner = playerService.findPlayerById(eventRegistration.getPartner());
|
var partner = playerService.findPlayerById(eventRegistration.getPartner());
|
||||||
existingPlayerRegistration.setPartner(partner);
|
existingPlayerRegistration.setPartner(partner);
|
||||||
} else {
|
} else {
|
||||||
@@ -50,4 +49,44 @@ public class RegistrationService {
|
|||||||
|
|
||||||
tournamentService.saveTournament(tournament);
|
tournamentService.saveTournament(tournament);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeEventFromTournamentPlayer(Tournament tournament, Player player, Event event) {
|
||||||
|
var tournamentPlayer = findOrAddTournamentPlayer(tournament, player);
|
||||||
|
tournamentPlayer.getEvents().removeIf(eventType -> eventType.equals(event.getType().name()));
|
||||||
|
if (tournamentPlayer.getSubstitutions() != null) {
|
||||||
|
tournamentPlayer.getSubstitutions().removeIf(substitution -> substitution.getEvent().equals(event));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addEventToTournamentPlayer(Tournament tournament, Player player, Event event) {
|
||||||
|
var tournamentPlayer = findOrAddTournamentPlayer(tournament, player);
|
||||||
|
tournamentPlayer.getEvents().add(event.getType().name());
|
||||||
|
if (tournamentPlayer.getSubstitutions() == null) {
|
||||||
|
tournamentPlayer.setSubstitutions(new ArrayList<>());
|
||||||
|
}
|
||||||
|
var substitution = new TournamentPlayerSubstitution();
|
||||||
|
substitution.setEvent(event);
|
||||||
|
substitution.setSubstitute(null);
|
||||||
|
tournamentPlayer.getSubstitutions().add(substitution);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TournamentPlayer findOrAddTournamentPlayer(Tournament tournament, Player player) {
|
||||||
|
for (var tournamentPlayer : tournament.getTournamentPlayers()) {
|
||||||
|
if (tournamentPlayer.getPlayer().getId().equals(player.getId())) {
|
||||||
|
return tournamentPlayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return registerTournamentPlayer(tournament, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TournamentPlayer registerTournamentPlayer(Tournament tournament, Player player) {
|
||||||
|
var tournamentPlayer = new TournamentPlayer();
|
||||||
|
tournamentPlayer.setTournament(tournament);
|
||||||
|
tournamentPlayer.setPlayer(player);
|
||||||
|
tournamentPlayer.setEvents(new ArrayList<>());
|
||||||
|
tournament.getTournamentPlayers().add(tournamentPlayer);
|
||||||
|
|
||||||
|
return tournamentPlayer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package nl.connectedit.swiss.service;
|
package nl.connectedit.swiss.service;
|
||||||
|
|
||||||
import nl.connectedit.swiss.domain.entity.Group;
|
import nl.connectedit.swiss.domain.StandingsEntry;
|
||||||
import nl.connectedit.swiss.domain.entity.Match;
|
import nl.connectedit.swiss.domain.entity.Match;
|
||||||
import nl.connectedit.swiss.domain.entity.Round;
|
import nl.connectedit.swiss.domain.entity.Round;
|
||||||
import nl.connectedit.swiss.domain.entity.Team;
|
import nl.connectedit.swiss.domain.entity.Team;
|
||||||
import nl.connectedit.swiss.dto.StandingsEntry;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.java.Log;
|
||||||
import nl.connectedit.swiss.domain.EventType;
|
import nl.connectedit.swiss.domain.EventType;
|
||||||
import nl.connectedit.swiss.domain.Status;
|
import nl.connectedit.swiss.domain.Status;
|
||||||
import nl.connectedit.swiss.domain.TournamentStatus;
|
import nl.connectedit.swiss.domain.TournamentStatus;
|
||||||
@@ -22,6 +23,7 @@ import org.springframework.stereotype.Service;
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@Log
|
||||||
public class TournamentDivideService {
|
public class TournamentDivideService {
|
||||||
|
|
||||||
private final TournamentValidationService tournamentValidationService;
|
private final TournamentValidationService tournamentValidationService;
|
||||||
@@ -36,7 +38,7 @@ public class TournamentDivideService {
|
|||||||
|
|
||||||
for (var event : tournament.getEvents()) {
|
for (var event : tournament.getEvents()) {
|
||||||
if ((event.getType().isDoublesEvent() && event.getRegistrations().size() >= 8)
|
if ((event.getType().isDoublesEvent() && event.getRegistrations().size() >= 8)
|
||||||
|| (!event.getType().isDoublesEvent() && event.getRegistrations().size() >= 4)) {
|
|| (!event.getType().isDoublesEvent() && event.getRegistrations().size() >= 4)) {
|
||||||
divide(event);
|
divide(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,6 +66,7 @@ public class TournamentDivideService {
|
|||||||
event.getGroups().add(group);
|
event.getGroups().add(group);
|
||||||
} else {
|
} else {
|
||||||
var groups = getGroups(registrations, event.getType());
|
var groups = getGroups(registrations, event.getType());
|
||||||
|
groups.forEach(group -> group.setEvent(event));
|
||||||
event.getGroups().addAll(groups);
|
event.getGroups().addAll(groups);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,7 +74,7 @@ public class TournamentDivideService {
|
|||||||
private List<Registration> groupRegistrations(List<Registration> registrations) {
|
private List<Registration> groupRegistrations(List<Registration> registrations) {
|
||||||
var groupedRegistrations = new ArrayList<Registration>();
|
var groupedRegistrations = new ArrayList<Registration>();
|
||||||
|
|
||||||
nextRegistration:
|
nextRegistration:
|
||||||
for (var registration : registrations) {
|
for (var registration : registrations) {
|
||||||
for (var groupedRegistration : groupedRegistrations) {
|
for (var groupedRegistration : groupedRegistrations) {
|
||||||
if (Objects.equals(groupedRegistration.getPartner(), registration.getPlayer())) {
|
if (Objects.equals(groupedRegistration.getPartner(), registration.getPlayer())) {
|
||||||
@@ -90,13 +93,16 @@ nextRegistration:
|
|||||||
group.setStatus(Status.IN_PROGRESS);
|
group.setStatus(Status.IN_PROGRESS);
|
||||||
group.setTeams(new ArrayList<>());
|
group.setTeams(new ArrayList<>());
|
||||||
for (var registration : registrations) {
|
for (var registration : registrations) {
|
||||||
group.getTeams().add(getTeam(registration, group));
|
// group.getTeams().add(getTeam(registration, group));
|
||||||
|
addTeamToGroup(registration, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Group> getGroups(List<Registration> orgRegistrations, EventType type) {
|
private List<Group> getGroups(List<Registration> orgRegistrations, EventType type) {
|
||||||
|
var groups = new ArrayList<Group>();
|
||||||
|
|
||||||
var registrations = new ArrayList<>(orgRegistrations);
|
var registrations = new ArrayList<>(orgRegistrations);
|
||||||
|
|
||||||
var group1 = new Group();
|
var group1 = new Group();
|
||||||
@@ -139,18 +145,28 @@ nextRegistration:
|
|||||||
group2.getTeams().removeLast();
|
group2.getTeams().removeLast();
|
||||||
}
|
}
|
||||||
|
|
||||||
return List.of(group1, group2);
|
groups.add(group1);
|
||||||
|
groups.add(group2);
|
||||||
|
return groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Team getTeam(Registration registration, Group group) {
|
private Team getTeam(Registration registration, Group group) {
|
||||||
var team = new Team();
|
var team = new Team();
|
||||||
team.setPlayer1(registration.getPlayer());
|
team.setPlayer1(registration.getPlayer());
|
||||||
team.setPlayer2(registration.getPartner());
|
team.setPlayer2(registration.getPartner());
|
||||||
team.setGroup(group);
|
team.getGroups().add(group);
|
||||||
|
|
||||||
return team;
|
return team;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addTeamToGroup(Registration registration, Group group) {
|
||||||
|
var team = new Team();
|
||||||
|
team.setPlayer1(registration.getPlayer());
|
||||||
|
team.setPlayer2(registration.getPartner());
|
||||||
|
team.getGroups().add(group);
|
||||||
|
group.getTeams().add(team);
|
||||||
|
}
|
||||||
|
|
||||||
public Tournament clear(Tournament tournament) {
|
public Tournament clear(Tournament tournament) {
|
||||||
for (var event : tournament.getEvents()) {
|
for (var event : tournament.getEvents()) {
|
||||||
event.getGroups().clear();
|
event.getGroups().clear();
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class TournamentDrawService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerTournamentPlayers(tournament);
|
// registerTournamentPlayers(tournament);
|
||||||
|
|
||||||
tournament.setStatus(TournamentStatus.DRAWN);
|
tournament.setStatus(TournamentStatus.DRAWN);
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ public class TournamentDrawService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tournament.getTournamentPlayers().clear();
|
// tournament.getTournamentPlayers().clear();
|
||||||
|
|
||||||
tournament.setStatus(TournamentStatus.DIVIDED);
|
tournament.setStatus(TournamentStatus.DIVIDED);
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ package nl.connectedit.swiss.service;
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.java.Log;
|
import lombok.extern.java.Log;
|
||||||
|
import nl.connectedit.swiss.domain.EventType;
|
||||||
|
import nl.connectedit.swiss.domain.StandingsEntry;
|
||||||
import nl.connectedit.swiss.domain.Status;
|
import nl.connectedit.swiss.domain.Status;
|
||||||
import nl.connectedit.swiss.domain.TournamentStatus;
|
import nl.connectedit.swiss.domain.TournamentStatus;
|
||||||
import nl.connectedit.swiss.domain.entity.*;
|
import nl.connectedit.swiss.domain.entity.*;
|
||||||
import nl.connectedit.swiss.dto.ResultDto;
|
import nl.connectedit.swiss.dto.ResultDto;
|
||||||
import nl.connectedit.swiss.dto.StandingsEntry;
|
import nl.connectedit.swiss.dto.TournamentPlayerSubstitutionDto;
|
||||||
import nl.connectedit.swiss.repository.TournamentRepository;
|
import nl.connectedit.swiss.repository.TournamentRepository;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -14,7 +16,6 @@ import java.time.LocalDateTime;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static nl.connectedit.swiss.service.ServiceUtil.*;
|
import static nl.connectedit.swiss.service.ServiceUtil.*;
|
||||||
@@ -42,11 +43,86 @@ public class TournamentPlayService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Tournament finishGroup(Tournament tournament, Long groupId) {
|
public Tournament finishGroup(Tournament tournament, Long groupId) {
|
||||||
getGroup(tournament, groupId).setStatus(Status.FINISHED);
|
var group = getGroup(tournament, groupId);
|
||||||
|
group.setStatus(Status.FINISHED);
|
||||||
|
|
||||||
|
checkForEventCompletion(tournament, group.getType());
|
||||||
|
|
||||||
tournamentRepository.save(tournament);
|
tournamentRepository.save(tournament);
|
||||||
return tournament;
|
return tournament;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkForEventCompletion(Tournament tournament, EventType type) {
|
||||||
|
Group group1 = null;
|
||||||
|
Group group2 = null;
|
||||||
|
Event event = null;
|
||||||
|
|
||||||
|
for (var e : tournament.getEvents()) {
|
||||||
|
if (e.getType() == type) {
|
||||||
|
if (e.getGroups().size() != 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
group1 = e.getGroups().getFirst();
|
||||||
|
if (group1.getStatus() != Status.FINISHED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
group2 = e.getGroups().getLast();
|
||||||
|
if (group2.getStatus() != Status.FINISHED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var finalsGroup = new Group();
|
||||||
|
finalsGroup.setName(type.getText());
|
||||||
|
finalsGroup.setType(type);
|
||||||
|
finalsGroup.setStatus(Status.IN_PROGRESS);
|
||||||
|
finalsGroup.setEvent(group1.getEvent());
|
||||||
|
|
||||||
|
var standings1 = standingsService.getStandings(group1.getRounds(), group1.getTeams());
|
||||||
|
var standings2 = standingsService.getStandings(group2.getRounds(), group2.getTeams());
|
||||||
|
|
||||||
|
var team1_1 = standings1.get(0).getTeam();
|
||||||
|
var team1_2 = standings1.get(1).getTeam();
|
||||||
|
var team2_1 = standings2.get(0).getTeam();
|
||||||
|
var team2_2 = standings2.get(1).getTeam();
|
||||||
|
|
||||||
|
team1_1.getGroups().add(finalsGroup);
|
||||||
|
team1_2.getGroups().add(finalsGroup);
|
||||||
|
team2_1.getGroups().add(finalsGroup);
|
||||||
|
team2_2.getGroups().add(finalsGroup);
|
||||||
|
|
||||||
|
finalsGroup.setTeams(List.of(team1_1, team1_2, team2_1, team2_2));
|
||||||
|
|
||||||
|
var finalsRound = new Round();
|
||||||
|
finalsRound.setGroup(finalsGroup);
|
||||||
|
finalsRound.setStatus(Status.NOT_STARTED);
|
||||||
|
finalsRound.setName("Finales");
|
||||||
|
finalsRound.setIsFinalsRound(Boolean.TRUE);
|
||||||
|
|
||||||
|
var match1 = new Match();
|
||||||
|
match1.setRound(finalsRound);
|
||||||
|
match1.setType(type);
|
||||||
|
match1.setStatus(Status.NOT_STARTED);
|
||||||
|
match1.setPlayed(false);
|
||||||
|
match1.setTeam1(standings1.get(0).getTeam());
|
||||||
|
match1.setTeam2(standings2.get(0).getTeam());
|
||||||
|
|
||||||
|
var match2 = new Match();
|
||||||
|
match2.setRound(finalsRound);
|
||||||
|
match2.setType(type);
|
||||||
|
match2.setStatus(Status.NOT_STARTED);
|
||||||
|
match2.setPlayed(false);
|
||||||
|
match2.setTeam1(standings1.get(1).getTeam());
|
||||||
|
match2.setTeam2(standings2.get(1).getTeam());
|
||||||
|
|
||||||
|
finalsRound.setMatches(List.of(match1, match2));
|
||||||
|
finalsGroup.setRounds(List.of(finalsRound));
|
||||||
|
event.getGroups().add(finalsGroup);
|
||||||
|
}
|
||||||
|
|
||||||
public Tournament reopenGroup(Tournament tournament, Long groupId) {
|
public Tournament reopenGroup(Tournament tournament, Long groupId) {
|
||||||
getGroup(tournament, groupId).setStatus(Status.IN_PROGRESS);
|
getGroup(tournament, groupId).setStatus(Status.IN_PROGRESS);
|
||||||
tournamentRepository.save(tournament);
|
tournamentRepository.save(tournament);
|
||||||
@@ -92,22 +168,74 @@ public class TournamentPlayService {
|
|||||||
|
|
||||||
round.setMatches(matches);
|
round.setMatches(matches);
|
||||||
|
|
||||||
printRound(round, standings);
|
|
||||||
|
|
||||||
group.getRounds().add(round);
|
group.getRounds().add(round);
|
||||||
|
|
||||||
tournamentRepository.save(tournament);
|
tournamentRepository.save(tournament);
|
||||||
return tournament;
|
return tournament;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void printRound(Round round, List<StandingsEntry> standings) {
|
public Tournament playerSubstitutions(Tournament tournament, Long playerId, TournamentPlayerSubstitutionDto[] substitutions) {
|
||||||
for (var match: round.getMatches()) {
|
var tournamentPlayer = getTournamentPlayer(tournament, playerId);
|
||||||
log.info("%s - %s".formatted(
|
|
||||||
String.valueOf(standings.stream().filter(entry -> entry.getTeam().equals(match.getTeam1())).map(StandingsEntry::getPosition).findFirst().get()),
|
var playerSubstitutions = new ArrayList<TournamentPlayerSubstitution>();
|
||||||
String.valueOf(standings.stream().filter(entry -> entry.getTeam().equals(match.getTeam2())).map(StandingsEntry::getPosition).findFirst().get())));
|
|
||||||
|
for (var substitution : substitutions) {
|
||||||
|
var playerSubstitution = new TournamentPlayerSubstitution();
|
||||||
|
|
||||||
|
var eventType = EventType.valueOf(substitution.getEvent());
|
||||||
|
var event = getEventByType(tournament, eventType);
|
||||||
|
playerSubstitution.setEvent(event);
|
||||||
|
|
||||||
|
TournamentPlayer substitute;
|
||||||
|
if (substitution.getSubstitute() != null) {
|
||||||
|
substitute = getTournamentPlayerById(tournament, substitution.getSubstitute());
|
||||||
|
} else {
|
||||||
|
substitute = null;
|
||||||
|
}
|
||||||
|
playerSubstitution.setSubstitute(substitute);
|
||||||
|
playerSubstitutions.add(playerSubstitution);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tournamentPlayer.setSubstitutions(playerSubstitutions);
|
||||||
|
|
||||||
|
tournamentRepository.save(tournament);
|
||||||
|
return tournament;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Event getEvent(Tournament tournament, Long eventId) {
|
||||||
|
for (var event : tournament.getEvents()) {
|
||||||
|
if (event.getId().equals(eventId)) {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Event getEventByType(Tournament tournament, EventType eventType) {
|
||||||
|
for (var event : tournament.getEvents()) {
|
||||||
|
if (event.getType().equals(eventType)) {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tournament updateCounter(Tournament tournament, Long matchId, Long counter) {
|
||||||
|
var match = getMatch(tournament, matchId);
|
||||||
|
|
||||||
|
var currentlyCountingPlayer = getTournamentPlayer(tournament, match.getCounter().getId());
|
||||||
|
currentlyCountingPlayer.setCounting(false);
|
||||||
|
|
||||||
|
var newCountingPlayer = getTournamentPlayer(tournament, counter);
|
||||||
|
newCountingPlayer.setCounting(true);
|
||||||
|
match.setCounter(newCountingPlayer.getPlayer());
|
||||||
|
|
||||||
|
tournamentRepository.save(tournament);
|
||||||
|
return tournament;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class ConflictInDrawException extends RuntimeException {}
|
private static class ConflictInDrawException extends RuntimeException {}
|
||||||
|
|
||||||
private List<Match> tryMatches(List<Team> remainingTeams, Group group) {
|
private List<Match> tryMatches(List<Team> remainingTeams, Group group) {
|
||||||
@@ -121,7 +249,6 @@ public class TournamentPlayService {
|
|||||||
if (!findPreviousMatchOccurence(newMatch.getTeam1(), remainingTeams.get(opponentIndex), group)) {
|
if (!findPreviousMatchOccurence(newMatch.getTeam1(), remainingTeams.get(opponentIndex), group)) {
|
||||||
newMatch.setTeam2(remainingTeams.get(opponentIndex));
|
newMatch.setTeam2(remainingTeams.get(opponentIndex));
|
||||||
} else {
|
} else {
|
||||||
log.info("Wedstrijd %s - %s kwam al eerder voor.".formatted(newMatch.getTeam1().toString(), remainingTeams.get(opponentIndex).toString()));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var newRemainingTeams = getRemainingTeams(remainingTeams, opponentIndex);
|
var newRemainingTeams = getRemainingTeams(remainingTeams, opponentIndex);
|
||||||
@@ -166,26 +293,48 @@ public class TournamentPlayService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean playerHasSkippedRoundBefore(Player player, Tournament tournament) {
|
public Tournament startMatch(Tournament tournament, Long matchId, Long court, Long counter) {
|
||||||
var hasSkippedRound = false;
|
|
||||||
|
|
||||||
return hasSkippedRound;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tournament startMatch(Tournament tournament, Long matchId, Long court) {
|
|
||||||
var match = getMatch(tournament, matchId);
|
var match = getMatch(tournament, matchId);
|
||||||
match.setStatus(Status.IN_PROGRESS);
|
match.setStatus(Status.IN_PROGRESS);
|
||||||
match.setStartTime(LocalDateTime.now());
|
match.setStartTime(LocalDateTime.now());
|
||||||
match.setCourt(court);
|
match.setCourt(court);
|
||||||
|
|
||||||
|
var countingPlayer = getTournamentPlayer(tournament, counter);
|
||||||
|
countingPlayer.setCounting(true);
|
||||||
|
match.setCounter(countingPlayer.getPlayer());
|
||||||
|
|
||||||
tournamentRepository.save(tournament);
|
tournamentRepository.save(tournament);
|
||||||
return tournament;
|
return tournament;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TournamentPlayer getTournamentPlayerById(Tournament tournament, Long id) {
|
||||||
|
for (var tournamentPlayer : tournament.getTournamentPlayers()) {
|
||||||
|
if (id.equals(tournamentPlayer.getId())) {
|
||||||
|
return tournamentPlayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TournamentPlayer getTournamentPlayer(Tournament tournament, Long playerId) {
|
||||||
|
for (var tournamentPlayer : tournament.getTournamentPlayers()) {
|
||||||
|
if (playerId.equals(tournamentPlayer.getPlayer().getId())) {
|
||||||
|
return tournamentPlayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public Tournament stopMatch(Tournament tournament, Long matchId) {
|
public Tournament stopMatch(Tournament tournament, Long matchId) {
|
||||||
var match = getMatch(tournament, matchId);
|
var match = getMatch(tournament, matchId);
|
||||||
match.setStatus(Status.NOT_STARTED);
|
match.setStatus(Status.NOT_STARTED);
|
||||||
match.setStartTime(null);
|
match.setStartTime(null);
|
||||||
match.setCourt(null);
|
match.setCourt(null);
|
||||||
|
|
||||||
|
var countingPlayer = getTournamentPlayer(tournament, match.getCounter().getId());
|
||||||
|
countingPlayer.setCounting(false);
|
||||||
|
match.setCounter(null);
|
||||||
|
|
||||||
tournamentRepository.save(tournament);
|
tournamentRepository.save(tournament);
|
||||||
return tournament;
|
return tournament;
|
||||||
}
|
}
|
||||||
@@ -200,6 +349,14 @@ public class TournamentPlayService {
|
|||||||
match.getGames().clear();
|
match.getGames().clear();
|
||||||
match.getGames().addAll(resultToGames(result, match));
|
match.getGames().addAll(resultToGames(result, match));
|
||||||
|
|
||||||
|
var counter = match.getCounter();
|
||||||
|
if (counter != null) { // match was already saved, this is a correction
|
||||||
|
var countingPlayer = getTournamentPlayer(tournament, counter.getId());
|
||||||
|
countingPlayer.setCounting(false);
|
||||||
|
countingPlayer.incrementCounts();
|
||||||
|
match.setCounter(null);
|
||||||
|
}
|
||||||
|
|
||||||
tournamentRepository.save(tournament);
|
tournamentRepository.save(tournament);
|
||||||
return tournament;
|
return tournament;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ spring:
|
|||||||
# - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
|
# - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
|
||||||
# - org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
|
# - org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
|
||||||
datasource:
|
datasource:
|
||||||
url: jdbc:postgresql://localhost:5432/postgres?currentSchema=swiss
|
url: jdbc:postgresql://localhost:5432/postgres?currentSchema=swiss2
|
||||||
username: ${DB_USERNAME:postgres}
|
username: ${DB_USERNAME:postgres}
|
||||||
password: ${DB_PASSWORD:postgres}
|
password: ${DB_PASSWORD:postgres}
|
||||||
flyway:
|
flyway:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ spring:
|
|||||||
password: ${DB_PASSWORD:postgres}
|
password: ${DB_PASSWORD:postgres}
|
||||||
jpa:
|
jpa:
|
||||||
hibernate:
|
hibernate:
|
||||||
ddl-auto: none
|
ddl-auto: update
|
||||||
flyway:
|
flyway:
|
||||||
url: jdbc:postgresql://${DB_URL:localhost:5432}/${DB_NAME}?currentSchema=swiss
|
url: jdbc:postgresql://${DB_URL:localhost:5432}/${DB_NAME}?currentSchema=swiss
|
||||||
user: ${DB_USERNAME:postgres}
|
user: ${DB_USERNAME:postgres}
|
||||||
@@ -31,3 +31,9 @@ management:
|
|||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
security: true
|
security: true
|
||||||
|
|
||||||
|
jwt:
|
||||||
|
private:
|
||||||
|
key: classpath:certs/private.pem
|
||||||
|
public:
|
||||||
|
key: classpath:certs/public.pem
|
||||||
|
|||||||
Reference in New Issue
Block a user