migrate to spring boot 3.2

This commit is contained in:
_Bastler 2023-12-12 21:20:25 +01:00
parent fabd70fe56
commit 7ccdc4de00
24 changed files with 175 additions and 205 deletions

4
.gitignore vendored
View File

@ -6,4 +6,6 @@ target/
hs_err*.log hs_err*.log
application.properties application.properties
usernames.txt usernames.txt
lucene lucene
.vscode

48
pom.xml
View File

@ -9,15 +9,16 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version> <java.version>17</java.version>
<log4j2.version>2.19.0</log4j2.version> <querydsl.version>5.0.0</querydsl.version>
<revision>1.5.0</revision> <hibernate.version>6.4.0.Final</hibernate.version>
<revision>2.0.0</revision>
</properties> </properties>
<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>2.7.6</version> <version>3.2.0</version>
<relativePath /> <relativePath />
</parent> </parent>
@ -58,35 +59,39 @@
<artifactId>spring-session-jdbc</artifactId> <artifactId>spring-session-jdbc</artifactId>
</dependency> </dependency>
<!-- Search --> <!-- Search -->
<dependency> <dependency>
<groupId>org.hibernate.search</groupId> <groupId>org.hibernate.search</groupId>
<artifactId>hibernate-search-mapper-orm</artifactId> <artifactId>hibernate-search-mapper-orm</artifactId>
<version>6.0.7.Final</version> <version>7.0.0.Final</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.hibernate.search</groupId> <groupId>org.hibernate.search</groupId>
<artifactId>hibernate-search-backend-lucene</artifactId> <artifactId>hibernate-search-backend-lucene</artifactId>
<version>6.0.7.Final</version> <version>7.0.0.Final</version>
</dependency> </dependency>
<!-- Query DSL --> <!-- Query DSL -->
<dependency> <dependency>
<groupId>com.querydsl</groupId> <groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId> <artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<classifier>jakarta</classifier>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.querydsl</groupId> <groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId> <artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
<classifier>jakarta</classifier>
</dependency> </dependency>
<!-- Utils --> <!-- Utils -->
<dependency> <dependency>
<groupId>commons-validator</groupId> <groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId> <artifactId>commons-validator</artifactId>
<version>1.7</version> <version>1.8.0</version>
</dependency> </dependency>
<dependency> <dependency>
@ -97,7 +102,7 @@
<dependency> <dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId> <groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>owasp-java-html-sanitizer</artifactId> <artifactId>owasp-java-html-sanitizer</artifactId>
<version>20200713.1</version> <version>20220608.1</version>
</dependency> </dependency>
<dependency> <dependency>
@ -108,7 +113,13 @@
<dependency> <dependency>
<groupId>org.bouncycastle</groupId> <groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId> <artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version> <version>1.70</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>runtime</scope>
</dependency> </dependency>
</dependencies> </dependencies>
@ -175,23 +186,6 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor
</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

View File

@ -3,7 +3,7 @@
*/ */
package de.bstly.board; package de.bstly.board;
import javax.persistence.EntityManager; import jakarta.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;

View File

