Compare commits
2 Commits
8d69f2ed39
...
667b3908fd
Author | SHA1 | Date | |
---|---|---|---|
|
667b3908fd | ||
|
4f49793817 |
@ -2,9 +2,9 @@ package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
|||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
||||||
|
|
||||||
|
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;
|
||||||
@ -33,44 +33,18 @@ class HsDomainSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
|||||||
return violations;
|
return violations;
|
||||||
}
|
}
|
||||||
|
|
||||||
final var domainName = assetEntity.getIdentifier();
|
final var dnsResult = new Dns(assetEntity.getIdentifier()).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 expectedTxtRecordValue = "Hostsharing-domain-setup-verification-code=" + getCode.get();
|
violations.addAll(handleDomainNameFound(assetEntity, dnsResult));
|
||||||
final var verificationFound = findTxtRecord(dnsResult, expectedTxtRecordValue)
|
|
||||||
.or(() -> superDomain(domainName)
|
|
||||||
.flatMap(superDomainName -> findTxtRecord(
|
|
||||||
new Dns(superDomainName).fetchRecordsOfType("TXT"),
|
|
||||||
expectedTxtRecordValue))
|
|
||||||
);
|
|
||||||
if (verificationFound.isEmpty()) {
|
|
||||||
violations.add(
|
|
||||||
"[DNS] no TXT record '" + expectedTxtRecordValue +
|
|
||||||
"' found for domain name '" + domainName + "' (nor in its super-domain)");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case Dns.Status.NAME_NOT_FOUND: {
|
case Dns.Status.NAME_NOT_FOUND:
|
||||||
if (isDnsVerificationRequiredForUnregisteredDomain(assetEntity)) {
|
violations.addAll(handleDomainNameNotFoundError(assetEntity, dnsResult));
|
||||||
final var superDomain = superDomain(domainName);
|
|
||||||
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:
|
||||||
|
// should not happen because we validate the domain name at booking item level
|
||||||
violations.add("[DNS] invalid domain name '" + assetEntity.getIdentifier() + "'");
|
violations.add("[DNS] invalid domain name '" + assetEntity.getIdentifier() + "'");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -82,6 +56,10 @@ class HsDomainSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
|||||||
return violations;
|
return violations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String verificationCode(final HsHostingAsset assetEntity) {
|
||||||
|
return assetEntity.getBookingItem().getDirectValue("verificationCode", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Pattern identifierPattern(final HsHostingAsset assetEntity) {
|
protected Pattern identifierPattern(final HsHostingAsset assetEntity) {
|
||||||
if (assetEntity.getBookingItem() != null) {
|
if (assetEntity.getBookingItem() != null) {
|
||||||
@ -93,6 +71,49 @@ class HsDomainSetupHostingAssetValidator extends HostingAssetEntityValidator {
|
|||||||
return Pattern.compile(SUBDOMAIN_NAME_REGEX + "\\." + parentDomainName.replace(".", "\\."), Pattern.CASE_INSENSITIVE);
|
return Pattern.compile(SUBDOMAIN_NAME_REGEX + "\\." + parentDomainName.replace(".", "\\."), Pattern.CASE_INSENSITIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<String> handleDomainNameFound(final HsHostingAsset assetEntity, final Dns.Result dnsResult) {
|
||||||
|
final var violations = new ArrayList<String>();
|
||||||
|
final var expectedTxtRecordValue = "Hostsharing-domain-setup-verification-code=" + verificationCode(assetEntity);
|
||||||
|
final var verificationFound = findTxtRecord(dnsResult, expectedTxtRecordValue)
|
||||||
|
.or(() -> superDomain(assetEntity.getIdentifier())
|
||||||
|
.flatMap(superDomainName -> findTxtRecord(
|
||||||
|
new Dns(superDomainName).fetchRecordsOfType("TXT"),
|
||||||
|
expectedTxtRecordValue))
|
||||||
|
);
|
||||||
|
if (verificationFound.isEmpty()) {
|
||||||
|
violations.add(
|
||||||
|
"[DNS] no TXT record '" + expectedTxtRecordValue +
|
||||||
|
"' found for domain name '" + assetEntity.getIdentifier() + "' (nor in its super-domain)");
|
||||||
|
}
|
||||||
|
return violations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> handleDomainNameNotFoundError(final HsHostingAsset assetEntity, final Dns.Result dnsResult) {
|
||||||
|
final var violations = new ArrayList<String>();
|
||||||
|
if (isDnsVerificationRequiredForUnregisteredDomain(assetEntity)) {
|
||||||
|
final var superDomain = superDomain(assetEntity.getIdentifier());
|
||||||
|
final var expectedTxtRecordValue = "Hostsharing-domain-setup-verification-code=" + verificationCode(assetEntity);
|
||||||
|
final var verificationFoundInSuperDomain = superDomain.map(superDomainName ->
|
||||||
|
{
|
||||||
|
final Dns.Result superDomainDnsResult = new Dns(superDomainName).fetchRecordsOfType("TXT");
|
||||||
|
if (superDomainDnsResult.status() != Dns.Status.SUCCESS) {
|
||||||
|
violations.add("[DNS] lookup failed for domain name '" + superDomainName + "': " + dnsResult.exception());
|
||||||
|
}
|
||||||
|
return superDomainDnsResult;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.flatMap(records -> findTxtRecord(records, expectedTxtRecordValue));
|
||||||
|
if (verificationFoundInSuperDomain.isEmpty()) {
|
||||||
|
violations.add(
|
||||||
|
"[DNS] no TXT record '" + expectedTxtRecordValue +
|
||||||
|
"' found for domain name '" + superDomain.orElseThrow() + "'");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// otherwise no DNS verification to be able to setup DNS for domains to register
|
||||||
|
}
|
||||||
|
return violations;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isDnsVerificationRequiredForUnregisteredDomain(final HsHostingAsset assetEntity) {
|
private static boolean isDnsVerificationRequiredForUnregisteredDomain(final HsHostingAsset assetEntity) {
|
||||||
return !Dns.isRegistrableDomain(assetEntity.getIdentifier())
|
return !Dns.isRegistrableDomain(assetEntity.getIdentifier())
|
||||||
&& assetEntity.getParentAsset() == null;
|
&& assetEntity.getParentAsset() == null;
|
||||||
|
@ -358,6 +358,12 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
.isRejectedWithCauseMissingVerificationIn("example.org");
|
.isRejectedWithCauseMissingVerificationIn("example.org");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectSetupOfUnregisteredSubdomainOfUnregisteredSuperDomain() {
|
||||||
|
domainSetupFor("sub.sub.example.org").notRegistered()
|
||||||
|
.isRejectedWithCauseDomainNameNotFound("sub.example.org");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void acceptSetupOfUnregisteredSubdomainWithParentAssetEvenWithoutDnsVerificationInSuperDomain() {
|
void acceptSetupOfUnregisteredSubdomainWithParentAssetEvenWithoutDnsVerificationInSuperDomain() {
|
||||||
domainSetupWithParentAssetFor("sub.example.org").notRegistered()
|
domainSetupWithParentAssetFor("sub.example.org").notRegistered()
|
||||||
@ -488,6 +494,12 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void isRejectedWithCauseDomainNameNotFound(final String domainName) {
|
||||||
|
assertThat(validate()).contains(
|
||||||
|
"[DNS] lookup failed for domain name '" + domainName + "': javax.naming.NameNotFoundException: domain not registered"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void isAccepted() {
|
void isAccepted() {
|
||||||
assertThat(validate()).isEmpty();
|
assertThat(validate()).isEmpty();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user