no verification necessary directly for direct subdomains of registrar-level-domains if subdomain does not yet exist
This commit is contained in:
parent
888e53397d
commit
17a5aa2ff4
@ -2,31 +2,18 @@ package net.hostsharing.hsadminng.hs.booking.item.validators;
|
|||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
|
||||||
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
|
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
|
||||||
import net.hostsharing.hsadminng.mapper.Array;
|
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.Dns.REGISTRAR_LEVEL_DOMAINS;
|
||||||
import static net.hostsharing.hsadminng.hs.validation.StringProperty.stringProperty;
|
import static net.hostsharing.hsadminng.hs.validation.StringProperty.stringProperty;
|
||||||
|
|
||||||
class HsDomainSetupBookingItemValidator extends HsBookingItemEntityValidator {
|
class HsDomainSetupBookingItemValidator extends HsBookingItemEntityValidator {
|
||||||
|
|
||||||
public static final String FQDN_REGEX = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,12}";
|
public static final String FQDN_REGEX = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,12}";
|
||||||
public static final String[] REGISTRAR_LEVEL_DOMAINS = Array.of(
|
|
||||||
// "[^.]+", // top-level-domains are already rejected by FQDN_REGEX
|
|
||||||
"(co|org|gov|ac|sch)\\.uk",
|
|
||||||
"(com|net|org|edu|gov|asn|id)\\.au",
|
|
||||||
"(co|ne|or|ac|go)\\.jp",
|
|
||||||
"(com|net|org|gov|edu|ac)\\.cn",
|
|
||||||
"(com|net|org|gov|edu|mil|art)\\.br",
|
|
||||||
"(co|net|org|gen|firm|ind)\\.in",
|
|
||||||
"(com|net|org|gob|edu)\\.mx",
|
|
||||||
"(gov|edu)\\.it",
|
|
||||||
"(co|net|org|govt|ac|school|geek|kiwi)\\.nz",
|
|
||||||
"(co|ne|or|go|re|pe)\\.kr"
|
|
||||||
);
|
|
||||||
public static final String DOMAIN_NAME_PROPERTY_NAME = "domainName";
|
public static final String DOMAIN_NAME_PROPERTY_NAME = "domainName";
|
||||||
public static final String VERIFICATION_CODE_PROPERTY_NAME = "verificationCode";
|
public static final String VERIFICATION_CODE_PROPERTY_NAME = "verificationCode";
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.mapper.Array;
|
||||||
import org.apache.commons.collections4.EnumerationUtils;
|
import org.apache.commons.collections4.EnumerationUtils;
|
||||||
|
|
||||||
import javax.naming.InvalidNameException;
|
import javax.naming.InvalidNameException;
|
||||||
@ -14,14 +15,45 @@ import java.util.Hashtable;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static java.util.Arrays.stream;
|
import static java.util.Arrays.stream;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
|
||||||
public class Dns {
|
public class Dns {
|
||||||
|
|
||||||
|
public static final String[] REGISTRAR_LEVEL_DOMAINS = Array.of(
|
||||||
|
"[^.]+", // top-level-domains
|
||||||
|
"(co|org|gov|ac|sch)\\.uk",
|
||||||
|
"(com|net|org|edu|gov|asn|id)\\.au",
|
||||||
|
"(co|ne|or|ac|go)\\.jp",
|
||||||
|
"(com|net|org|gov|edu|ac)\\.cn",
|
||||||
|
"(com|net|org|gov|edu|mil|art)\\.br",
|
||||||
|
"(co|net|org|gen|firm|ind)\\.in",
|
||||||
|
"(com|net|org|gob|edu)\\.mx",
|
||||||
|
"(gov|edu)\\.it",
|
||||||
|
"(co|net|org|govt|ac|school|geek|kiwi)\\.nz",
|
||||||
|
"(co|ne|or|go|re|pe)\\.kr"
|
||||||
|
);
|
||||||
|
public static final Pattern[] REGISTRAR_LEVEL_DOMAIN_PATTERN = stream(REGISTRAR_LEVEL_DOMAINS)
|
||||||
|
.map(Pattern::compile)
|
||||||
|
.toArray(Pattern[]::new);
|
||||||
|
|
||||||
private final static Map<String, Result> fakeResults = new HashMap<>();
|
private final static Map<String, Result> fakeResults = new HashMap<>();
|
||||||
|
|
||||||
|
public static Optional<String> superDomain(final String domainName) {
|
||||||
|
final var parts = domainName.split("\\.", 2);
|
||||||
|
if (parts.length == 2) {
|
||||||
|
return Optional.of(parts[1]);
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isRegistrarLevel(final String domainName) {
|
||||||
|
return stream(REGISTRAR_LEVEL_DOMAIN_PATTERN)
|
||||||
|
.anyMatch(p -> p.matcher(domainName).matches());
|
||||||
|
}
|
||||||
|
|
||||||
public static void fakeResultForDomain(final String domainName, final Result fakeResult) {
|
public static void fakeResultForDomain(final String domainName, final Result fakeResult) {
|
||||||
fakeResults.put(domainName, fakeResult);
|
fakeResults.put(domainName, fakeResult);
|
||||||
}
|
}
|
||||||
@ -40,13 +72,6 @@ public class Dns {
|
|||||||
|
|
||||||
public record Result(Status status, List<String> records, NamingException exception) {
|
public record Result(Status status, List<String> records, NamingException exception) {
|
||||||
|
|
||||||
public static Optional<String> superDomain(final String domainName) {
|
|
||||||
final var parts = domainName.split("\\.", 2);
|
|
||||||
if (parts.length == 2) {
|
|
||||||
return Optional.of(parts[1]);
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Result fromRecords(final NamingEnumeration<?> recordEnumeration) {
|
public static Result fromRecords(final NamingEnumeration<?> recordEnumeration) {
|
||||||
final List<String> records = recordEnumeration == null
|
final List<String> records = recordEnumeration == null
|
||||||
|
@ -5,10 +5,11 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Supplier;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SETUP;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SETUP;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.Dns.Result.superDomain;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.Dns.superDomain;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainHttpSetupHostingAssetValidator.SUBDOMAIN_NAME_REGEX;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainHttpSetupHostingAssetValidator.SUBDOMAIN_NAME_REGEX;
|
||||||
|
|
||||||
class HsDomainSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
class HsDomainSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
||||||
@ -24,54 +25,48 @@ class HsDomainSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
|||||||
NO_EXTRA_PROPERTIES);
|
NO_EXTRA_PROPERTIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public List<String> validateEntity(final HsHostingAsset assetEntity) {
|
|
||||||
// // TODO.impl: for newly created entities, check the permission of setting up a domain
|
|
||||||
// //
|
|
||||||
// // allow if
|
|
||||||
// // - user has Admin/Agent-role for all its sub-domains and the direct parent-Domain which are set up at at Hostsharing
|
|
||||||
// // - domain has DNS zone with TXT record approval
|
|
||||||
// // - parent-domain has DNS zone with TXT record approval
|
|
||||||
// //
|
|
||||||
// // TXT-Record check:
|
|
||||||
// // new InitialDirContext().getAttributes("dns:_netblocks.google.com", new String[] { "TXT"}).get("TXT").getAll();
|
|
||||||
// final var violations = new ArrayList<String>();
|
|
||||||
// if ( assetEntity.getBookingItem() != null ) {
|
|
||||||
// final var bookingItemDomainName = assetEntity .getDirectValue(DOMAIN_NAME_PROPERTY_NAME, String.class);
|
|
||||||
// if ( bookingItemDomainName ) {
|
|
||||||
// violations.add("'" + bookingItem.toShortString() + ".resources." + DOMAIN_NAME_PROPERTY_NAME + "' = '" + domainName + "' is a forbidden Hostsharing domain name");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// violations.addAll(super.validateEntity(assetEntity));
|
|
||||||
// return violations;
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> validateEntity(final HsHostingAsset assetEntity) {
|
public List<String> validateEntity(final HsHostingAsset assetEntity) {
|
||||||
|
|
||||||
final var violations = new ArrayList<String>();
|
final var violations = new ArrayList<String>();
|
||||||
final var domainName = assetEntity.getIdentifier();
|
final var domainName = assetEntity.getIdentifier();
|
||||||
final var dnsResult = new Dns(domainName).fetchRecordsOfType("TXT");
|
final var dnsResult = new Dns(domainName).fetchRecordsOfType("TXT");
|
||||||
|
final Supplier<String> getCode = () -> assetEntity.getBookingItem().getDirectValue("verificationCode", String.class);
|
||||||
switch (dnsResult.status()) {
|
switch (dnsResult.status()) {
|
||||||
case Dns.Status.SUCCESS:
|
case Dns.Status.SUCCESS: {
|
||||||
final var code = assetEntity.getBookingItem().getDirectValue("verificationCode", String.class);
|
final var expectedTxtRecordValue = "Hostsharing-domain-setup-verification-code=" + getCode.get();
|
||||||
final var expectedTxtRecordValue = "Hostsharing-domain-setup-verification-code=" + code;
|
final var verificationFound = findTxtRecord(dnsResult, expectedTxtRecordValue)
|
||||||
final var found = findTxtRecord(dnsResult, expectedTxtRecordValue)
|
|
||||||
.or(() -> superDomain(domainName)
|
.or(() -> superDomain(domainName)
|
||||||
.flatMap(superDomainName -> findTxtRecord(
|
.flatMap(superDomainName -> findTxtRecord(
|
||||||
new Dns(superDomainName).fetchRecordsOfType("TXT"),
|
new Dns(superDomainName).fetchRecordsOfType("TXT"),
|
||||||
expectedTxtRecordValue))
|
expectedTxtRecordValue))
|
||||||
);
|
);
|
||||||
if (found.isEmpty()) {
|
if (verificationFound.isEmpty()) {
|
||||||
violations.add(
|
violations.add(
|
||||||
"[DNS] no TXT record 'Hostsharing-domain-setup-verification=" + code + "' found for domain name '"
|
"[DNS] no TXT record '" + expectedTxtRecordValue +
|
||||||
+ assetEntity.getIdentifier() + "'");
|
"' found for domain name '" + domainName + "'");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Dns.Status.NAME_NOT_FOUND:
|
case Dns.Status.NAME_NOT_FOUND: {
|
||||||
// no DNS verification necessary / FIXME: at least if the superdomain is at registrar level
|
final var superDomain = superDomain(domainName);
|
||||||
|
final var verificationRequired = !superDomain.map(Dns::isRegistrarLevel).orElse(false)
|
||||||
|
&& assetEntity.getBookingItem() != null; // FIXME: or getParentAsset() == nuĺl? or extract method
|
||||||
|
if (verificationRequired) {
|
||||||
|
final var expectedTxtRecordValue = "Hostsharing-domain-setup-verification-code=" + getCode.get();
|
||||||
|
final var verificationFoundInSuperDomain = superDomain.flatMap(superDomainName -> findTxtRecord(
|
||||||
|
new Dns(superDomainName).fetchRecordsOfType("TXT"),
|
||||||
|
expectedTxtRecordValue));
|
||||||
|
if (verificationFoundInSuperDomain.isEmpty()) {
|
||||||
|
violations.add(
|
||||||
|
"[DNS] no TXT record '" + expectedTxtRecordValue +
|
||||||
|
"' found for domain name '" + superDomain.orElseThrow() + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// otherwise no DNS verification to be able to setup DNS for domains to register
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Dns.Status.INVALID_NAME:
|
case Dns.Status.INVALID_NAME:
|
||||||
violations.add("[DNS] invalid domain name '" + assetEntity.getIdentifier() + "'");
|
violations.add("[DNS] invalid domain name '" + assetEntity.getIdentifier() + "'");
|
||||||
|
@ -26,14 +26,14 @@ class HsDomainSetupBookingItemValidatorUnitTest {
|
|||||||
private EntityManager em;
|
private EntityManager em;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void acceptsUnregisteredDomain() {
|
void acceptsRegisterableDomain() {
|
||||||
// given
|
// given
|
||||||
final var domainSetupBookingItemEntity = HsBookingItemRealEntity.builder()
|
final var domainSetupBookingItemEntity = HsBookingItemRealEntity.builder()
|
||||||
.type(DOMAIN_SETUP)
|
.type(DOMAIN_SETUP)
|
||||||
.project(project)
|
.project(project)
|
||||||
.caption("Test-Domain")
|
.caption("Test-Domain")
|
||||||
.resources(Map.ofEntries(
|
.resources(Map.ofEntries(
|
||||||
entry("domainName", "example.org") // TODO.test: amend once we check registration
|
entry("domainName", "example.org")
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@ -44,27 +44,9 @@ class HsDomainSetupBookingItemValidatorUnitTest {
|
|||||||
assertThat(result).isEmpty();
|
assertThat(result).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void rejectsTopLevelDomain() {
|
|
||||||
// given
|
|
||||||
final var domainSetupBookingItemEntity = HsBookingItemRealEntity.builder()
|
|
||||||
.type(DOMAIN_SETUP)
|
|
||||||
.project(project)
|
|
||||||
.caption("Test-Domain")
|
|
||||||
.resources(Map.ofEntries(
|
|
||||||
entry("domainName", "org")
|
|
||||||
))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, domainSetupBookingItemEntity);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(result).containsExactly("'D-12345:Test-Project:Test-Domain.resources.domainName' = 'org' is not a (non-top-level) fully qualified domain name");
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@ValueSource(strings = {
|
@ValueSource(strings = {
|
||||||
|
"de", "com", "net", "org", "actually-any-top-level-domain",
|
||||||
"co.uk", "org.uk", "gov.uk", "ac.uk", "sch.uk",
|
"co.uk", "org.uk", "gov.uk", "ac.uk", "sch.uk",
|
||||||
"com.au", "net.au", "org.au", "edu.au", "gov.au", "asn.au", "id.au",
|
"com.au", "net.au", "org.au", "edu.au", "gov.au", "asn.au", "id.au",
|
||||||
"co.jp", "ne.jp", "or.jp", "ac.jp", "go.jp",
|
"co.jp", "ne.jp", "or.jp", "ac.jp", "go.jp",
|
||||||
@ -76,7 +58,7 @@ class HsDomainSetupBookingItemValidatorUnitTest {
|
|||||||
"co.nz", "net.nz", "org.nz", "govt.nz", "ac.nz", "school.nz", "geek.nz", "kiwi.nz",
|
"co.nz", "net.nz", "org.nz", "govt.nz", "ac.nz", "school.nz", "geek.nz", "kiwi.nz",
|
||||||
"co.kr", "ne.kr", "or.kr", "go.kr", "re.kr", "pe.kr"
|
"co.kr", "ne.kr", "or.kr", "go.kr", "re.kr", "pe.kr"
|
||||||
})
|
})
|
||||||
void reject2ndLevelRegistrarDomain(final String secondLevelRegistrarDomain) {
|
void rejectRegistrarLevelDomain(final String secondLevelRegistrarDomain) {
|
||||||
// given
|
// given
|
||||||
final var domainSetupBookingItemEntity = HsBookingItemRealEntity.builder()
|
final var domainSetupBookingItemEntity = HsBookingItemRealEntity.builder()
|
||||||
.type(DOMAIN_SETUP)
|
.type(DOMAIN_SETUP)
|
||||||
@ -91,7 +73,7 @@ class HsDomainSetupBookingItemValidatorUnitTest {
|
|||||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, domainSetupBookingItemEntity);
|
final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, domainSetupBookingItemEntity);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).containsExactly(
|
assertThat(result).contains(
|
||||||
"'D-12345:Test-Project:Test-Domain.resources.domainName' = '" +
|
"'D-12345:Test-Project:Test-Domain.resources.domainName' = '" +
|
||||||
secondLevelRegistrarDomain +
|
secondLevelRegistrarDomain +
|
||||||
"' is a forbidden registrar-level domain name");
|
"' is a forbidden registrar-level domain name");
|
||||||
@ -129,7 +111,7 @@ class HsDomainSetupBookingItemValidatorUnitTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
||||||
"{type=string, propertyName=domainName, matchesRegEx=[^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,12}], matchesRegExDescription=is not a (non-top-level) fully qualified domain name, notMatchesRegEx=[(co|org|gov|ac|sch)\\.uk, (com|net|org|edu|gov|asn|id)\\.au, (co|ne|or|ac|go)\\.jp, (com|net|org|gov|edu|ac)\\.cn, (com|net|org|gov|edu|mil|art)\\.br, (co|net|org|gen|firm|ind)\\.in, (com|net|org|gob|edu)\\.mx, (gov|edu)\\.it, (co|net|org|govt|ac|school|geek|kiwi)\\.nz, (co|ne|or|go|re|pe)\\.kr], notMatchesRegExDescription=is a forbidden registrar-level domain name, required=true, writeOnce=true}",
|
"{type=string, propertyName=domainName, matchesRegEx=[^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,12}], matchesRegExDescription=is not a (non-top-level) fully qualified domain name, notMatchesRegEx=[[^.]+, (co|org|gov|ac|sch)\\.uk, (com|net|org|edu|gov|asn|id)\\.au, (co|ne|or|ac|go)\\.jp, (com|net|org|gov|edu|ac)\\.cn, (com|net|org|gov|edu|mil|art)\\.br, (co|net|org|gen|firm|ind)\\.in, (com|net|org|gob|edu)\\.mx, (gov|edu)\\.it, (co|net|org|govt|ac|school|geek|kiwi)\\.nz, (co|ne|or|go|re|pe)\\.kr], notMatchesRegExDescription=is a forbidden registrar-level domain name, required=true, writeOnce=true}",
|
||||||
"{type=string, propertyName=verificationCode, readOnly=true, computed=IN_INIT}");
|
"{type=string, propertyName=verificationCode, readOnly=true, computed=IN_INIT}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class DnsUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void isRegistrarLevel() {
|
||||||
|
assertThat(Dns.isRegistrarLevel("de")).isTrue();
|
||||||
|
assertThat(Dns.isRegistrarLevel("example.de")).isFalse();
|
||||||
|
|
||||||
|
assertThat(Dns.isRegistrarLevel("co.uk")).isTrue();
|
||||||
|
assertThat(Dns.isRegistrarLevel("example.co.uk")).isFalse();
|
||||||
|
}
|
||||||
|
}
|
@ -97,8 +97,12 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
@EnumSource(ValidDomainNameIdentifier.class)
|
@EnumSource(ValidDomainNameIdentifier.class)
|
||||||
void acceptsValidIdentifier(final ValidDomainNameIdentifier testCase) {
|
void acceptsValidIdentifier(final ValidDomainNameIdentifier testCase) {
|
||||||
// given
|
// given
|
||||||
Dns.fakeResultForDomain(testCase.domainName, new Dns.Result(Dns.Status.NAME_NOT_FOUND, null, null));
|
|
||||||
final var givenEntity = validEntityBuilder(testCase.domainName).identifier(testCase.domainName).build();
|
final var givenEntity = validEntityBuilder(testCase.domainName).identifier(testCase.domainName).build();
|
||||||
|
final var expectedHash = givenEntity.getBookingItem()
|
||||||
|
.getDirectValue("verificationCode", String.class);
|
||||||
|
Dns.fakeResultForDomain(
|
||||||
|
testCase.domainName,
|
||||||
|
Dns.Result.fromRecords("Hostsharing-domain-setup-verification-code=" + expectedHash));
|
||||||
final var validator = HostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
final var validator = HostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -270,7 +274,7 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
final var result = validator.validateEntity(domainSetupHostingAssetEntity);
|
final var result = validator.validateEntity(domainSetupHostingAssetEntity);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).contains("[DNS] no TXT record 'Hostsharing-domain-setup-verification=" + expectedHash
|
assertThat(result).contains("[DNS] no TXT record 'Hostsharing-domain-setup-verification-code=" + expectedHash
|
||||||
+ "' found for domain name 'example.org'");
|
+ "' found for domain name 'example.org'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,6 +322,29 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
assertThat(result).isEmpty();
|
assertThat(result).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void RejectSetupOfUnregisteredSubdomainWithoutDnsVerificationInSuperDomain() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
final var domainSetupHostingAssetEntity = validEntityBuilder("sub.example.org").build();
|
||||||
|
// ... the new subdomain is not yet registered:
|
||||||
|
Dns.fakeResultForDomain(
|
||||||
|
"sub.example.org",
|
||||||
|
Dns.Result.fromException(new NameNotFoundException("domain not registered")));
|
||||||
|
// ... and a valid verification-code in the super-domain:
|
||||||
|
final var expectedHash = domainSetupHostingAssetEntity.getBookingItem()
|
||||||
|
.getDirectValue("verificationCode", String.class);
|
||||||
|
final var validator = HostingAssetEntityValidatorRegistry.forType(domainSetupHostingAssetEntity.getType());
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = validator.validateEntity(domainSetupHostingAssetEntity);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).containsExactly(
|
||||||
|
"[DNS] no TXT record 'Hostsharing-domain-setup-verification-code=" + expectedHash
|
||||||
|
+ "' found for domain name 'example.org'");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void allowSetupOfExistingSubdomainWithValidDnsVerificationInSuperDomain() {
|
void allowSetupOfExistingSubdomainWithValidDnsVerificationInSuperDomain() {
|
||||||
|
|
||||||
@ -355,7 +382,7 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
final var result = validator.validateEntity(domainSetupHostingAssetEntity);
|
final var result = validator.validateEntity(domainSetupHostingAssetEntity);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).contains("[DNS] no TXT record 'Hostsharing-domain-setup-verification=" + expectedHash
|
assertThat(result).contains("[DNS] no TXT record 'Hostsharing-domain-setup-verification-code=" + expectedHash
|
||||||
+ "' found for domain name 'sub.example.org'");
|
+ "' found for domain name 'sub.example.org'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user