allowSetupOfNonExistingSubdomainOfRegistrarLevelDomain
This commit is contained in:
parent
bab85c5581
commit
8316a88bce
@ -9,17 +9,23 @@ import javax.naming.NamingException;
|
|||||||
import javax.naming.ServiceUnavailableException;
|
import javax.naming.ServiceUnavailableException;
|
||||||
import javax.naming.directory.Attribute;
|
import javax.naming.directory.Attribute;
|
||||||
import javax.naming.directory.InitialDirContext;
|
import javax.naming.directory.InitialDirContext;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
|
|
||||||
public class Dns {
|
public class Dns {
|
||||||
|
|
||||||
private static Result nextFakeResult = null;
|
private final static Map<String, Result> fakeResults = new HashMap<>();
|
||||||
|
|
||||||
public static void fakeNextResult(final Result fakeResult) {
|
public static void fakeResultForDomain(final String domainName, final Result fakeResult) {
|
||||||
nextFakeResult = fakeResult;
|
fakeResults.put(domainName, fakeResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void resetFakeResults() {
|
||||||
|
fakeResults.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Status {
|
public enum Status {
|
||||||
@ -56,12 +62,8 @@ public class Dns {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Result fetchRecordsOfType(final String recordType) {
|
public Result fetchRecordsOfType(final String recordType) {
|
||||||
if (nextFakeResult != null) {
|
if (fakeResults.containsKey(domainName)) {
|
||||||
try {
|
return fakeResults.get(domainName);
|
||||||
return nextFakeResult;
|
|
||||||
} finally {
|
|
||||||
nextFakeResult = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -60,12 +60,12 @@ class HsDomainSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Dns.Status.INVALID_NAME:
|
case Dns.Status.INVALID_NAME:
|
||||||
violations.add("Invalid domain name " + assetEntity.getIdentifier());
|
violations.add("[DNS] invalid domain name '" + assetEntity.getIdentifier() + "'");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Dns.Status.SERVICE_UNAVAILABLE:
|
case Dns.Status.SERVICE_UNAVAILABLE:
|
||||||
case Dns.Status.UNKNOWN_FAILURE:
|
case Dns.Status.UNKNOWN_FAILURE:
|
||||||
violations.add("DNS request for " + assetEntity.getIdentifier() + " failed: " + result.exception());
|
violations.add("[DNS] lookup failed for domain name '" + assetEntity.getIdentifier() + "': " + result.exception());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
void globalAdmin_canAddTopLevelAsset() {
|
void globalAdmin_canAddTopLevelAsset() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
Dns.fakeNextResult(new Dns.Result(Dns.Status.NAME_NOT_FOUND, null, null));
|
Dns.fakeResultForDomain("example.com", new Dns.Result(Dns.Status.NAME_NOT_FOUND, null, null));
|
||||||
final var givenProject = realProjectRepo.findByCaption("D-1000111 default project").stream()
|
final var givenProject = realProjectRepo.findByCaption("D-1000111 default project").stream()
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
final var bookingItem = givenSomeTemporaryBookingItem(() ->
|
final var bookingItem = givenSomeTemporaryBookingItem(() ->
|
||||||
|
@ -4,6 +4,7 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.EnumSource;
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
@ -39,6 +40,11 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
return validEntityBuilder("example.org");
|
return validEntityBuilder("example.org");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void cleanup() {
|
||||||
|
Dns.resetFakeResults();
|
||||||
|
}
|
||||||
|
|
||||||
enum InvalidDomainNameIdentifier {
|
enum InvalidDomainNameIdentifier {
|
||||||
EMPTY(""),
|
EMPTY(""),
|
||||||
TOO_LONG("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456890123456789.de"),
|
TOO_LONG("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456890123456789.de"),
|
||||||
@ -57,7 +63,6 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
@EnumSource(InvalidDomainNameIdentifier.class)
|
@EnumSource(InvalidDomainNameIdentifier.class)
|
||||||
void rejectsInvalidIdentifier(final InvalidDomainNameIdentifier testCase) {
|
void rejectsInvalidIdentifier(final InvalidDomainNameIdentifier testCase) {
|
||||||
// given
|
// given
|
||||||
Dns.fakeNextResult(new Dns.Result(Dns.Status.NAME_NOT_FOUND, null, null));
|
|
||||||
final var givenEntity = validEntityBuilder().identifier(testCase.domainName).build();
|
final var givenEntity = validEntityBuilder().identifier(testCase.domainName).build();
|
||||||
final var validator = HostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
final var validator = HostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
||||||
|
|
||||||
@ -65,12 +70,11 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
final var result = validator.validateEntity(givenEntity);
|
final var result = validator.validateEntity(givenEntity);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).containsExactly(
|
assertThat(result).contains(
|
||||||
"'identifier' expected to match 'example.org', but is '"+testCase.domainName+"'"
|
"'identifier' expected to match 'example.org', but is '"+testCase.domainName+"'"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum ValidDomainNameIdentifier {
|
enum ValidDomainNameIdentifier {
|
||||||
SIMPLE("example.org"),
|
SIMPLE("example.org"),
|
||||||
MAX_LENGTH("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz01234568901.de"),
|
MAX_LENGTH("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz01234568901.de"),
|
||||||
@ -88,7 +92,7 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
@EnumSource(ValidDomainNameIdentifier.class)
|
@EnumSource(ValidDomainNameIdentifier.class)
|
||||||
void acceptsValidIdentifier(final ValidDomainNameIdentifier testCase) {
|
void acceptsValidIdentifier(final ValidDomainNameIdentifier testCase) {
|
||||||
// given
|
// given
|
||||||
Dns.fakeNextResult(new Dns.Result(Dns.Status.NAME_NOT_FOUND, null, null));
|
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 validator = HostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
final var validator = HostingAssetEntityValidatorRegistry.forType(givenEntity.getType());
|
||||||
|
|
||||||
@ -111,7 +115,6 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void validatesReferencedEntities() {
|
void validatesReferencedEntities() {
|
||||||
// given
|
// given
|
||||||
Dns.fakeNextResult(new Dns.Result(Dns.Status.NAME_NOT_FOUND, null, null));
|
|
||||||
final var domainSetupHostingAssetEntity = validEntityBuilder()
|
final var domainSetupHostingAssetEntity = validEntityBuilder()
|
||||||
.parentAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
|
.parentAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
|
||||||
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_SERVER).build())
|
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_SERVER).build())
|
||||||
@ -169,8 +172,10 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
void expectsEitherParentAssetOrBookingItem() {
|
void expectsEitherParentAssetOrBookingItem() {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
Dns.fakeNextResult(new Dns.Result(Dns.Status.NAME_NOT_FOUND, null, null));
|
|
||||||
final var domainSetupHostingAssetEntity = validEntityBuilder().build();
|
final var domainSetupHostingAssetEntity = validEntityBuilder().build();
|
||||||
|
Dns.fakeResultForDomain(
|
||||||
|
domainSetupHostingAssetEntity.getIdentifier(),
|
||||||
|
new Dns.Result(Dns.Status.NAME_NOT_FOUND, null, null));
|
||||||
final var validator = HostingAssetEntityValidatorRegistry.forType(domainSetupHostingAssetEntity.getType());
|
final var validator = HostingAssetEntityValidatorRegistry.forType(domainSetupHostingAssetEntity.getType());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -183,16 +188,16 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
enum DnsLookupFailureTestCase {
|
enum DnsLookupFailureTestCase {
|
||||||
SERVICE_UNAVAILABLE(
|
SERVICE_UNAVAILABLE(
|
||||||
new ServiceUnavailableException("no Internet connection"),
|
new ServiceUnavailableException("no Internet connection"),
|
||||||
"DNS request for example.org failed: javax.naming.ServiceUnavailableException: no Internet connection"),
|
"[DNS] lookup failed for domain name 'example.org': javax.naming.ServiceUnavailableException: no Internet connection"),
|
||||||
NAME_NOT_FOUND(
|
NAME_NOT_FOUND(
|
||||||
new NameNotFoundException("domain not registered"),
|
new NameNotFoundException("domain name not found"),
|
||||||
null), // no
|
null), // no
|
||||||
INVALID_NAME(
|
INVALID_NAME(
|
||||||
new InvalidNameException("domain name too long or whatever"),
|
new InvalidNameException("domain name too long or whatever"),
|
||||||
"Invalid domain name example.org"),
|
"[DNS] invalid domain name 'example.org'"),
|
||||||
UNKNOWN_FAILURE(
|
UNKNOWN_FAILURE(
|
||||||
new NamingException("some other problem"),
|
new NamingException("some other problem"),
|
||||||
"DNS request for example.org failed: javax.naming.NamingException: some other problem");
|
"[DNS] lookup failed for domain name 'example.org': javax.naming.NamingException: some other problem");
|
||||||
|
|
||||||
public final NamingException givenException;
|
public final NamingException givenException;
|
||||||
public final String expectedErrorMessage;
|
public final String expectedErrorMessage;
|
||||||
@ -208,8 +213,10 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
void handlesDnsLookupFailures(final DnsLookupFailureTestCase testCase) {
|
void handlesDnsLookupFailures(final DnsLookupFailureTestCase testCase) {
|
||||||
|
|
||||||
// given
|
// given
|
||||||
Dns.fakeNextResult(Dns.Result.fromException(testCase.givenException));
|
|
||||||
final var domainSetupHostingAssetEntity = validEntityBuilder().build();
|
final var domainSetupHostingAssetEntity = validEntityBuilder().build();
|
||||||
|
Dns.fakeResultForDomain(
|
||||||
|
domainSetupHostingAssetEntity.getIdentifier(),
|
||||||
|
Dns.Result.fromException(testCase.givenException));
|
||||||
final var validator = HostingAssetEntityValidatorRegistry.forType(domainSetupHostingAssetEntity.getType());
|
final var validator = HostingAssetEntityValidatorRegistry.forType(domainSetupHostingAssetEntity.getType());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -223,6 +230,24 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void allowSetupOfNonExistingSubdomainOfRegistrarLevelDomain() {
|
||||||
|
|
||||||
|
// given
|
||||||
|
final var domainSetupHostingAssetEntity = validEntityBuilder().build();
|
||||||
|
final var domainName = domainSetupHostingAssetEntity.getIdentifier();
|
||||||
|
Dns.fakeResultForDomain(
|
||||||
|
domainName,
|
||||||
|
Dns.Result.fromException(new NameNotFoundException("domain not registered")));
|
||||||
|
final var validator = HostingAssetEntityValidatorRegistry.forType(domainSetupHostingAssetEntity.getType());
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = validator.validateEntity(domainSetupHostingAssetEntity);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
private static HsHostingAssetRealEntity createValidParentDomainSetupAsset(final String parentDomainName) {
|
private static HsHostingAssetRealEntity createValidParentDomainSetupAsset(final String parentDomainName) {
|
||||||
final var bookingItem = HsBookingItemRealEntity.builder()
|
final var bookingItem = HsBookingItemRealEntity.builder()
|
||||||
.type(HsBookingItemType.DOMAIN_SETUP)
|
.type(HsBookingItemType.DOMAIN_SETUP)
|
||||||
|
Loading…
Reference in New Issue
Block a user