upgrade spring boot and dependencies, migrate spring boot, add dyndns draft
This commit is contained in:
Executable
+35
@@ -0,0 +1,35 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>de.bstly.we</groupId>
|
||||
<artifactId>webstly-main</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
|
||||
<name>dyndns</name>
|
||||
<artifactId>webstly-dyndns</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>de.bstly.we</groupId>
|
||||
<artifactId>webstly-core</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dnsjava</groupId>
|
||||
<artifactId>dnsjava</artifactId>
|
||||
<version>3.5.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Query DSL -->
|
||||
<dependency>
|
||||
<groupId>com.querydsl</groupId>
|
||||
<artifactId>querydsl-apt</artifactId>
|
||||
<version>${querydsl.version}</version>
|
||||
<classifier>jakarta</classifier>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.dyndns.businesslogic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import de.bstly.we.businesslogic.QuotaManager;
|
||||
import de.bstly.we.businesslogic.UserDataProvider;
|
||||
import de.bstly.we.dyndns.model.DyndnsToken;
|
||||
import de.bstly.we.dyndns.repository.DyndnsTokenRepository;
|
||||
import de.bstly.we.model.Quota;
|
||||
import de.bstly.we.model.UserData;
|
||||
|
||||
/**
|
||||
* The Class DyndnsTokenManager.
|
||||
*/
|
||||
@Component
|
||||
public class DyndnsTokenManager implements UserDataProvider {
|
||||
|
||||
public static final int TOKEN_LENGTH = 32;
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@Autowired
|
||||
private QuotaManager quotaManager;
|
||||
@Autowired
|
||||
private DyndnsTokenRepository dyndnsTokenRepository;
|
||||
|
||||
/**
|
||||
* Gets the.
|
||||
*
|
||||
* @param code the code
|
||||
* @return the shortened url
|
||||
*/
|
||||
public DyndnsToken get(Long owner) {
|
||||
return dyndnsTokenRepository.findById(owner).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the.
|
||||
*
|
||||
* @param owner the owner
|
||||
* @param quota the quota
|
||||
* @return the shortened url
|
||||
*/
|
||||
public DyndnsToken create(Long owner, boolean quota) {
|
||||
DyndnsToken dyndnsToken = new DyndnsToken();
|
||||
String token = RandomStringUtils.random(TOKEN_LENGTH, true, true);
|
||||
dyndnsToken.setOwner(owner);
|
||||
dyndnsToken.setToken(token);
|
||||
dyndnsToken.setTokenHash(passwordEncoder.encode(dyndnsToken.getToken()));
|
||||
|
||||
dyndnsToken = dyndnsTokenRepository.save(dyndnsToken);
|
||||
|
||||
if (quota) {
|
||||
Quota dyndnsTokensQuota = quotaManager.get(dyndnsToken.getOwner(), DyndnsTokenQuotas.DYNDNS);
|
||||
if (dyndnsTokensQuota != null) {
|
||||
dyndnsTokensQuota.setValue(dyndnsTokensQuota.getValue() - 1);
|
||||
quotaManager.update(dyndnsTokensQuota);
|
||||
}
|
||||
}
|
||||
|
||||
dyndnsToken.setToken(token);
|
||||
return dyndnsToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete.
|
||||
*
|
||||
* @param dyndnsToken the shortened url
|
||||
* @param quota the quota
|
||||
*/
|
||||
public void delete(DyndnsToken dyndnsToken, boolean quota) {
|
||||
if (quota) {
|
||||
Quota dyndnsTokensQuota = quotaManager.get(dyndnsToken.getOwner(), DyndnsTokenQuotas.DYNDNS);
|
||||
if (dyndnsTokensQuota == null) {
|
||||
dyndnsTokensQuota = quotaManager.create(dyndnsToken.getOwner(), DyndnsTokenQuotas.DYNDNS, 0,
|
||||
"#", true);
|
||||
}
|
||||
|
||||
dyndnsTokensQuota.setValue(dyndnsTokensQuota.getValue() + 1);
|
||||
quotaManager.update(dyndnsTokensQuota);
|
||||
}
|
||||
|
||||
dyndnsTokenRepository.delete(dyndnsToken);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see de.bstly.we.businesslogic.UserDataProvider#getId()
|
||||
*/
|
||||
@Override
|
||||
public String getId() {
|
||||
return "dyndns-tokens";
|
||||
}
|
||||
|
||||
/*
|
||||
* @see de.bstly.we.businesslogic.UserDataProvider#getUserData(java.lang.Long)
|
||||
*/
|
||||
@Override
|
||||
public List<UserData> getUserData(Long userId) {
|
||||
List<UserData> result = Lists.newArrayList();
|
||||
DyndnsToken dyndnsToken = get(userId);
|
||||
if (dyndnsToken != null) {
|
||||
result.add(dyndnsToken);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see de.bstly.we.businesslogic.UserDataProvider#purgeUserData(java.lang.Long)
|
||||
*/
|
||||
@Override
|
||||
public void purgeUserData(Long userId) {
|
||||
DyndnsToken dyndnsToken = get(userId);
|
||||
if (dyndnsToken != null) {
|
||||
dyndnsTokenRepository.delete(dyndnsToken);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.dyndns.businesslogic;
|
||||
|
||||
/**
|
||||
* The Interface DyndnsTokenPermissions.
|
||||
*/
|
||||
public interface DyndnsTokenPermissions {
|
||||
public static final String DYNDNS = "dyndns";
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.dyndns.businesslogic;
|
||||
|
||||
/**
|
||||
* The Interface DyndnsTokenQuotas.
|
||||
*/
|
||||
public interface DyndnsTokenQuotas {
|
||||
|
||||
public static final String DYNDNS = "dyndns";
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.dyndns.controller;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.xbill.DNS.Name;
|
||||
import org.xbill.DNS.Resolver;
|
||||
import org.xbill.DNS.SimpleResolver;
|
||||
import org.xbill.DNS.TSIG;
|
||||
import org.xbill.DNS.Type;
|
||||
import org.xbill.DNS.Update;
|
||||
|
||||
import de.bstly.we.businesslogic.PermissionManager;
|
||||
import de.bstly.we.businesslogic.SystemPropertyManager;
|
||||
import de.bstly.we.businesslogic.UserAliasManager;
|
||||
import de.bstly.we.controller.BaseController;
|
||||
import de.bstly.we.controller.support.EntityResponseStatusException;
|
||||
import de.bstly.we.dyndns.businesslogic.DyndnsTokenManager;
|
||||
import de.bstly.we.dyndns.businesslogic.DyndnsTokenPermissions;
|
||||
import de.bstly.we.dyndns.model.DyndnsToken;
|
||||
import de.bstly.we.model.User;
|
||||
|
||||
/**
|
||||
* The Class DyndnsController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/dyndns")
|
||||
public class DyndnsController extends BaseController {
|
||||
|
||||
public static final String SYSTEM_PROPERTY_DYNDNS_HOSTNAME = "dyndns.hostname";
|
||||
public static final String SYSTEM_PROPERTY_DYNDNS_KEY = "dyndns.key";
|
||||
|
||||
@Autowired
|
||||
private UserAliasManager userAliasManager;
|
||||
@Autowired
|
||||
private DyndnsTokenManager dyndnsTokenManager;
|
||||
@Autowired
|
||||
private PermissionManager permissionManager;
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@Autowired
|
||||
private SystemPropertyManager systemPropertyManager;
|
||||
|
||||
@GetMapping
|
||||
public void updateDns(@RequestParam("username") String name, @RequestParam("token") String token,
|
||||
@RequestParam("ip") Optional<String> ip, @RequestParam("ipv6") Optional<String> ipv6) {
|
||||
User user = userAliasManager.getUser(name);
|
||||
|
||||
if (user == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
if (!permissionManager.hasPermission(user.getId(), DyndnsTokenPermissions.DYNDNS)
|
||||
|| !permissionManager.isFullUser(user.getId())) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
DyndnsToken dyndnsToken = dyndnsTokenManager.get(user.getId());
|
||||
if (dyndnsToken == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
if (!passwordEncoder.matches(token, dyndnsToken.getTokenHash())) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
if (ip.isEmpty() && ipv6.isEmpty()) {
|
||||
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
try {
|
||||
Name zone = Name.fromString(name + ".we.bstly.de.");
|
||||
Name host = Name.fromString("host", zone);
|
||||
Update update = new Update(zone);
|
||||
if (ip.isPresent()) {
|
||||
update.replace(host, Type.A, 3600, ip.get());
|
||||
}
|
||||
if (ipv6.isPresent()) {
|
||||
update.replace(host, Type.AAAA, 3600, ipv6.get());
|
||||
}
|
||||
|
||||
String hostname = systemPropertyManager.get(SYSTEM_PROPERTY_DYNDNS_HOSTNAME, "127.0.0.1");
|
||||
String key = systemPropertyManager.get(SYSTEM_PROPERTY_DYNDNS_KEY, "");
|
||||
|
||||
Resolver res = new SimpleResolver(hostname);
|
||||
res.setTSIGKey(new TSIG(TSIG.HMAC_SHA512, host, key));
|
||||
res.setTCP(true);
|
||||
|
||||
res.send(update);
|
||||
} catch (Exception e) {
|
||||
throw new EntityResponseStatusException(HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.dyndns.controller;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import de.bstly.we.businesslogic.PermissionManager;
|
||||
import de.bstly.we.businesslogic.QuotaManager;
|
||||
import de.bstly.we.controller.BaseController;
|
||||
import de.bstly.we.controller.support.EntityResponseStatusException;
|
||||
import de.bstly.we.dyndns.businesslogic.DyndnsTokenManager;
|
||||
import de.bstly.we.dyndns.businesslogic.DyndnsTokenPermissions;
|
||||
import de.bstly.we.dyndns.businesslogic.DyndnsTokenQuotas;
|
||||
import de.bstly.we.dyndns.model.DyndnsToken;
|
||||
import de.bstly.we.model.Quota;
|
||||
|
||||
/**
|
||||
* The Class DyndnsTokenController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/dyndns/token")
|
||||
public class DyndnsTokenController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private DyndnsTokenManager dyndnsTokenManager;
|
||||
@Autowired
|
||||
private PermissionManager permissionManager;
|
||||
@Autowired
|
||||
private QuotaManager quotaManager;
|
||||
|
||||
/**
|
||||
* Gets the shortened url.
|
||||
* @return the shortened url
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping()
|
||||
public DyndnsToken getDyndnsToken() {
|
||||
DyndnsToken dyndnsToken = dyndnsTokenManager.get(getCurrentUserId());
|
||||
if (dyndnsToken == null) {
|
||||
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(dyndnsToken.getTokenHash())) {
|
||||
dyndnsToken.setTokenHash(null);
|
||||
}
|
||||
|
||||
return dyndnsToken;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the shortened url.
|
||||
* @return the shortened url
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PostMapping
|
||||
public DyndnsToken createDyndnsToken() {
|
||||
if (!permissionManager.hasPermission(getCurrentUserId(), DyndnsTokenPermissions.DYNDNS)
|
||||
|| !permissionManager.isFullUser(getCurrentUserId())) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
DyndnsToken dyndnsToken = dyndnsTokenManager.get(getCurrentUserId());
|
||||
if (dyndnsToken != null) {
|
||||
dyndnsTokenManager.delete(dyndnsToken, true);
|
||||
}
|
||||
|
||||
Quota shortenedUrlsQuota = quotaManager.get(getCurrentUserId(), DyndnsTokenQuotas.DYNDNS);
|
||||
if (shortenedUrlsQuota == null || shortenedUrlsQuota.getValue() < 1) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
return dyndnsTokenManager.create(getCurrentUserId(), true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Delete shortened url.
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@DeleteMapping
|
||||
public void deleteDyndnsToken() {
|
||||
if (!permissionManager.hasPermission(getCurrentUserId(), DyndnsTokenPermissions.DYNDNS)
|
||||
|| !permissionManager.isFullUser(getCurrentUserId())) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
DyndnsToken dyndnsToken = dyndnsTokenManager.get(getCurrentUserId());
|
||||
if (dyndnsToken != null) {
|
||||
dyndnsTokenManager.delete(dyndnsToken, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.dyndns.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import de.bstly.we.controller.BaseController;
|
||||
|
||||
/**
|
||||
* The Class DyndnsTokenManagementController.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/dyndns/token/manage")
|
||||
public class DyndnsTokenManagementController extends BaseController {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.dyndns.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import de.bstly.we.businesslogic.support.AbstractModelEventListener;
|
||||
import de.bstly.we.model.UserData;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Transient;
|
||||
|
||||
/**
|
||||
* The Class DyndnsToken.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "dyndns_tokens")
|
||||
@EntityListeners(AbstractModelEventListener.class)
|
||||
public class DyndnsToken implements UserData {
|
||||
|
||||
@Id
|
||||
@Column(name = "owner")
|
||||
private Long owner;
|
||||
@JsonIgnore
|
||||
@Column(name = "token", nullable = true)
|
||||
private String tokenHash;
|
||||
@Transient
|
||||
private String token;
|
||||
|
||||
/**
|
||||
* Gets the owner.
|
||||
*
|
||||
* @return the owner
|
||||
*/
|
||||
public Long getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the owner.
|
||||
*
|
||||
* @param owner the new owner
|
||||
*/
|
||||
public void setOwner(Long owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token hash.
|
||||
*
|
||||
* @return the token hash
|
||||
*/
|
||||
public String getTokenHash() {
|
||||
return tokenHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the token hash.
|
||||
*
|
||||
* @param tokenHash the new token hash
|
||||
*/
|
||||
public void setTokenHash(String tokenHash) {
|
||||
this.tokenHash = tokenHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token.
|
||||
*
|
||||
* @return the token
|
||||
*/
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the token.
|
||||
*
|
||||
* @param token the new token
|
||||
*/
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.dyndns.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import de.bstly.we.dyndns.model.DyndnsToken;
|
||||
|
||||
/**
|
||||
* The Interface DyndnsTokenRepository.
|
||||
*/
|
||||
@Repository
|
||||
public interface DyndnsTokenRepository
|
||||
extends JpaRepository<DyndnsToken, Long>, QuerydslPredicateExecutor<DyndnsToken> {
|
||||
}
|
||||
Reference in New Issue
Block a user