upgrade to Spring Boot 4, add webauthn support, some cleanup

This commit is contained in:
2025-12-18 20:55:43 +01:00
parent c27e68caf0
commit b4b2552e7e
326 changed files with 2768 additions and 1075 deletions
+5
View File
@@ -82,6 +82,11 @@
<artifactId>webstly-urlshortener</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.bstly.we</groupId>
<artifactId>webauthn</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.bstly.we</groupId>
<artifactId>webstly-wireguard</artifactId>
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we;
import java.util.EnumSet;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.businesslogic;
import java.util.Iterator;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.businesslogic;
/**
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.businesslogic;
import java.text.ParseException;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.controller;
import java.util.Optional;
@@ -100,7 +97,7 @@ public class BorrowItemController extends BaseController {
*/
@PreAuthorize("isAuthenticated()")
@GetMapping("/{id}")
public BorrowItem getBorrowItem(@PathVariable("id") Long id) {
public BorrowItem getBorrowItem(@PathVariable Long id) {
if (!permissionManager.hasPermission(getCurrentUserId(), BorrowPermissions.BORROW_REQUESTS)
|| !permissionManager.isFullUser(getCurrentUserId())) {
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
@@ -109,7 +106,7 @@ public class BorrowItemController extends BaseController {
BorrowItem borrowItem = borrowItemManager.get(id);
if (borrowItem == null) {
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
}
if (!borrowItem.getOwner().equals(getCurrentUserId())) {
@@ -166,7 +163,7 @@ public class BorrowItemController extends BaseController {
*/
@PreAuthorize("isAuthenticated()")
@DeleteMapping("/{id}")
public void deleteBorrowItem(@PathVariable("id") Long id) {
public void deleteBorrowItem(@PathVariable Long id) {
BorrowItem borrowItem = borrowItemManager.get(id);
if (borrowItem == null || !borrowItem.getOwner().equals(getCurrentUserId())) {
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.controller;
import java.text.ParseException;
@@ -163,7 +160,7 @@ public class BorrowRequestController extends BaseController {
*/
@PreAuthorize("isAuthenticated()")
@DeleteMapping("/{id}")
public void deleteBorrowRequest(@PathVariable("id") Long id) {
public void deleteBorrowRequest(@PathVariable Long id) {
BorrowRequest borrowRequest = borrowRequestManager.get(id);
if (borrowRequest == null || !borrowRequest.getUser().equals(getCurrentUserId())) {
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
@@ -212,14 +209,14 @@ public class BorrowRequestController extends BaseController {
*/
@PreAuthorize("isAuthenticated()")
@GetMapping("/code/{id}")
public String getCode(@PathVariable("id") Long id, HttpServletRequest request) {
public String getCode(@PathVariable Long id, HttpServletRequest request) {
BorrowRequest borrowRequest = borrowRequestManager.get(id);
if (borrowRequest == null || !borrowRequest.getUser().equals(getCurrentUserId())) {
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
}
if (!borrowRequest.getStatus().equals(BorrowRequestStatus.ACCEPTED)) {
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
}
String issuer = jwtBorrowIssuer;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.controller.validation;
import org.apache.commons.validator.routines.EmailValidator;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.controller.validation;
import java.text.ParseException;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.controller.validation;
import java.time.Duration;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.model;
import java.time.Duration;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.model;
/**
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.model;
import java.time.Instant;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.model;
import java.time.DayOfWeek;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.model;
import jakarta.persistence.Column;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.model;
import java.time.Instant;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.model;
/**
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.repository;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.repository;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.repository;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.repository;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.borrow.repository;
import org.springframework.data.domain.Page;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we;
import jakarta.persistence.EntityManager;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.time.Instant;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.time.Instant;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
/**
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
/**
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.time.Instant;
@@ -0,0 +1,457 @@
package de.bstly.we.businesslogic;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.google.common.collect.Lists;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import de.bstly.we.businesslogic.support.InstantHelper;
import de.bstly.we.model.QQuotaExtension;
import de.bstly.we.model.QuotaExtension;
import de.bstly.we.model.QuotaExtensionMapping;
import de.bstly.we.model.UserData;
import de.bstly.we.repository.QuotaExtensionRepository;
/**
* The Class QuotaExtensionManager.
*/
@Component
public class QuotaExtensionManager implements UserDataProvider {
@Autowired
private QuotaExtensionRepository quotaExtensionRepository;
@Autowired
private QuotaExtensionMappingManager quotaExtensionMappingManager;
private QQuotaExtension qQuotaExtension = QQuotaExtension.quotaExtension;
DateTimeFormatter pretixOffsetDateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssx");
/**
* Gets the active extensions by target.
*
* @param target the target
* @return the active extensions by target
*/
public List<QuotaExtension> getNotExpiresByTarget(Long target) {
return getNotExpiresByTarget(target, null);
}
/**
* Gets the active extensions by target.
*
* @param target the target
* @param sort the sort
* @return the active extensions by target
*/
public List<QuotaExtension> getNotExpiresByTarget(Long target, String sort) {
if (target != null) {
return Lists.newArrayList(quotaExtensionRepository.findAll(
qQuotaExtension.target.eq(target)
.and(qQuotaExtension.expires.after(Instant.now())
.and(qQuotaExtension.starts.isNull()
.or(qQuotaExtension.starts.before(Instant.now())))),
Sort.by(StringUtils.hasText(sort) ? sort : "id")));
}
return Lists.newArrayList();
}
/**
* Gets the active extensions by target and name.
*
* @param target the target
* @param name the name
* @return the active extensions by target and name
*/
public List<QuotaExtension> getActiveExtensions(Long target, String name) {
return getActiveExtensions(target, name, null);
}
/**
* Gets the active extensions by target and name.
*
* @param target the target
* @param name the name
* @param sort the sort
* @return the active extensions by target and name
*/
public List<QuotaExtension> getActiveExtensions(Long target, String name, String sort) {
if (target != null && StringUtils.hasText(name)) {
return Lists.newArrayList(quotaExtensionRepository.findAll(
qQuotaExtension.target.eq(target).and(qQuotaExtension.name.eq(name))
.and(qQuotaExtension.expires.after(Instant.now())
.and(qQuotaExtension.starts.isNull()
.or(qQuotaExtension.starts.before(Instant.now())))),
Sort.by(StringUtils.hasText(sort) ? sort : "id")));
}
return Lists.newArrayList();
}
/**
* Gets the total active extension value.
*
* @param target the target
* @param name the name
* @return the total active extension value
*/
public long getActiveExtensionValue(Long target, String name) {
return getActiveExtensions(target, name).stream()
.mapToLong(QuotaExtension::getValue)
.sum();
}
/**
* Gets the all by target.
*
* @param target the target
* @return the all by target
*/
public List<QuotaExtension> getAllByTarget(Long target) {
return getAllByTarget(target, null);
}
/**
* Gets the all by target.
*
* @param target the target
* @param sort the sort
* @return the all by target
*/
public List<QuotaExtension> getAllByTarget(Long target, String sort) {
if (target != null) {
return Lists.newArrayList(quotaExtensionRepository.findAll(qQuotaExtension.target.eq(target),
Sort.by(StringUtils.hasText(sort) ? sort : "id")));
}
return Lists.newArrayList();
}
/**
* Creates the.
*
* @param target the target
* @param name the name
* @param value the value
* @param unit the unit
* @param starts the starts
* @param expires the expires
* @param source the source
* @param description the description
* @return the quota extension
*/
public QuotaExtension create(Long target, String name, long value, String unit, Instant starts, Instant expires,
String source, String description) {
QuotaExtension newQuotaExtension = new QuotaExtension();
newQuotaExtension.setTarget(target);
newQuotaExtension.setName(name);
newQuotaExtension.setValue(value);
newQuotaExtension.setUnit(unit);
newQuotaExtension.setStarts(starts);
newQuotaExtension.setExpires(expires);
newQuotaExtension.setSource(source);
newQuotaExtension.setDescription(description);
return quotaExtensionRepository.save(newQuotaExtension);
}
/**
* Update.
*
* @param quotaExtension the quota extension
* @return the quota extension
*/
public QuotaExtension update(QuotaExtension quotaExtension) {
Assert.isTrue(quotaExtensionRepository.existsById(quotaExtension.getId()),
"QuotaExtension '" + quotaExtension.getId() + "' does not exists!");
QuotaExtension updateQuotaExtension = quotaExtensionRepository.findById(quotaExtension.getId()).get();
updateQuotaExtension.setValue(quotaExtension.getValue());
updateQuotaExtension.setUnit(quotaExtension.getUnit());
updateQuotaExtension.setStarts(quotaExtension.getStarts());
updateQuotaExtension.setExpires(quotaExtension.getExpires());
updateQuotaExtension.setSource(quotaExtension.getSource());
updateQuotaExtension.setDescription(quotaExtension.getDescription());
return quotaExtensionRepository.save(updateQuotaExtension);
}
/**
* Delete.
*
* @param id the id
*/
public void delete(Long id) {
Assert.isTrue(quotaExtensionRepository.existsById(id), "QuotaExtension '" + id + "' does not exists!");
quotaExtensionRepository.deleteById(id);
}
public void addForItem(Long target, Integer item, List<QuotaExtension> quotas) {
for (QuotaExtensionMapping quotaMapping : quotaExtensionMappingManager.getAllByItem(item)) {
boolean added = false;
for (QuotaExtension quotaExtension : quotas) {
if (quotaExtension.getName().equals(quotaMapping.getName())) {
quotaExtension.setValue(quotaMapping.getValue());
added = true;
}
}
if (!added) {
QuotaExtension quotaExtension = new QuotaExtension();
quotaExtension.setName(quotaMapping.getName());
quotaExtension.setValue(quotaMapping.getValue());
quotaExtension.setUnit(quotaMapping.getUnit());
quotas.add(quotaExtension);
}
}
}
/**
* Apply item - creates extensions based on mapping rules.
*
* @param target the target
* @param item the item
* @param answers the answers
* @param starts the starts
* @param expires the expires
*/
public void applyItem(Long target, Integer item, JsonArray answers, Instant starts, Instant expires) {
for (QuotaExtension quotaExtension : getForItem(target, item, answers, starts, expires)) {
quotaExtensionRepository.save(quotaExtension);
}
}
/**
* Gets extensions for item - mirrors PermissionManager.getForItem logic.
*
* @param target the target
* @param item the item
* @param answers the answers
* @param starts the starts
* @param expires the expires
* @return the list of quota extensions
*/
public List<QuotaExtension> getForItem(Long target, Integer item, JsonArray answers, Instant starts,
Instant expires) {
List<QuotaExtension> extensions = Lists.newArrayList();
for (QuotaExtensionMapping extensionMapping : quotaExtensionMappingManager.getAllByItem(item)) {
Instant extensionStarts = starts;
Instant extensionExpires = expires;
if (extensionMapping.getStarts() != null) {
extensionStarts = extensionMapping.getStarts();
}
if (extensionMapping.getExpires() != null) {
extensionExpires = extensionMapping.getExpires();
}
if (extensionExpires == null) {
extensionExpires = InstantHelper.plus(extensionStarts == null ? Instant.now() : extensionStarts,
extensionMapping.getLifetime(), extensionMapping.getLifetimeUnit());
}
// Process question-based dates (mirroring permission logic)
for (JsonElement answer : answers) {
if (answer.isJsonObject() && answer.getAsJsonObject().has("question_identifier")) {
if (StringUtils.hasText(extensionMapping.getStartsQuestion())
&& extensionMapping.getStartsQuestion()
.equals(answer.getAsJsonObject().get("question_identifier").getAsString())
&& answer.getAsJsonObject().has("answer")) {
String dateTimeString = answer.getAsJsonObject().get("answer").getAsString();
if (StringUtils.hasText(dateTimeString)) {
dateTimeString = dateTimeString.replace(" ", "T");
extensionStarts = OffsetDateTime.parse(dateTimeString).toInstant();
extensionExpires = InstantHelper.plus(extensionStarts,
extensionMapping.getLifetime(), extensionMapping.getLifetimeUnit());
}
}
if (StringUtils.hasText(extensionMapping.getExpiresQuestion())
&& extensionMapping.getExpiresQuestion()
.equals(answer.getAsJsonObject().get("question_identifier").getAsString())
&& answer.getAsJsonObject().has("answer")) {
String dateTimeString = answer.getAsJsonObject().get("answer").getAsString();
if (StringUtils.hasText(dateTimeString)) {
dateTimeString = dateTimeString.replace(" ", "T");
extensionExpires = InstantHelper.plus(
OffsetDateTime.parse(dateTimeString).toInstant(),
extensionMapping.getLifetime(), extensionMapping.getLifetimeUnit());
}
}
}
}
// Create the extension
QuotaExtension extension = new QuotaExtension();
extension.setTarget(target);
extension.setName(extensionMapping.getName());
extension.setValue(extensionMapping.getValue());
extension.setUnit(extensionMapping.getUnit());
extension.setStarts(extensionStarts);
extension.setExpires(extensionExpires);
// Apply start cleanup and lifetime rounding
if (extension.getStarts() != null && extension.getStarts().isBefore(Instant.now())) {
extension.setStarts(null);
}
if (extensionMapping.isLifetimeRound()) {
extension.setExpires(
InstantHelper.truncate(extension.getExpires(), extensionMapping.getLifetimeUnit()));
}
extensions.add(extension);
}
return extensions;
}
/**
* Cleanup expired extensions.
*/
public void cleanupExpiredExtensions() {
for (QuotaExtension extension : quotaExtensionRepository
.findAll(qQuotaExtension.expires.before(Instant.now()))) {
quotaExtensionRepository.delete(extension);
}
}
/*
* @see de.bstly.we.businesslogic.UserDataProvider#getId()
*/
@Override
public String getId() {
return "quota_extensions";
}
/*
* @see de.bstly.we.businesslogic.UserDataProvider#getUserData(java.lang.Long)
*/
@Override
public List<UserData> getUserData(Long userId) {
List<UserData> result = Lists.newArrayList();
for (QuotaExtension extension : getAllByTarget(userId)) {
result.add(extension);
}
return result;
}
/**
* Gets all quota extensions with predicate and pageable.
*
* @param predicate the predicate
* @param pageable the pageable
* @return the page of quota extensions
*/
public org.springframework.data.domain.Page<QuotaExtension> getAll(com.querydsl.core.types.Predicate predicate,
org.springframework.data.domain.Pageable pageable) {
return quotaExtensionRepository.findAll(predicate, pageable);
}
/**
* Gets quota extension by id.
*
* @param id the id
* @return the quota extension
*/
public QuotaExtension get(Long id) {
Assert.notNull(id, "id must not be null!");
return quotaExtensionRepository.findById(id).orElse(null);
}
/**
* Gets quota extensions by target.
*
* @param target the target
* @return the list of quota extensions
*/
public List<QuotaExtension> getByTarget(Long target) {
Assert.notNull(target, "target must not be empty!");
return Lists.newArrayList(quotaExtensionRepository.findAll(qQuotaExtension.target.eq(target),
Sort.by("expires").ascending()));
}
/**
* Gets active quota extensions by target.
*
* @param target the target
* @return the list of active quota extensions
*/
public List<QuotaExtension> getActiveExtensions(Long target) {
Assert.notNull(target, "target must not be empty!");
Instant now = Instant.now();
return Lists.newArrayList(quotaExtensionRepository.findAll(
qQuotaExtension.target.eq(target)
.and(qQuotaExtension.expires.after(now))
.and(qQuotaExtension.starts.isNull().or(qQuotaExtension.starts.before(now))),
Sort.by("expires").ascending()));
}
/**
* Creates a quota extension.
*
* @param quotaExtension the quota extension to create
* @return the created quota extension
*/
public QuotaExtension create(QuotaExtension quotaExtension) {
Assert.notNull(quotaExtension, "quotaExtension must not be null!");
Assert.isNull(quotaExtension.getTarget(), "target must not be empty!");
Assert.hasText(quotaExtension.getName(), "name must not be empty!");
Assert.notNull(quotaExtension.getExpires(), "expires must not be null!");
Assert.isTrue(quotaExtension.getValue() > 0, "value must be positive!");
return quotaExtensionRepository.save(quotaExtension);
}
/**
* Updates a quota extension.
*
* @param id the id of the quota extension
* @param quotaExtension the updated quota extension data
* @return the updated quota extension
*/
public QuotaExtension update(Long id, QuotaExtension quotaExtension) {
Assert.notNull(id, "id must not be null!");
Assert.notNull(quotaExtension, "quotaExtension must not be null!");
QuotaExtension existingExtension = get(id);
Assert.notNull(existingExtension, "QuotaExtension with id " + id + " not found!");
existingExtension.setTarget(quotaExtension.getTarget());
existingExtension.setName(quotaExtension.getName());
existingExtension.setValue(quotaExtension.getValue());
existingExtension.setUnit(quotaExtension.getUnit());
existingExtension.setExpires(quotaExtension.getExpires());
existingExtension.setStarts(quotaExtension.getStarts());
existingExtension.setSource(quotaExtension.getSource());
existingExtension.setDescription(quotaExtension.getDescription());
return quotaExtensionRepository.save(existingExtension);
}
/**
* Cleanup expired quota extensions.
*/
public void cleanupExpired() {
Instant now = Instant.now();
List<QuotaExtension> expiredExtensions = Lists.newArrayList(quotaExtensionRepository.findAll(
qQuotaExtension.expires.before(now)));
quotaExtensionRepository.deleteAll(expiredExtensions);
}
@Override
public void purgeUserData(Long userId) {
for (QuotaExtension quotaExtension : getAllByTarget(userId)) {
quotaExtensionRepository.delete(quotaExtension);
}
}
}
@@ -0,0 +1,153 @@
package de.bstly.we.businesslogic;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import com.google.common.collect.Lists;
import de.bstly.we.model.QQuotaExtensionMapping;
import de.bstly.we.model.QuotaExtensionMapping;
import de.bstly.we.repository.QuotaExtensionMappingRepository;
/**
* The Class QuotaExtensionMappingManager.
*/
@Component
public class QuotaExtensionMappingManager {
@Autowired
private QuotaExtensionMappingRepository quotaExtensionMappingRepository;
private QQuotaExtensionMapping qQuotaExtensionMapping = QQuotaExtensionMapping.quotaExtensionMapping;
/**
* Gets the all by item.
*
* @param item the item
* @return the all by item
*/
public List<QuotaExtensionMapping> getAllByItem(Integer item) {
return Lists.newArrayList(quotaExtensionMappingRepository.findAll(qQuotaExtensionMapping.items.contains(item)));
}
/**
* Exists.
*
* @param item the item
* @return true, if successful
*/
public boolean exists(Integer item) {
return quotaExtensionMappingRepository.exists(qQuotaExtensionMapping.items.contains(item));
}
/**
* Exists.
*
* @param item the item
* @param name the name
* @return true, if successful
*/
public boolean exists(Integer item, String name) {
return quotaExtensionMappingRepository
.exists(qQuotaExtensionMapping.items.contains(item).and(qQuotaExtensionMapping.name.eq(name)));
}
/**
* Creates the.
*
* @param items the items
* @param name the name
* @param value the value
* @param unit the unit
* @param lifetime the lifetime
* @param lifetimeUnit the lifetime unit
* @param lifetimeRound the lifetime round
* @param products the products
* @param starts the starts
* @param expires the expires
* @param startsQuestion the starts question
* @param expiresQuestion the expires question
* @return the quota extension mapping
*/
public QuotaExtensionMapping create(Set<Integer> items, String name, long value, String unit, Long lifetime,
ChronoUnit lifetimeUnit, boolean lifetimeRound, Set<String> products, Instant starts, Instant expires,
String startsQuestion, String expiresQuestion) {
QuotaExtensionMapping quotaExtensionMapping = new QuotaExtensionMapping();
quotaExtensionMapping.setItems(items);
quotaExtensionMapping.setName(name);
quotaExtensionMapping.setValue(value);
quotaExtensionMapping.setUnit(unit);
quotaExtensionMapping.setLifetime(lifetime);
quotaExtensionMapping.setLifetimeUnit(lifetimeUnit);
quotaExtensionMapping.setLifetimeRound(lifetimeRound);
quotaExtensionMapping.setProducts(products);
quotaExtensionMapping.setStarts(starts);
quotaExtensionMapping.setExpires(expires);
quotaExtensionMapping.setStartsQuestion(startsQuestion);
quotaExtensionMapping.setExpiresQuestion(expiresQuestion);
return quotaExtensionMappingRepository.save(quotaExtensionMapping);
}
/**
* Update.
*
* @param quotaExtensionMapping the quota extension mapping
* @return the quota extension mapping
*/
public QuotaExtensionMapping update(QuotaExtensionMapping quotaExtensionMapping) {
Assert.isTrue(
quotaExtensionMapping.getId() != null
&& quotaExtensionMappingRepository.existsById(quotaExtensionMapping.getId()),
"QuotaExtensionMapping '" + quotaExtensionMapping.getId() + "' does not exists!");
QuotaExtensionMapping updateQuotaExtensionMapping = quotaExtensionMappingRepository
.findById(quotaExtensionMapping.getId()).get();
updateQuotaExtensionMapping.setItems(quotaExtensionMapping.getItems());
updateQuotaExtensionMapping.setName(quotaExtensionMapping.getName());
updateQuotaExtensionMapping.setValue(quotaExtensionMapping.getValue());
updateQuotaExtensionMapping.setUnit(quotaExtensionMapping.getUnit());
updateQuotaExtensionMapping.setLifetime(quotaExtensionMapping.getLifetime());
updateQuotaExtensionMapping.setLifetimeUnit(quotaExtensionMapping.getLifetimeUnit());
updateQuotaExtensionMapping.setLifetimeRound(quotaExtensionMapping.isLifetimeRound());
updateQuotaExtensionMapping.setProducts(quotaExtensionMapping.getProducts());
updateQuotaExtensionMapping.setStarts(quotaExtensionMapping.getStarts());
updateQuotaExtensionMapping.setExpires(quotaExtensionMapping.getExpires());
updateQuotaExtensionMapping.setStartsQuestion(quotaExtensionMapping.getStartsQuestion());
updateQuotaExtensionMapping.setExpiresQuestion(quotaExtensionMapping.getExpiresQuestion());
return quotaExtensionMappingRepository.save(updateQuotaExtensionMapping);
}
/**
* Delete.
*
* @param id the id
*/
public void delete(Long id) {
Assert.isTrue(quotaExtensionMappingRepository.existsById(id),
"QuotaExtensionMapping '" + id + "' does not exists!");
quotaExtensionMappingRepository.deleteById(id);
}
/**
* Gets the.
*
* @param page the page
* @param size the size
* @param sortBy the sort by
* @param descending the descending
* @return the page
*/
public Page<QuotaExtensionMapping> get(int page, int size, String sortBy, boolean descending) {
Sort sort = descending ? Sort.by(sortBy).descending() : Sort.by(sortBy).ascending();
return quotaExtensionMappingRepository.findAll(PageRequest.of(page, size, sort));
}
}
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.util.List;
@@ -29,6 +26,8 @@ public class QuotaManager implements UserDataProvider {
private QuotaRepository quotaRepository;
@Autowired
private QuotaMappingManager quotaMappingManager;
@Autowired
private QuotaExtensionManager quotaExtensionManager;
private QQuota qQuota = QQuota.quota;
/**
@@ -129,6 +128,23 @@ public class QuotaManager implements UserDataProvider {
&& quotaRepository.exists(qQuota.name.eq(name).and(qQuota.target.eq(target)).and(qQuota.value.gt(0)));
}
/**
* Gets the effective quota value (base quota + active extensions).
*
* @param target the target
* @param name the name
* @return the effective quota value
*/
public long getEffectiveQuotaValue(Long target, String name) {
Quota baseQuota = get(target, name);
long baseValue = baseQuota != null ? baseQuota.getValue() : 0;
// Add all active extension values
long extensionValue = quotaExtensionManager.getActiveExtensionValue(target, name);
return baseValue + extensionValue;
}
/**
* Creates the.
*
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
/**
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.time.Instant;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.io.BufferedReader;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import org.springframework.beans.factory.annotation.Autowired;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import org.springframework.beans.factory.annotation.Autowired;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.time.Instant;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.util.Hashtable;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.io.BufferedReader;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
/**
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic.support;
import jakarta.persistence.PostLoad;
@@ -0,0 +1,21 @@
package de.bstly.we.businesslogic.support;
import java.time.temporal.ChronoUnit;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
@Converter
public class ChronoUnitConverter implements AttributeConverter<ChronoUnit, String> {
@Override
public String convertToDatabaseColumn(ChronoUnit chronoUnit) {
return chronoUnit.name();
}
@Override
public ChronoUnit convertToEntityAttribute(String value) {
return ChronoUnit.valueOf(value);
}
}
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.businesslogic.support;
import java.time.Instant;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -110,8 +107,8 @@ public class Authentication2FAController extends BaseController {
*/
@PreAuthorize("authentication.authenticated")
@GetMapping("/{id}")
public void isSecondFactorEnabled(@PathVariable("id") String providerId) {
SecondFactorProvider<?> provider = secondFactorProviderManager.getProvider(providerId);
public void isSecondFactorEnabled(@PathVariable String id) {
SecondFactorProvider<?> provider = secondFactorProviderManager.getProvider(id);
if (provider == null) {
throw new EntityResponseStatusException(HttpStatus.UNAUTHORIZED);
@@ -123,18 +120,19 @@ public class Authentication2FAController extends BaseController {
}
/**
* Request second factor mail.
* Request second factor.
*
* @param providerId the provider id
* @return the challenge data (e.g., PublicKeyCredentialRequestOptions for WebAuthn)
*/
@PreAuthorize("hasRole('ROLE_PRE_AUTH_USER')")
@PostMapping("/{id}")
public void requestSecondFactorMail(@PathVariable("id") String providerId) {
public Object requestSecondFactor(@PathVariable String id) {
Long userId = getPreAuthenticationId();
if (userId == null) {
throw new EntityResponseStatusException(HttpStatus.UNAUTHORIZED);
}
SecondFactorProvider<?> provider = secondFactorProviderManager.getProvider(providerId);
SecondFactorProvider<?> provider = secondFactorProviderManager.getProvider(id);
if (provider == null) {
throw new EntityResponseStatusException(HttpStatus.UNAUTHORIZED);
@@ -146,7 +144,7 @@ public class Authentication2FAController extends BaseController {
SecondFactorRequestProvider<?> requestProvider = (SecondFactorRequestProvider<?>) provider;
requestProvider.request(userId);
return requestProvider.request(userId);
}
/**
@@ -157,8 +155,8 @@ public class Authentication2FAController extends BaseController {
*/
@PreAuthorize("authentication.authenticated")
@PutMapping("/{id}")
public SecondFactor createSecondFactor(@PathVariable("id") String providerId) {
SecondFactorProvider<?> provider = secondFactorProviderManager.getProvider(providerId);
public SecondFactor createSecondFactor(@PathVariable String id) {
SecondFactorProvider<?> provider = secondFactorProviderManager.getProvider(id);
if (provider == null) {
throw new EntityResponseStatusException(HttpStatus.UNAUTHORIZED);
@@ -179,8 +177,8 @@ public class Authentication2FAController extends BaseController {
*/
@PreAuthorize("authentication.authenticated")
@PatchMapping("/{id}")
public void enableSecondFactor(@PathVariable("id") String providerId, @RequestBody String token) {
SecondFactorProvider<?> provider = secondFactorProviderManager.getProvider(providerId);
public void enableSecondFactor(@PathVariable String id, @RequestBody String token) {
SecondFactorProvider<?> provider = secondFactorProviderManager.getProvider(id);
if (provider == null) {
throw new EntityResponseStatusException(HttpStatus.UNAUTHORIZED);
@@ -198,8 +196,8 @@ public class Authentication2FAController extends BaseController {
*/
@PreAuthorize("authentication.authenticated")
@DeleteMapping("/{id}")
public void removeSecondFactorMail(@PathVariable("id") String providerId) {
SecondFactorProvider<?> provider = secondFactorProviderManager.getProvider(providerId);
public void removeSecondFactorMail(@PathVariable String id) {
SecondFactorProvider<?> provider = secondFactorProviderManager.getProvider(id);
if (provider == null) {
throw new EntityResponseStatusException(HttpStatus.UNAUTHORIZED);
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.io.IOException;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import org.springframework.security.core.Authentication;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.Map;
@@ -135,7 +132,7 @@ public class ItemController extends BaseController {
*/
@PreAuthorize("isAuthenticated()")
@PostMapping("/{username}")
public void redeemForUser(@PathVariable("username") String username, HttpSession session) {
public void redeemForUser(@PathVariable String username, HttpSession session) {
if (tokenSessionManager.getTokenFromSession(session).isEmpty()) {
throw new EntityResponseStatusException(HttpStatus.NOT_MODIFIED);
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.time.Instant;
@@ -49,8 +46,8 @@ public class PermissionManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/{username}")
public List<Permission> getPermissionsForUser(@PathVariable("username") String username,
@RequestParam("sort") Optional<String> sort, @RequestParam("ignoreStart") Optional<Boolean> ignoreStart) {
public List<Permission> getPermissionsForUser(@PathVariable String username,
@RequestParam Optional<String> sort, @RequestParam Optional<Boolean> ignoreStart) {
User user = userManager.getByUsername(username);
if (user == null) {
@@ -73,7 +70,7 @@ public class PermissionManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/{username}/all")
public List<Permission> getAllPermissionsForUser(@PathVariable("username") String username,
public List<Permission> getAllPermissionsForUser(@PathVariable String username,
@RequestParam("sort") Optional<String> sort) {
User user = userManager.getByUsername(username);
@@ -161,7 +158,7 @@ public class PermissionManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/{name}/clone/{clone}")
public List<Permission> clone(@PathVariable("name") String name, @PathVariable("clone") String clone) {
public List<Permission> clone(@PathVariable String name, @PathVariable String clone) {
if (name.equals(clone)) {
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
}
@@ -192,7 +189,7 @@ public class PermissionManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping("/{target}")
public void deleteAll(@PathVariable("target") Long target) {
public void deleteAll(@PathVariable Long target) {
permissionManager.deleteAll(target);
}
@@ -203,7 +200,7 @@ public class PermissionManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping("/byname/{name}")
public void deleteAllByName(@PathVariable("name") String name) {
public void deleteAllByName(@PathVariable String name) {
permissionManager.deleteAll(name);
}
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.io.IOException;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -0,0 +1,77 @@
package de.bstly.we.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.google.common.collect.Lists;
import de.bstly.we.businesslogic.QuotaExtensionManager;
import de.bstly.we.controller.support.TokenSessionManager;
import de.bstly.we.model.QuotaExtension;
import jakarta.servlet.http.HttpSession;
/**
* The Class QuotaExtensionController.
*/
@RestController
@RequestMapping("/quota/extensions")
public class QuotaExtensionController extends BaseController {
@Autowired
private QuotaExtensionManager quotaExtensionManager;
@Autowired
private TokenSessionManager tokenSessionManager;
/**
* Gets the quotas.
*
* @return the quotas
*/
@GetMapping
public List<QuotaExtension> getQuotaExtensions() {
if (getCurrentUserId() == null) {
return Lists.newArrayList();
}
return quotaExtensionManager.getNotExpiresByTarget(getCurrentUserId());
}
/**
* Gets the new quotas.
*
* @param session the session
* @return the new quotas
*/
@GetMapping("/new")
public List<QuotaExtension> getNewQuotaExtensions(HttpSession session) {
List<QuotaExtension> quotas = Lists.newArrayList();
if (tokenSessionManager.getTokenFromSession(session).isEmpty()) {
return quotas;
}
for (String token : tokenSessionManager.getTokenFromSession(session)) {
tokenSessionManager.addQuotaExtensionsForToken(getCurrentUserId(), token, quotas);
}
return quotas;
}
/**
* Gets the all quotas.
*
* @return the all quotas
*/
@GetMapping("/all")
public List<QuotaExtension> getAllQuotas() {
if (getCurrentUserId() == null) {
return Lists.newArrayList();
}
return quotaExtensionManager.getAllByTarget(getCurrentUserId());
}
}
@@ -0,0 +1,122 @@
package de.bstly.we.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.binding.QuerydslPredicate;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import com.querydsl.core.types.Predicate;
import de.bstly.we.businesslogic.QuotaExtensionManager;
import de.bstly.we.businesslogic.UserManager;
import de.bstly.we.controller.support.EntityResponseStatusException;
import de.bstly.we.model.QuotaExtension;
import de.bstly.we.model.User;
/**
* The Class QuotaExtensionManagementController.
*/
@RestController
@RequestMapping("/management/quota/extensions")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public class QuotaExtensionManagementController {
@Autowired
private QuotaExtensionManager quotaExtensionManager;
@Autowired
private UserManager userManager;
/**
* Get all quota extensions.
*/
@GetMapping
public Page<QuotaExtension> get(@QuerydslPredicate(root = QuotaExtension.class) Predicate predicate,
Pageable pageable) {
return quotaExtensionManager.getAll(predicate, pageable);
}
/**
* Get quota extension by id.
*/
@GetMapping("/{id}")
public QuotaExtension get(@PathVariable Long id) {
return quotaExtensionManager.get(id);
}
/**
* Get quota extensions by target.
*/
@GetMapping("/by-target/{target}")
public List<QuotaExtension> getByTarget(@PathVariable String username) {
User user = userManager.getByUsername(username);
if (user == null) {
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
}
return quotaExtensionManager.getByTarget(user.getId());
}
/**
* Get active quota extensions for target.
*/
@GetMapping("/by-target/{target}/active")
public List<QuotaExtension> getActiveByTarget(@PathVariable String username) {
User user = userManager.getByUsername(username);
if (user == null) {
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
}
return quotaExtensionManager.getActiveExtensions(user.getId());
}
/**
* Create quota extension.
*/
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public QuotaExtension create(@RequestBody QuotaExtension quotaExtension) {
return quotaExtensionManager.create(quotaExtension);
}
/**
* Update quota extension.
*/
@PatchMapping("/{id}")
public QuotaExtension update(@PathVariable Long id, @RequestBody QuotaExtension quotaExtension) {
return quotaExtensionManager.update(id, quotaExtension);
}
/**
* Delete quota extension.
*/
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void delete(@PathVariable Long id) {
quotaExtensionManager.delete(id);
}
/**
* Cleanup expired quota extensions.
*/
@PostMapping("/cleanup")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void cleanup() {
quotaExtensionManager.cleanupExpired();
}
}
@@ -0,0 +1,141 @@
package de.bstly.we.controller;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.google.common.collect.Lists;
import de.bstly.we.businesslogic.QuotaExtensionMappingManager;
import de.bstly.we.controller.support.EntityResponseStatusException;
import de.bstly.we.controller.support.RequestBodyErrors;
import de.bstly.we.controller.validation.QuotaExtensionMappingValidator;
import de.bstly.we.model.QuotaExtensionMapping;
/**
* The Class QuotaExtensionMappingController.
*/
@RestController
@RequestMapping("/quotas/extension-mappings")
public class QuotaExtensionMappingController extends BaseController {
@Autowired
private QuotaExtensionMappingManager quotaExtensionMappingManager;
@Autowired
private QuotaExtensionMappingValidator quotaExtensionMappingValidator;
/**
* Gets the quota extension mappings.
*
* @param pageParameter the page parameter
* @param sizeParameter the size parameter
* @return the quota extension mappings
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping
public Page<QuotaExtensionMapping> getQuotaExtensionMappings(@RequestParam("page") Optional<Integer> pageParameter,
@RequestParam("size") Optional<Integer> sizeParameter) {
return quotaExtensionMappingManager.get(pageParameter.orElse(0), sizeParameter.orElse(10), "id", true);
}
/**
* Creates the.
*
* @param quotaExtensionMapping the quota extension mapping
* @return the quota extension mapping
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping
public QuotaExtensionMapping create(@RequestBody QuotaExtensionMapping quotaExtensionMapping) {
Errors errors = new RequestBodyErrors(quotaExtensionMapping);
quotaExtensionMappingValidator.validate(quotaExtensionMapping, errors);
if (errors.hasErrors()) {
throw new EntityResponseStatusException(errors.getAllErrors(), HttpStatus.CONFLICT);
}
return quotaExtensionMappingManager.create(quotaExtensionMapping.getItems(), quotaExtensionMapping.getName(),
quotaExtensionMapping.getValue(), quotaExtensionMapping.getUnit(), quotaExtensionMapping.getLifetime(),
quotaExtensionMapping.getLifetimeUnit(), quotaExtensionMapping.isLifetimeRound(),
quotaExtensionMapping.getProducts(), quotaExtensionMapping.getStarts(),
quotaExtensionMapping.getExpires(),
quotaExtensionMapping.getStartsQuestion(), quotaExtensionMapping.getExpiresQuestion());
}
/**
* Creates the list.
*
* @param quotaExtensionMappings the quota extension mappings
* @return the list
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/list")
public List<QuotaExtensionMapping> createList(@RequestBody List<QuotaExtensionMapping> quotaExtensionMappings) {
List<QuotaExtensionMapping> result = Lists.newArrayList();
for (QuotaExtensionMapping quotaExtensionMapping : quotaExtensionMappings) {
Errors errors = new RequestBodyErrors(quotaExtensionMapping);
quotaExtensionMappingValidator.validate(quotaExtensionMapping, errors);
if (errors.hasErrors()) {
throw new EntityResponseStatusException(errors.getAllErrors(), HttpStatus.CONFLICT);
}
result.add(quotaExtensionMappingManager.create(quotaExtensionMapping.getItems(),
quotaExtensionMapping.getName(),
quotaExtensionMapping.getValue(), quotaExtensionMapping.getUnit(),
quotaExtensionMapping.getLifetime(),
quotaExtensionMapping.getLifetimeUnit(), quotaExtensionMapping.isLifetimeRound(),
quotaExtensionMapping.getProducts(), quotaExtensionMapping.getStarts(),
quotaExtensionMapping.getExpires(),
quotaExtensionMapping.getStartsQuestion(), quotaExtensionMapping.getExpiresQuestion()));
}
return result;
}
/**
* Update.
*
* @param quotaExtensionMapping the quota extension mapping
* @return the quota extension mapping
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PatchMapping
public QuotaExtensionMapping update(@RequestBody QuotaExtensionMapping quotaExtensionMapping) {
Errors errors = new RequestBodyErrors(quotaExtensionMapping);
if (errors.hasErrors()) {
throw new EntityResponseStatusException(errors.getAllErrors(), HttpStatus.CONFLICT);
}
return quotaExtensionMappingManager.update(quotaExtensionMapping);
}
/**
* Delete.
*
* @param quotaExtensionMapping the quota extension mapping
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping
public void delete(@RequestBody QuotaExtensionMapping quotaExtensionMapping) {
quotaExtensionMappingManager.delete(quotaExtensionMapping.getId());
}
}
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -48,8 +45,8 @@ public class QuotaManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/{username}")
public List<Quota> getQuotasForUser(@PathVariable("username") String username,
@RequestParam("sort") Optional<String> sort) {
public List<Quota> getQuotasForUser(@PathVariable String username,
@RequestParam Optional<String> sort) {
User user = userManager.getByUsername(username);
if (user == null) {
@@ -68,8 +65,8 @@ public class QuotaManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/{username}/all")
public List<Quota> getAllQuotasForUser(@PathVariable("username") String username,
@RequestParam("sort") Optional<String> sort) {
public List<Quota> getAllQuotasForUser(@PathVariable String username,
@RequestParam Optional<String> sort) {
User user = userManager.getByUsername(username);
if (user == null) {
@@ -88,7 +85,7 @@ public class QuotaManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/byname/{name}")
public List<Quota> getQuotasByName(@PathVariable("name") String name, @RequestParam("sort") Optional<String> sort) {
public List<Quota> getQuotasByName(@PathVariable String name, @RequestParam Optional<String> sort) {
return quotaManager.getAllByName(name, sort.orElse(null));
}
@@ -174,7 +171,7 @@ public class QuotaManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/{name}/clone/{clone}")
public List<Quota> clone(@PathVariable("name") String name, @PathVariable("clone") String clone,
public List<Quota> clone(@PathVariable String name, @PathVariable String clone,
@RequestBody long value) {
if (name.equals(clone)) {
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
@@ -205,7 +202,7 @@ public class QuotaManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping("/{target}")
public void deleteAll(@PathVariable("target") Long target) {
public void deleteAll(@PathVariable Long target) {
quotaManager.deleteAll(target);
}
@@ -216,7 +213,7 @@ public class QuotaManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping("/byname/{name}")
public void deleteAllByName(@PathVariable("name") String name) {
public void deleteAllByName(@PathVariable String name) {
quotaManager.deleteAll(name);
}
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -73,7 +70,7 @@ public class SystemController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/properties/{key}")
public SystemProperty getProperty(@PathVariable("key") String key) {
public SystemProperty getProperty(@PathVariable String key) {
if (!systemPropertyRepository.existsById(key)) {
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
}
@@ -111,7 +108,7 @@ public class SystemController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping("/properties/{key}")
public void deleteProperty(@PathVariable("key") String key) {
public void deleteProperty(@PathVariable String key) {
if (!systemPropertyRepository.existsById(key)) {
throw new EntityResponseStatusException(HttpStatus.NOT_MODIFIED);
}
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -57,7 +54,7 @@ public class SystemProfileFieldController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/{name}")
public SystemProfileField getByName(@PathVariable("name") String name) {
public SystemProfileField getByName(@PathVariable String name) {
SystemProfileField systemProfileField = systemProfileFieldManager.get(name);
if (systemProfileField == null) {
@@ -104,7 +101,7 @@ public class SystemProfileFieldController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping("/{name}")
public void deleteByName(@PathVariable("name") String name) {
public void deleteByName(@PathVariable String name) {
SystemProfileField systemProfileField = systemProfileFieldManager.get(name);
if (systemProfileField == null) {
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -123,7 +120,7 @@ public class UserAliasController extends BaseController {
*/
@PreAuthorize("isAuthenticated()")
@DeleteMapping("/{id}")
public void deleteAlias(@PathVariable("id") Long id) {
public void deleteAlias(@PathVariable Long id) {
UserAlias userAlias = userAliasManager.get(id);
if (userAlias == null || !userAlias.getTarget().equals(getCurrentUserId())) {
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -64,7 +61,7 @@ public class UserAliasManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/{username}")
public List<UserAlias> getAliasesForUser(@PathVariable("username") String username) {
public List<UserAlias> getAliasesForUser(@PathVariable String username) {
User user = userManager.getByUsername(username);
if (user == null) {
@@ -100,7 +97,7 @@ public class UserAliasManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping("/{id}")
public void deleteAlias(@PathVariable("id") Long id) {
public void deleteAlias(@PathVariable Long id) {
UserAlias userAlias = userAliasManager.get(id);
if (userAlias == null) {
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import jakarta.servlet.http.HttpSession;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -42,7 +39,7 @@ public class UserDataManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/{username}")
public Map<String, List<UserData>> getForUser(@PathVariable("username") String username) {
public Map<String, List<UserData>> getForUser(@PathVariable String username) {
User user = userManager.getByUsername(username);
if (user == null) {
@@ -59,7 +56,7 @@ public class UserDataManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/purge")
public void purge(@RequestParam("dry") boolean dry) {
public void purge(@RequestParam boolean dry) {
userDataManager.purge(dry);
}
@@ -71,7 +68,7 @@ public class UserDataManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/purge/{username}")
public void purgeByUsername(@PathVariable("username") String username, @RequestParam("dry") boolean dry) {
public void purgeByUsername(@PathVariable String username, @RequestParam boolean dry) {
User user = userManager.getByUsername(username);
if (user == null) {
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -118,7 +115,7 @@ public class UserDomainController extends BaseController {
*/
@PreAuthorize("isAuthenticated()")
@DeleteMapping("/{id}")
public void deleteDomain(@PathVariable("id") Long id) {
public void deleteDomain(@PathVariable Long id) {
UserDomain userDomain = userDomainManager.get(id);
if (userDomain == null || !userDomain.getTarget().equals(getCurrentUserId())) {
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -68,7 +65,7 @@ public class UserDomainManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/{username}")
public List<UserDomain> getDomainsForUser(@PathVariable("username") String username) {
public List<UserDomain> getDomainsForUser(@PathVariable String username) {
User user = userManager.getByUsername(username);
if (user == null) {
@@ -113,7 +110,7 @@ public class UserDomainManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping("/{id}")
public void deleteDomain(@PathVariable("id") Long id) {
public void deleteDomain(@PathVariable Long id) {
UserDomain userDomain = userDomainManager.get(id);
if (userDomain == null) {
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
@@ -128,7 +125,7 @@ public class UserDomainManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/validate/{id}")
public void validate(@PathVariable("id") Long id) {
public void validate(@PathVariable Long id) {
UserDomain userDomain = userDomainManager.get(id);
if (userDomain == null) {
throw new EntityResponseStatusException(HttpStatus.CONFLICT);
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.time.Instant;
@@ -95,7 +92,7 @@ public class UserManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/{username}")
public User getUserByUsername(@PathVariable("username") String username) {
public User getUserByUsername(@PathVariable String username) {
User user = userManager.getByUsername(username);
if (user == null) {
@@ -201,7 +198,7 @@ public class UserManagementController extends BaseController {
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@DeleteMapping("/{username}")
public void deleteUserByUsername(@PathVariable("username") String username) {
public void deleteUserByUsername(@PathVariable String username) {
User user = userManager.getByUsername(username);
if (user == null) {
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -79,7 +76,7 @@ public class UserProfileFieldController extends BaseController {
*/
@PreAuthorize("isAuthenticated()")
@GetMapping("/field/{name}")
public UserProfileField getField(@PathVariable("name") String name) {
public UserProfileField getField(@PathVariable String name) {
UserProfileField userProfileField = userProfileFieldManager.get(getCurrentUserId(), name);
if (userProfileField == null) {
@@ -96,7 +93,7 @@ public class UserProfileFieldController extends BaseController {
* @return the for user
*/
@GetMapping("/{username}")
public ProfileModel getForUser(@PathVariable("username") String username) {
public ProfileModel getForUser(@PathVariable String username) {
Long currentUserId = getCurrentUserId();
User user = userManager.getByUsername(username);
@@ -182,8 +179,8 @@ public class UserProfileFieldController extends BaseController {
* @return the field for user
*/
@GetMapping("/{username}/field/{name}")
public UserProfileField getFieldForUser(@PathVariable("username") String username,
@PathVariable("name") String name) {
public UserProfileField getFieldForUser(@PathVariable String username,
@PathVariable String name) {
User user = userManager.getByUsername(username);
@@ -275,7 +272,7 @@ public class UserProfileFieldController extends BaseController {
*/
@PreAuthorize("isAuthenticated()")
@DeleteMapping("/{name}")
public void delete(@PathVariable("name") String name) {
public void delete(@PathVariable String name) {
if (userProfileFieldManager.get(getCurrentUserId(), name) == null) {
throw new EntityResponseStatusException(HttpStatus.NOT_MODIFIED);
}
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -66,7 +63,7 @@ public class VoucherController extends BaseController {
*/
@PreAuthorize("isAuthenticated()")
@PostMapping("/{name}")
public String getVoucher(@PathVariable("name") String name) {
public String getVoucher(@PathVariable String name) {
if (!permissionManager.isFullUser(getCurrentUserId())) {
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
}
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.debug;
import java.util.Map;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.model;
import java.util.Map;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.model;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.model;
import lombok.Getter;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.model;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.model;
import lombok.Getter;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.model;
import lombok.Getter;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.model;
import java.util.Map;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.model;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.model;
import lombok.AllArgsConstructor;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.model;
import java.util.List;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.support;
import org.springframework.http.HttpHeaders;
@@ -1,10 +1,5 @@
/**
*
*/
package de.bstly.we.controller.support;
import org.springframework.lang.Nullable;
import org.springframework.core.NestedRuntimeException;
import org.springframework.http.HttpStatusCode;
import org.springframework.util.Assert;
@@ -21,7 +16,6 @@ public class EntityResponseStatusException extends NestedRuntimeException {
private final HttpStatusCode status;
@Nullable
private final Object body;
/**
@@ -39,7 +33,7 @@ public class EntityResponseStatusException extends NestedRuntimeException {
* @param body the body
* @param status the status
*/
public EntityResponseStatusException(@Nullable Object body, HttpStatusCode status) {
public EntityResponseStatusException(Object body, HttpStatusCode status) {
this(body, status, null);
}
@@ -50,7 +44,7 @@ public class EntityResponseStatusException extends NestedRuntimeException {
* @param status the status
* @param cause the cause
*/
public EntityResponseStatusException(@Nullable Object body, HttpStatusCode status, @Nullable Throwable cause) {
public EntityResponseStatusException(Object body, HttpStatusCode status, Throwable cause) {
super(null, cause);
Assert.notNull(status, "HttpStatus is required");
this.status = status;
@@ -71,7 +65,6 @@ public class EntityResponseStatusException extends NestedRuntimeException {
*
* @return the body
*/
@Nullable
public Object getBody() {
return this.body;
}
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.support;
import java.io.IOException;
@@ -1,9 +1,5 @@
/**
*
*/
package de.bstly.we.controller.support;
import org.springframework.lang.Nullable;
import org.springframework.validation.AbstractBindingResult;
/**
@@ -12,7 +8,6 @@ import org.springframework.validation.AbstractBindingResult;
@SuppressWarnings("serial")
public class RequestBodyErrors extends AbstractBindingResult {
@Nullable
private final Object target;
/**
@@ -20,7 +15,7 @@ public class RequestBodyErrors extends AbstractBindingResult {
*
* @param target the target
*/
public RequestBodyErrors(@Nullable Object target) {
public RequestBodyErrors(Object target) {
super("request-body");
this.target = target;
}
@@ -1,14 +1,9 @@
/**
*
*/
package de.bstly.we.controller.support;
import java.time.Instant;
import java.util.List;
import java.util.Set;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
@@ -22,15 +17,20 @@ import com.google.gson.JsonObject;
import de.bstly.we.businesslogic.PermissionManager;
import de.bstly.we.businesslogic.PermissionMappingManager;
import de.bstly.we.businesslogic.PretixManager;
import de.bstly.we.businesslogic.QuotaExtensionManager;
import de.bstly.we.businesslogic.QuotaExtensionMappingManager;
import de.bstly.we.businesslogic.QuotaManager;
import de.bstly.we.businesslogic.QuotaMappingManager;
import de.bstly.we.controller.model.ItemResultModel;
import de.bstly.we.model.Permission;
import de.bstly.we.model.PermissionMapping;
import de.bstly.we.model.Quota;
import de.bstly.we.model.QuotaExtension;
import de.bstly.we.model.QuotaExtensionMapping;
import de.bstly.we.model.QuotaMapping;
import de.bstly.we.security.model.LocalUserDetails;
import de.bstly.we.security.token.LocalAnonymousAuthenticationToken;
import jakarta.servlet.http.HttpSession;
/**
* The Class TokenSessionManager.
@@ -47,8 +47,12 @@ public class TokenSessionManager {
@Autowired
private QuotaMappingManager quotaMappingManager;
@Autowired
private QuotaExtensionMappingManager quotaExtensionMappingManager;
@Autowired
private QuotaManager quotaManager;
@Autowired
private QuotaExtensionManager quotaExtensionManager;
@Autowired
private PretixManager pretixManager;
/**
@@ -154,6 +158,51 @@ public class TokenSessionManager {
}
}
/**
* Gets the quota mappings for token.
*
* @param userId the user id
* @param token the token
* @return the quota mappings for token
*/
public List<QuotaExtensionMapping> getQuotaExtensionMappingsForToken(Long userId, String token) {
List<QuotaExtensionMapping> quotaMappings = Lists.newArrayList();
try {
JsonObject result = pretixManager.getCheckInItemBySecret(token);
if (result != null && result.get("secret").getAsString().equals(token)
&& result.getAsJsonArray("checkins").size() < 1
&& "p".equals(result.get("order__status").getAsString())) {
int item = result.get("item").getAsInt();
quotaMappings.addAll(quotaExtensionMappingManager.getAllByItem(item));
}
} catch (Exception e) {
// ignore
}
return quotaMappings;
}
/**
* Adds the quotas for token.
*
* @param userId the user id
* @param token the token
* @param quotas the quotas
*/
public void addQuotaExtensionsForToken(Long userId, String token, List<QuotaExtension> quotas) {
try {
JsonObject result = pretixManager.getCheckInItemBySecret(token);
if (result != null && result.get("secret").getAsString().equals(token)
&& result.getAsJsonArray("checkins").size() < 1
&& "p".equals(result.get("order__status").getAsString())) {
int item = result.get("item").getAsInt();
quotaExtensionManager.addForItem(userId, item, quotas);
}
} catch (Exception e) {
// ignore
}
}
/**
* Apply tokens.
*
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.validation;
import java.util.ArrayList;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.validation;
import org.springframework.beans.factory.annotation.Autowired;
@@ -0,0 +1,53 @@
package de.bstly.we.controller.validation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import de.bstly.we.businesslogic.QuotaExtensionMappingManager;
import de.bstly.we.model.QuotaExtensionMapping;
/**
* The Class QuotaExtensionMappingValidator.
*/
@Component
public class QuotaExtensionMappingValidator implements Validator {
@Autowired
private QuotaExtensionMappingManager quotaExtensionMappingManager;
/*
* @see org.springframework.validation.Validator#supports(java.lang.Class)
*/
@Override
public boolean supports(Class<?> clazz) {
return clazz.isAssignableFrom(QuotaExtensionMapping.class);
}
/*
*
* @see org.springframework.validation.Validator#validate(java.lang.Object,
* org.springframework.validation.Errors)
*/
@Override
public void validate(Object target, Errors errors) {
QuotaExtensionMapping quotaExtensionMapping = (QuotaExtensionMapping) target;
for (Integer item : quotaExtensionMapping.getItems()) {
if (quotaExtensionMappingManager.exists(item, quotaExtensionMapping.getName())) {
errors.rejectValue("item", "ALREADY_EXISTS");
errors.rejectValue("name", "ALREADY_EXISTS");
}
}
if (quotaExtensionMapping.getValue() <= 0) {
errors.rejectValue("value", "TOO_SHORT");
}
if (quotaExtensionMapping.getLifetime() != null && quotaExtensionMapping.getLifetime() <= 0) {
errors.rejectValue("lifetime", "TOO_SHORT");
}
}
}
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.validation;
import org.springframework.beans.factory.annotation.Autowired;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.validation;
import org.springframework.beans.factory.annotation.Autowired;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.validation;
import org.apache.commons.validator.routines.DomainValidator;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.validation;
import org.springframework.beans.factory.annotation.Autowired;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.validation;
import java.time.Instant;
@@ -1,6 +1,3 @@
/**
*
*/
package de.bstly.we.controller.validation;
import org.springframework.beans.factory.annotation.Autowired;

Some files were not shown because too many files have changed in this diff Show More