@ -3,13 +3,9 @@
*/ */
package de.bstly.board.businesslogic; package de.bstly.board.businesslogic;
import java.math.BigInteger;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
@ -35,6 +31,8 @@ import de.bstly.board.model.support.Types;
import de.bstly.board.model.support.VoteType; import de.bstly.board.model.support.VoteType;
import de.bstly.board.repository.EntryRepository; import de.bstly.board.repository.EntryRepository;
import de.bstly.board.repository.VoteRepository; import de.bstly.board.repository.VoteRepository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
/** /**
* The Class EntryManager. * The Class EntryManager.
@ -110,7 +108,7 @@ public class EntryManager {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Entry> list = query.getResultList(); List<Entry> list = query.getResultList();
Query queryTotal = createCountQuery(COUNT_QUERY, username, filter); Query queryTotal = createCountQuery(COUNT_QUERY, username, filter);
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue(); long countResult = ((Long) queryTotal.getSingleResult()).longValue();
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult); return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
} }
@ -131,7 +129,7 @@ public class EntryManager {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Entry> list = query.getResultList(); List<Entry> list = query.getResultList();
Query queryTotal = createCountQuery(COUNT_QUERY, username, filter); Query queryTotal = createCountQuery(COUNT_QUERY, username, filter);
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue(); long countResult = ((Long) queryTotal.getSingleResult()).longValue();
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult); return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
} }
@ -156,7 +154,7 @@ public class EntryManager {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Entry> list = query.getResultList(); List<Entry> list = query.getResultList();
Query queryTotal = createCountQuery(COUNT_QUERY, username, filter); Query queryTotal = createCountQuery(COUNT_QUERY, username, filter);
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue(); long countResult = ((Long) queryTotal.getSingleResult()).longValue();
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult); return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
} }
@ -178,7 +176,7 @@ public class EntryManager {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
List<Entry> list = query.getResultList(); List<Entry> list = query.getResultList();
Query queryTotal = createCountQuery(COUNT_QUERY, username, filter); Query queryTotal = createCountQuery(COUNT_QUERY, username, filter);
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue(); long countResult = ((Long) queryTotal.getSingleResult()).longValue();
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult); return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
} }
@ -204,7 +202,7 @@ public class EntryManager {
List<Entry> list = query.getResultList(); List<Entry> list = query.getResultList();
Query queryTotal = createCountQuery(COUNT_QUERY, username, filter); Query queryTotal = createCountQuery(COUNT_QUERY, username, filter);
queryTotal.setParameter("username", username); queryTotal.setParameter("username", username);
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue(); long countResult = ((Long) queryTotal.getSingleResult()).longValue();
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult); return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
} }

View File

@ -5,8 +5,8 @@ package de.bstly.board.businesslogic;
import java.util.List; import java.util.List;
import javax.persistence.EntityManager; import jakarta.persistence.EntityManager;
import javax.transaction.Transactional; import jakarta.transaction.Transactional;
import org.hibernate.search.engine.search.query.SearchResult; import org.hibernate.search.engine.search.query.SearchResult;
import org.hibernate.search.mapper.orm.Search; import org.hibernate.search.mapper.orm.Search;

View File

@ -61,11 +61,10 @@ public class AuthenticationController extends BaseController {
ResolvableType type = ResolvableType.forInstance(clientRegistrationRepository).as(Iterable.class); ResolvableType type = ResolvableType.forInstance(clientRegistrationRepository).as(Iterable.class);
if (type != ResolvableType.NONE && ClientRegistration.class.isAssignableFrom(type.resolveGenerics()[0])) { if (type != ResolvableType.NONE && ClientRegistration.class.isAssignableFrom(type.resolveGenerics()[0])) {
clientRegistrations = (Iterable<ClientRegistration>) clientRegistrationRepository; clientRegistrations = (Iterable<ClientRegistration>) clientRegistrationRepository;
clientRegistrations.forEach(registration -> clients.add(new Client(registration.getRegistrationId(),
authorizationRequestBaseUri + "/" + registration.getRegistrationId())));
} }
clientRegistrations.forEach(registration -> clients.add(new Client(registration.getRegistrationId(),
authorizationRequestBaseUri + "/" + registration.getRegistrationId())));
return clients; return clients;
} }

View File

@ -5,9 +5,9 @@ package de.bstly.board.controller;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.SplittableRandom;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -26,6 +26,7 @@ import de.bstly.board.model.QLocalUser;
import de.bstly.board.model.Vote; import de.bstly.board.model.Vote;
import de.bstly.board.model.support.EntryStatus; import de.bstly.board.model.support.EntryStatus;
import de.bstly.board.model.support.EntryType; import de.bstly.board.model.support.EntryType;
import de.bstly.board.model.support.FlaggedStatus;
import de.bstly.board.model.support.Types; import de.bstly.board.model.support.Types;
import de.bstly.board.model.support.VoteType; import de.bstly.board.model.support.VoteType;
import de.bstly.board.repository.CommentRepository; import de.bstly.board.repository.CommentRepository;
@ -43,58 +44,44 @@ public class DebugController extends BaseController {
@Autowired @Autowired
private PasswordEncoder passwordEncoder; private PasswordEncoder passwordEncoder;
@Autowired @Autowired
private LocalUserRepository localUserRepository; private LocalUserRepository localUserRepository;
@Autowired @Autowired
private CommentRepository commentRepository; private CommentRepository commentRepository;
@Autowired @Autowired
private VoteRepository voteRepository; private VoteRepository voteRepository;
@Autowired @Autowired
private EntryManager entryManager; private EntryManager entryManager;
@Value("${debug.random.users:0}") @Value("${debug.random.users:0}")
private int users; private int users;
@Value("${debug.random.minEntries:0}") @Value("${debug.random.minEntries:0}")
private int minEntries; private int minEntries;
@Value("${debug.random.maxEntries:10}") @Value("${debug.random.maxEntries:10}")
private int maxEntries; private int maxEntries;
@Value("${debug.random.entryAge:63115200}") @Value("${debug.random.entryAge:63115200}")
private long entryAge; private long entryAge;
@Value("${debug.random.minComments:0}") @Value("${debug.random.minComments:0}")
private int minComments; private int minComments;
@Value("${debug.random.maxComments:10}") @Value("${debug.random.maxComments:10}")
private int maxComments; private int maxComments;
@Value("${debug.random.subCommentsFactor:0.5}") @Value("${debug.random.subCommentsFactor:0.5}")
private float subCommentsFactor; private float subCommentsFactor;
@Value("${debug.random.subCommentsThresh:0.3}") @Value("${debug.random.subCommentsThresh:0.3}")
private float subCommentsThresh; private float subCommentsThresh;
@Value("${debug.random.subCommentsDepth:2}") @Value("${debug.random.subCommentsDepth:2}")
private int subCommentsDepth; private int subCommentsDepth;
@Value("${debug.random.minUpvotes:5}") @Value("${debug.random.minUpvotes:5}")
private int minUpvotes; private int minUpvotes;
@Value("${debug.random.maxUpvotes:10}") @Value("${debug.random.maxUpvotes:10}")
private int maxUpvotes; private int maxUpvotes;
@Value("${debug.random.minDownvotes:0}") @Value("${debug.random.minDownvotes:0}")
private int minDownvotes; private int minDownvotes;
@Value("${debug.random.maxDownvotes:10}") @Value("${debug.random.maxDownvotes:10}")
private int maxDownvotes; private int maxDownvotes;
SplittableRandom splittableRandom = new SplittableRandom();
/** /**
* Random. * Random.
*/ */
@ -110,6 +97,7 @@ public class DebugController extends BaseController {
String username = "user" + i; String username = "user" + i;
localUser.setUsername(username); localUser.setUsername(username);
localUser.setPasswordHash(passwordEncoder.encode(username)); localUser.setPasswordHash(passwordEncoder.encode(username));
localUser.setLocale("en");
localUserRepository.save(localUser); localUserRepository.save(localUser);
logger.trace("Created user: '" + username + "'"); logger.trace("Created user: '" + username + "'");
} }
@ -130,15 +118,16 @@ public class DebugController extends BaseController {
* @param userCount the user count * @param userCount the user count
*/ */
protected void entries(String username, long userCount) { protected void entries(String username, long userCount) {
long numEntries = RandomUtils.nextLong(minEntries, maxEntries); long numEntries = splittableRandom.nextLong(minEntries, maxEntries);
for (int i = 0; i < numEntries; i++) { for (int i = 0; i < numEntries; i++) {
Entry entry = new Entry(); Entry entry = new Entry();
entry.setEntryType(EntryType.INTERN); entry.setEntryType(EntryType.INTERN);
entry.setAuthor(username); entry.setAuthor(username);
entry.setCreated(Instant.now().minus(RandomUtils.nextLong(0, entryAge), ChronoUnit.SECONDS)); entry.setCreated(Instant.now().minus(splittableRandom.nextLong(0, entryAge), ChronoUnit.SECONDS));
entry.setTitle(RandomStringUtils.randomAscii(RandomUtils.nextInt(10, 250))); entry.setTitle(RandomStringUtils.randomAscii(splittableRandom.nextInt(10, 250)));
entry.setText(RandomStringUtils.randomAscii(RandomUtils.nextInt(0, 2500))); entry.setText(RandomStringUtils.randomAscii(splittableRandom.nextInt(0, 2500)));
entry.setEntryStatus(EntryStatus.NORMAL); entry.setEntryStatus(EntryStatus.NORMAL);
entry.setFlaggedStatus(FlaggedStatus.NORMAL);
entry = entryManager.save(entry); entry = entryManager.save(entry);
logger.trace("Created entry: '" + entry.getId() + "'"); logger.trace("Created entry: '" + entry.getId() + "'");
comments(entry.getId(), entry.getCreated(), userCount); comments(entry.getId(), entry.getCreated(), userCount);
@ -155,15 +144,16 @@ public class DebugController extends BaseController {
* @param userCount the user count * @param userCount the user count
*/ */
protected void comments(Long target, Instant date, long userCount) { protected void comments(Long target, Instant date, long userCount) {
long numComments = RandomUtils.nextLong(minComments, maxComments); long numComments = splittableRandom.nextLong(minComments, maxComments);
logger.debug("Create " + numComments + " comments for '" + target + "'"); logger.debug("Create " + numComments + " comments for '" + target + "'");
for (int i = 0; i < numComments; i++) { for (int i = 0; i < numComments; i++) {
Comment comment = new Comment(); Comment comment = new Comment();
comment.setTarget(target); comment.setTarget(target);
comment.setAuthor("user" + RandomUtils.nextLong(0, userCount)); comment.setAuthor("user" + splittableRandom.nextLong(0, userCount));
comment.setText(RandomStringUtils.randomAscii(RandomUtils.nextInt(0, 2500))); comment.setText(RandomStringUtils.randomAscii(splittableRandom.nextInt(0, 2500)));
comment.setFlaggedStatus(FlaggedStatus.NORMAL);
comment.setCreated(Instant.now().minus( comment.setCreated(Instant.now().minus(
RandomUtils.nextLong(0, (Instant.now().toEpochMilli() - date.toEpochMilli()) / 1000), splittableRandom.nextLong(0, (Instant.now().toEpochMilli() - date.toEpochMilli()) / 1000),
ChronoUnit.SECONDS)); ChronoUnit.SECONDS));
comment = commentRepository.save(comment); comment = commentRepository.save(comment);
logger.trace("Created comment: '" + comment.getId() + "'"); logger.trace("Created comment: '" + comment.getId() + "'");
@ -185,17 +175,18 @@ public class DebugController extends BaseController {
*/ */
protected void subComments(Long target, Long parent, Instant date, float factor, float thresh, int depth, protected void subComments(Long target, Long parent, Instant date, float factor, float thresh, int depth,
long userCount) { long userCount) {
if (depth < subCommentsDepth && RandomUtils.nextFloat(0, 1) < thresh) { if (depth < subCommentsDepth && splittableRandom.nextFloat(0, 1) < thresh) {
long numSubComments = RandomUtils.nextLong(0, Math.round(maxComments * factor)); long numSubComments = splittableRandom.nextLong(0, Math.round(maxComments * factor));
logger.debug("Create " + numSubComments + " subComments for '" + parent + "'"); logger.debug("Create " + numSubComments + " subComments for '" + parent + "'");
for (int i = 0; i < numSubComments; i++) { for (int i = 0; i < numSubComments; i++) {
Comment comment = new Comment(); Comment comment = new Comment();
comment.setTarget(target); comment.setTarget(target);
comment.setParent(parent); comment.setParent(parent);
comment.setAuthor("user" + RandomUtils.nextLong(0, userCount)); comment.setAuthor("user" + splittableRandom.nextLong(0, userCount));
comment.setText(RandomStringUtils.randomAscii(RandomUtils.nextInt(0, 2500))); comment.setText(RandomStringUtils.randomAscii(splittableRandom.nextInt(0, 2500)));
comment.setFlaggedStatus(FlaggedStatus.NORMAL);
comment.setCreated(Instant.now().minus( comment.setCreated(Instant.now().minus(
RandomUtils.nextLong(0, (Instant.now().toEpochMilli() - date.toEpochMilli()) / 1000), splittableRandom.nextLong(0, (Instant.now().toEpochMilli() - date.toEpochMilli()) / 1000),
ChronoUnit.SECONDS)); ChronoUnit.SECONDS));
comment = commentRepository.save(comment); comment = commentRepository.save(comment);
logger.trace("Created subComment: '" + comment.getId() + "'"); logger.trace("Created subComment: '" + comment.getId() + "'");
@ -213,26 +204,26 @@ public class DebugController extends BaseController {
* @param userCount the user count * @param userCount the user count
*/ */
protected void votes(Long target, Types targetType, long userCount) { protected void votes(Long target, Types targetType, long userCount) {
long numUpvotes = RandomUtils.nextLong(minUpvotes, maxUpvotes); long numUpvotes = splittableRandom.nextLong(minUpvotes, maxUpvotes);
logger.debug("Create " + numUpvotes + " upvotes for '" + target + "'"); logger.debug("Create " + numUpvotes + " upvotes for '" + target + "'");
for (int i = 0; i < numUpvotes; i++) { for (int i = 0; i < numUpvotes; i++) {
Vote upvote = new Vote(); Vote upvote = new Vote();
upvote.setTarget(target); upvote.setTarget(target);
upvote.setType(VoteType.up); upvote.setType(VoteType.up);
upvote.setTargetType(targetType); upvote.setTargetType(targetType);
upvote.setAuthor("user" + RandomUtils.nextLong(0, userCount)); upvote.setAuthor("user" + splittableRandom.nextLong(0, userCount));
upvote = voteRepository.save(upvote); upvote = voteRepository.save(upvote);
logger.trace("Created upvote: '" + upvote.getId() + "'"); logger.trace("Created upvote: '" + upvote.getId() + "'");
} }
long numDownvotes = RandomUtils.nextLong(minDownvotes, maxDownvotes); long numDownvotes = splittableRandom.nextLong(minDownvotes, maxDownvotes);
logger.debug("Create " + numDownvotes + " downvotes for '" + target + "'"); logger.debug("Create " + numDownvotes + " downvotes for '" + target + "'");
for (int i = 0; i < numDownvotes; i++) { for (int i = 0; i < numDownvotes; i++) {
Vote downvote = new Vote(); Vote downvote = new Vote();
downvote.setTarget(target); downvote.setTarget(target);
downvote.setType(VoteType.down); downvote.setType(VoteType.down);
downvote.setTargetType(targetType); downvote.setTargetType(targetType);
downvote.setAuthor("user" + RandomUtils.nextLong(0, userCount)); downvote.setAuthor("user" + splittableRandom.nextLong(0, userCount));
downvote = voteRepository.save(downvote); downvote = voteRepository.save(downvote);
logger.trace("Created downvote: '" + downvote.getId() + "'"); logger.trace("Created downvote: '" + downvote.getId() + "'");
} }

View File

@ -5,7 +5,6 @@ package de.bstly.board.controller.support;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.core.NestedRuntimeException; import org.springframework.core.NestedRuntimeException;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -79,8 +78,7 @@ public class EntityResponseStatusException extends NestedRuntimeException {
*/ */
@Override @Override
public String getMessage() { public String getMessage() {
String msg = this.status + (this.body != null ? " \"" + this.body + "\"" : ""); return this.status + (this.body != null ? " \"" + this.body + "\"" : "");
return NestedExceptionUtils.buildMessage(msg, getCause());
} }
} }

View File

@ -9,7 +9,6 @@ import org.springframework.validation.AbstractBindingResult;
/** /**
* The Class RequestBodyErrors. * The Class RequestBodyErrors.
*/ */
@SuppressWarnings("serial")
public class RequestBodyErrors extends AbstractBindingResult { public class RequestBodyErrors extends AbstractBindingResult {
@Nullable @Nullable

View File

@ -52,9 +52,7 @@ public class ViewValidator implements Validator {
View origView = viewManager.get(view.getId()); View origView = viewManager.get(view.getId());
if (origView == null) { if (origView == null) {
errors.rejectValue("id", "INVALID"); errors.rejectValue("id", "INVALID");
} } else if (!origView.getUsername().equals(view.getUsername())) {
if (!origView.getUsername().equals(view.getUsername())) {
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN); throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
} }

View File

@ -6,7 +6,7 @@ package de.bstly.board.i18n.controller;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;

View File

@ -3,12 +3,12 @@
*/ */
package de.bstly.board.i18n.model; package de.bstly.board.i18n.model;
import javax.persistence.Column; import jakarta.persistence.Column;
import javax.persistence.Entity; import jakarta.persistence.Entity;
import javax.persistence.Id; import jakarta.persistence.Id;
import javax.persistence.Lob; import jakarta.persistence.Lob;
import javax.persistence.Table; import jakarta.persistence.Table;
import javax.persistence.UniqueConstraint; import jakarta.persistence.UniqueConstraint;
/** /**
* The Class I18n. * The Class I18n.
@ -22,7 +22,7 @@ public class I18n {
private String locale; private String locale;
@Lob @Lob
@Column(name = "label") @Column(name = "label", length = 100000)
private String label; private String label;
/** /**

View File

@ -5,16 +5,15 @@ package de.bstly.board.model;
import java.util.List; import java.util.List;
import javax.persistence.CollectionTable; import jakarta.persistence.CollectionTable;
import javax.persistence.Column; import jakarta.persistence.Column;
import javax.persistence.ElementCollection; import jakarta.persistence.ElementCollection;
import javax.persistence.Entity; import jakarta.persistence.Entity;
import javax.persistence.EntityListeners; import jakarta.persistence.EntityListeners;
import javax.persistence.Id; import jakarta.persistence.FetchType;
import javax.persistence.Table; import jakarta.persistence.Id;
import jakarta.persistence.Table;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.springframework.data.jpa.domain.support.AuditingEntityListener; import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -30,8 +29,7 @@ public class Bookmarks {
@Id @Id
@Column(name = "username", nullable = false) @Column(name = "username", nullable = false)
private String username; private String username;
@ElementCollection @ElementCollection(fetch = FetchType.EAGER)
@LazyCollection(LazyCollectionOption.FALSE)
@CollectionTable(name = "bookmark_entries") @CollectionTable(name = "bookmark_entries")
private List<Long> entries; private List<Long> entries;

View File

@ -6,17 +6,17 @@ package de.bstly.board.model;
import java.time.Instant; import java.time.Instant;
import java.util.Map; import java.util.Map;
import javax.persistence.Column; import jakarta.persistence.Column;
import javax.persistence.Entity; import jakarta.persistence.Entity;
import javax.persistence.EntityListeners; import jakarta.persistence.EntityListeners;
import javax.persistence.EnumType; import jakarta.persistence.EnumType;
import javax.persistence.Enumerated; import jakarta.persistence.Enumerated;
import javax.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import javax.persistence.GenerationType; import jakarta.persistence.GenerationType;
import javax.persistence.Id; import jakarta.persistence.Id;
import javax.persistence.Lob; import jakarta.persistence.Lob;
import javax.persistence.Table; import jakarta.persistence.Table;
import javax.persistence.Transient; import jakarta.persistence.Transient;
import org.hibernate.search.engine.backend.types.Projectable; import org.hibernate.search.engine.backend.types.Projectable;
import org.hibernate.search.engine.backend.types.Searchable; import org.hibernate.search.engine.backend.types.Searchable;
@ -56,7 +56,7 @@ public class Comment {
@Column(name = "parent", nullable = true) @Column(name = "parent", nullable = true)
private Long parent; private Long parent;
@Lob @Lob
@Column(name = "text", nullable = false) @Column(name = "text", nullable = false, length = 100000)
@FullTextField(name = "text", searchable = Searchable.YES, analyzer = "english", searchAnalyzer = "english_search") @FullTextField(name = "text", searchable = Searchable.YES, analyzer = "english", searchAnalyzer = "english_search")
@FullTextField(name = "text_de", searchable = Searchable.YES, analyzer = "german", searchAnalyzer = "german_search") @FullTextField(name = "text_de", searchable = Searchable.YES, analyzer = "german", searchAnalyzer = "german_search")
private String text; private String text;

View File

@ -7,17 +7,17 @@ import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.persistence.Column; import jakarta.persistence.Column;
import javax.persistence.Entity; import jakarta.persistence.Entity;
import javax.persistence.EntityListeners; import jakarta.persistence.EntityListeners;
import javax.persistence.EnumType; import jakarta.persistence.EnumType;
import javax.persistence.Enumerated; import jakarta.persistence.Enumerated;
import javax.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import javax.persistence.GenerationType; import jakarta.persistence.GenerationType;
import javax.persistence.Id; import jakarta.persistence.Id;
import javax.persistence.Lob; import jakarta.persistence.Lob;
import javax.persistence.Table; import jakarta.persistence.Table;
import javax.persistence.Transient; import jakarta.persistence.Transient;
import org.hibernate.search.engine.backend.types.Projectable; import org.hibernate.search.engine.backend.types.Projectable;
import org.hibernate.search.engine.backend.types.Searchable; import org.hibernate.search.engine.backend.types.Searchable;
@ -74,7 +74,7 @@ public class Entry {
@FullTextField(name = "title_de", searchable = Searchable.YES, analyzer = "german", searchAnalyzer = "german_search") @FullTextField(name = "title_de", searchable = Searchable.YES, analyzer = "german", searchAnalyzer = "german_search")
private String title; private String title;
@Lob @Lob
@Column(name = "text") @Column(name = "text", length = 100000)
@FullTextField(name = "text", searchable = Searchable.YES, analyzer = "english", searchAnalyzer = "english_search") @FullTextField(name = "text", searchable = Searchable.YES, analyzer = "english", searchAnalyzer = "english_search")
@FullTextField(name = "text_de", searchable = Searchable.YES, analyzer = "german", searchAnalyzer = "german_search") @FullTextField(name = "text_de", searchable = Searchable.YES, analyzer = "german", searchAnalyzer = "german_search")
private String text; private String text;

View File

@ -3,13 +3,13 @@
*/ */
package de.bstly.board.model; package de.bstly.board.model;
import javax.persistence.Column; import jakarta.persistence.Column;
import javax.persistence.Entity; import jakarta.persistence.Entity;
import javax.persistence.EntityListeners; import jakarta.persistence.EntityListeners;
import javax.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import javax.persistence.GenerationType; import jakarta.persistence.GenerationType;
import javax.persistence.Id; import jakarta.persistence.Id;
import javax.persistence.Table; import jakarta.persistence.Table;
import org.springframework.data.jpa.domain.support.AuditingEntityListener; import org.springframework.data.jpa.domain.support.AuditingEntityListener;

View File

@ -6,17 +6,14 @@ package de.bstly.board.model;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.persistence.CollectionTable; import jakarta.persistence.CollectionTable;
import javax.persistence.Column; import jakarta.persistence.Column;
import javax.persistence.ElementCollection; import jakarta.persistence.ElementCollection;
import javax.persistence.Entity; import jakarta.persistence.Entity;
import javax.persistence.Id; import jakarta.persistence.Id;
import javax.persistence.Lob; import jakarta.persistence.Lob;
import javax.persistence.Table; import jakarta.persistence.Table;
import javax.persistence.Transient; import jakarta.persistence.Transient;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
@ -24,6 +21,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import de.bstly.board.model.support.Types; import de.bstly.board.model.support.Types;
import jakarta.persistence.FetchType;
/** /**
* The Class LocalUser. * The Class LocalUser.
@ -41,12 +39,11 @@ public class LocalUser {
@JsonIgnore @JsonIgnore
@Column(name = "password_hash", nullable = true) @Column(name = "password_hash", nullable = true)
private String passwordHash; private String passwordHash;
@ElementCollection @ElementCollection(fetch = FetchType.EAGER)
@LazyCollection(LazyCollectionOption.FALSE)
@CollectionTable(name = "users_roles") @CollectionTable(name = "users_roles")
private List<String> roles; private List<String> roles;
@Lob @Lob
@Column(name = "about", nullable = true) @Column(name = "about", nullable = true, length = 100000)
private String about; private String about;
@Column(name = "email", nullable = true) @Column(name = "email", nullable = true)
private String email; private String email;
@ -54,8 +51,7 @@ public class LocalUser {
private String locale; private String locale;
@Column(name = "dark_theme", columnDefinition = "boolean default false") @Column(name = "dark_theme", columnDefinition = "boolean default false")
private boolean darkTheme; private boolean darkTheme;
@ElementCollection @ElementCollection(fetch = FetchType.EAGER)
@LazyCollection(LazyCollectionOption.FALSE)
@CollectionTable(name = "users_settings") @CollectionTable(name = "users_settings")
private Map<String, String> settings; private Map<String, String> settings;
@Transient @Transient

View File

@ -5,10 +5,10 @@ package de.bstly.board.model;
import java.time.Instant; import java.time.Instant;
import javax.persistence.Column; import jakarta.persistence.Column;
import javax.persistence.Entity; import jakarta.persistence.Entity;
import javax.persistence.Id; import jakarta.persistence.Id;
import javax.persistence.Table; import jakarta.persistence.Table;
/** /**
* The Class PersistentLogin. * The Class PersistentLogin.

View File

@ -5,11 +5,11 @@ package de.bstly.board.model;
import java.io.Serializable; import java.io.Serializable;
import javax.persistence.Column; import jakarta.persistence.Column;
import javax.persistence.Entity; import jakarta.persistence.Entity;
import javax.persistence.Id; import jakarta.persistence.Id;
import javax.persistence.IdClass; import jakarta.persistence.IdClass;
import javax.persistence.Table; import jakarta.persistence.Table;
/** /**
* The Class Tag. * The Class Tag.

View File

@ -5,24 +5,22 @@ package de.bstly.board.model;
import java.util.List; import java.util.List;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.springframework.data.jpa.domain.support.AuditingEntityListener; import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import de.bstly.board.model.support.EntryType; import de.bstly.board.model.support.EntryType;
import de.bstly.board.model.support.ViewSorting; import de.bstly.board.model.support.ViewSorting;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
/** /**
* The Class View. * The Class View.
@ -45,12 +43,10 @@ public class View {
private ViewSorting sorting; private ViewSorting sorting;
@Column(name = "indexNumber") @Column(name = "indexNumber")
private int index = 99; private int index = 99;
@ElementCollection @ElementCollection(fetch = FetchType.EAGER)
@LazyCollection(LazyCollectionOption.FALSE)
@CollectionTable(name = "views_tags") @CollectionTable(name = "views_tags")
private List<String> tags; private List<String> tags;
@ElementCollection @ElementCollection(fetch = FetchType.EAGER)
@LazyCollection(LazyCollectionOption.FALSE)
@CollectionTable(name = "views_excluded_tags") @CollectionTable(name = "views_excluded_tags")
private List<String> excludedTags; private List<String> excludedTags;
@Column(name = "entry_type", nullable = true) @Column(name = "entry_type", nullable = true)

View File

@ -3,13 +3,13 @@
*/ */
package de.bstly.board.model; package de.bstly.board.model;
import javax.persistence.Column; import jakarta.persistence.Column;
import javax.persistence.Entity; import jakarta.persistence.Entity;
import javax.persistence.EntityListeners; import jakarta.persistence.EntityListeners;
import javax.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import javax.persistence.GenerationType; import jakarta.persistence.GenerationType;
import javax.persistence.Id; import jakarta.persistence.Id;
import javax.persistence.Table; import jakarta.persistence.Table;
import org.springframework.data.jpa.domain.support.AuditingEntityListener; import org.springframework.data.jpa.domain.support.AuditingEntityListener;

View File

@ -3,7 +3,7 @@
*/ */
package de.bstly.board.security; package de.bstly.board.security;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices; import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;

View File

@ -6,9 +6,9 @@ package de.bstly.board.security;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import javax.servlet.ServletException; import jakarta.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;

View File

@ -10,8 +10,9 @@ import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; 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.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
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.crypto.argon2.Argon2PasswordEncoder; import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
@ -36,7 +37,8 @@ import de.bstly.board.businesslogic.UserManager;
* The Class SecurityConfig. * The Class SecurityConfig.
*/ */
@EnableWebSecurity @EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) @EnableMethodSecurity(prePostEnabled = true)
@Configuration
public class SecurityConfig { public class SecurityConfig {
@Autowired @Autowired
@ -65,28 +67,27 @@ public class SecurityConfig {
http http
// crsf // crsf
.csrf().disable() .csrf((csrf) -> csrf.disable())
// cors // cors
// .cors().configurationSource(corsConfigurationSource()).and() // .cors().configurationSource(corsConfigurationSource()).and()
// anonymous // anonymous
.anonymous().disable() .anonymous((anonymous) -> anonymous.disable())
// login // login
.formLogin().loginPage("/login").defaultSuccessUrl(loginTargetUrl) .formLogin((formLogin) -> formLogin.loginPage("/login").defaultSuccessUrl(loginTargetUrl)
.failureHandler(new SimpleUrlAuthenticationFailureHandler(loginUrl + "?error")).and() .failureHandler(new SimpleUrlAuthenticationFailureHandler(loginUrl + "?error")))
// remember me // remember me
.rememberMe().rememberMeServices(rememberMeServices()).and() .rememberMe((rememberMe) -> rememberMe.rememberMeServices(rememberMeServices()))
// logout // logout
.logout().logoutUrl("/logout") .logout((logout) -> logout.logoutUrl("/logout")
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)).and() .logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK)))
// exception // exception
.exceptionHandling() .exceptionHandling((exceptionHandling) -> exceptionHandling
.defaultAuthenticationEntryPointFor(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED), .defaultAuthenticationEntryPointFor(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED),
new AntPathRequestMatcher("/api/**")) new AntPathRequestMatcher("/api/**")))
.and()
// oidc // oidc
.oauth2Login().successHandler(oAuth2AuthenticationSuccessHandler) .oauth2Login((oauth2Login) -> oauth2Login.successHandler(oAuth2AuthenticationSuccessHandler)
.failureHandler(new SimpleUrlAuthenticationFailureHandler(loginUrl + "?externalError")) .failureHandler(new SimpleUrlAuthenticationFailureHandler(loginUrl + "?externalError"))
.loginPage("/login"); .loginPage("/login"));
return http.build(); return http.build();
} }
@ -98,7 +99,7 @@ public class SecurityConfig {
*/ */
@Bean(name = "passwordEncoder") @Bean(name = "passwordEncoder")
public Argon2PasswordEncoder passwordEncoder() { public Argon2PasswordEncoder passwordEncoder() {
return new Argon2PasswordEncoder(); return Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8();
} }
/** /**