check-domain-setup-permission #97
@ -4,6 +4,7 @@ import org.apache.commons.collections4.EnumerationUtils;
|
|||||||
|
|
||||||
import javax.naming.InvalidNameException;
|
import javax.naming.InvalidNameException;
|
||||||
import javax.naming.NameNotFoundException;
|
import javax.naming.NameNotFoundException;
|
||||||
|
import javax.naming.NamingEnumeration;
|
||||||
import javax.naming.NamingException;
|
import javax.naming.NamingException;
|
||||||
import javax.naming.ServiceUnavailableException;
|
import javax.naming.ServiceUnavailableException;
|
||||||
import javax.naming.directory.Attribute;
|
import javax.naming.directory.Attribute;
|
||||||
@ -23,7 +24,6 @@ public class Dns {
|
|||||||
|
|
||||||
public enum Status {
|
public enum Status {
|
||||||
SUCCESS,
|
SUCCESS,
|
||||||
RECORD_TYPE_NOT_FOUND,
|
|
||||||
NAME_NOT_FOUND,
|
NAME_NOT_FOUND,
|
||||||
INVALID_NAME,
|
INVALID_NAME,
|
||||||
SERVICE_UNAVAILABLE,
|
SERVICE_UNAVAILABLE,
|
||||||
@ -31,6 +31,22 @@ 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 Result fromRecords(final NamingEnumeration<?> enumeration) {
|
||||||
|
final List<String> records = enumeration == null
|
||||||
|
? emptyList()
|
||||||
|
: EnumerationUtils.toList(enumeration).stream().map(Object::toString).toList();
|
||||||
|
return new Result(Status.SUCCESS, records, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result fromException(final NamingException exception) {
|
||||||
|
return switch (exception) {
|
||||||
|
case ServiceUnavailableException exc -> new Result(Status.SERVICE_UNAVAILABLE, null, exc);
|
||||||
|
case NameNotFoundException exc -> new Result(Status.NAME_NOT_FOUND, null, exc);
|
||||||
|
case InvalidNameException exc -> new Result(Status.INVALID_NAME, null, exc);
|
||||||
|
case NamingException exc -> new Result(Status.UNKNOWN_FAILURE, null, exc);
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String domainName;
|
private final String domainName;
|
||||||
@ -51,23 +67,12 @@ public class Dns {
|
|||||||
try {
|
try {
|
||||||
final var env = new Hashtable<>();
|
final var env = new Hashtable<>();
|
||||||
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
|
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
|
||||||
final Attribute r = new InitialDirContext(env)
|
final Attribute records = new InitialDirContext(env)
|
||||||
.getAttributes(domainName, new String[] { recordType })
|
.getAttributes(domainName, new String[] { recordType })
|
||||||
.get(recordType);
|
.get(recordType);
|
||||||
return new Result(
|
return Result.fromRecords(records != null ? records.getAll() : null);
|
||||||
r == null ? Status.RECORD_TYPE_NOT_FOUND : Status.SUCCESS,
|
} catch (final NamingException exception) {
|
||||||
r == null
|
return Result.fromException(exception);
|
||||||
? emptyList()
|
|
||||||
: EnumerationUtils.toList(r.getAll()).stream().map(Object::toString).toList(),
|
|
||||||
null);
|
|
||||||
} catch (final ServiceUnavailableException e) {
|
|
||||||
return new Result(Status.SERVICE_UNAVAILABLE, null, e);
|
|
||||||
} catch (final NameNotFoundException e) {
|
|
||||||
return new Result(Status.NAME_NOT_FOUND, null, e);
|
|
||||||
} catch (InvalidNameException e) {
|
|
||||||
return new Result(Status.INVALID_NAME, null, e);
|
|
||||||
} catch (NamingException e) {
|
|
||||||
return new Result(Status.UNKNOWN_FAILURE, null, e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +54,9 @@ class HsDomainSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
|||||||
if (found.isPresent()) {
|
if (found.isPresent()) {
|
||||||
break;
|
break;
|
||||||
hsh-michaelhoennig marked this conversation as resolved
|
|||||||
}
|
}
|
||||||
case Dns.Status.RECORD_TYPE_NOT_FOUND:
|
|
||||||
violations.add("Domain " + assetEntity.getIdentifier() + " exists, but no record 'TXT Hostsharing-domain-setup-challenge:FIXME' found ");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Dns.Status.NAME_NOT_FOUND:
|
case Dns.Status.NAME_NOT_FOUND:
|
||||||
// no DNS verification necessary
|
// no DNS verification necessary / FIXME: at least if the superdomain is at registrar level
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Dns.Status.INVALID_NAME:
|
case Dns.Status.INVALID_NAME:
|
||||||
|
@ -9,6 +9,10 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||||||
import org.junit.jupiter.params.provider.EnumSource;
|
import org.junit.jupiter.params.provider.EnumSource;
|
||||||
import org.junit.jupiter.params.provider.ValueSource;
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
|
||||||
|
import javax.naming.InvalidNameException;
|
||||||
|
import javax.naming.NameNotFoundException;
|
||||||
|
import javax.naming.NamingException;
|
||||||
|
import javax.naming.ServiceUnavailableException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
||||||
@ -176,6 +180,49 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
assertThat(result).isEmpty();
|
assertThat(result).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum DnsLookupFailureTestCase {
|
||||||
|
SERVICE_UNAVAILABLE(
|
||||||
|
new ServiceUnavailableException("no Internet connection"),
|
||||||
|
"DNS request for example.org failed: javax.naming.ServiceUnavailableException: no Internet connection"),
|
||||||
|
NAME_NOT_FOUND(
|
||||||
|
new NameNotFoundException("domain not registered"),
|
||||||
|
null), // no
|
||||||
|
INVALID_NAME(
|
||||||
|
new InvalidNameException("domain name too long or whatever"),
|
||||||
|
"Invalid domain name example.org"),
|
||||||
|
UNKNOWN_FAILURE(
|
||||||
|
new NamingException("some other problem"),
|
||||||
|
"DNS request for example.org failed: javax.naming.NamingException: some other problem");
|
||||||
|
|
||||||
|
public final NamingException givenException;
|
||||||
|
public final String expectedErrorMessage;
|
||||||
|
|
||||||
|
DnsLookupFailureTestCase(final NamingException givenException, final String expectedErrorMessage) {
|
||||||
|
this.givenException = givenException;
|
||||||
|
this.expectedErrorMessage = expectedErrorMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@EnumSource(DnsLookupFailureTestCase.class)
|
||||||
|
void handlesDnsLookupFailures(final DnsLookupFailureTestCase testCase) {
|
||||||
|
|
||||||
|
// given
|
||||||
|
Dns.fakeNextResult(Dns.Result.fromException(testCase.givenException));
|
||||||
|
final var domainSetupHostingAssetEntity = validEntityBuilder().build();
|
||||||
|
final var validator = HostingAssetEntityValidatorRegistry.forType(domainSetupHostingAssetEntity.getType());
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = validator.validateEntity(domainSetupHostingAssetEntity);
|
||||||
|
|
||||||
|
// then
|
||||||
|
if (testCase.expectedErrorMessage != null) {
|
||||||
|
assertThat(result).containsExactly(testCase.expectedErrorMessage);
|
||||||
|
} else {
|
||||||
|
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
use getParentAsset == null + Test