add-domain-email-setup-validation #74
@ -25,6 +25,7 @@ public class HostingAssetEntityValidatorRegistry {
|
|||||||
register(DOMAIN_HTTP_SETUP, new HsDomainHttpSetupHostingAssetValidator());
|
register(DOMAIN_HTTP_SETUP, new HsDomainHttpSetupHostingAssetValidator());
|
||||||
register(DOMAIN_EMAIL_SUBMISSION_SETUP, new HsDomainEMailSubmissionSetupHostingAssetValidator());
|
register(DOMAIN_EMAIL_SUBMISSION_SETUP, new HsDomainEMailSubmissionSetupHostingAssetValidator());
|
||||||
hsh-michaelhoennig marked this conversation as resolved
Outdated
|
|||||||
register(DOMAIN_EMAIL_MAILBOX_SETUP, new HsDomainEMailMailboxSetupHostingAssetValidator());
|
register(DOMAIN_EMAIL_MAILBOX_SETUP, new HsDomainEMailMailboxSetupHostingAssetValidator());
|
||||||
|
register(EMAIL_ADDRESS, new HsEMailAddressHostingAssetValidator());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void register(final Enum<HsHostingAssetType> type, final HsEntityValidator<HsHostingAssetEntity> validator) {
|
private static void register(final Enum<HsHostingAssetType> type, final HsEntityValidator<HsHostingAssetEntity> validator) {
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static java.util.Optional.ofNullable;
|
||||||
|
import static net.hostsharing.hsadminng.hs.validation.ArrayProperty.arrayOf;
|
||||||
|
import static net.hostsharing.hsadminng.hs.validation.StringProperty.stringProperty;
|
||||||
|
|
||||||
|
class HsEMailAddressHostingAssetValidator extends HostingAssetEntityValidator {
|
||||||
|
|
||||||
|
private static final String UNIX_USER_REGEX = "^[a-z][a-z0-9]{2}[0-9]{2}(-[a-z0-9]+)?$"; // also accepts legacy pac-names
|
||||||
|
private static final String EMAIL_ADDRESS_LOCAL_PART_REGEX = "[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+"; // RFC 5322
|
||||||
|
private static final String EMAIL_ADDRESS_DOMAIN_PART_REGEX = "[a-zA-Z0-9.-]+";
|
||||||
|
private static final String EMAIL_ADDRESS_FULL_REGEX = "^" + EMAIL_ADDRESS_LOCAL_PART_REGEX + "@" + EMAIL_ADDRESS_DOMAIN_PART_REGEX + "$";
|
||||||
|
public static final int EMAIL_ADDRESS_MAX_LENGTH = 320; // according to RFC 5321 and RFC 5322
|
||||||
|
|
||||||
|
HsEMailAddressHostingAssetValidator() {
|
||||||
|
super( HsHostingAssetType.EMAIL_ADDRESS,
|
||||||
|
AlarmContact.isOptional(),
|
||||||
|
|
||||||
|
stringProperty("local-part").matchesRegEx("^" + EMAIL_ADDRESS_LOCAL_PART_REGEX + "$").required(),
|
||||||
|
stringProperty("sub-domain").matchesRegEx("^" + EMAIL_ADDRESS_LOCAL_PART_REGEX + "$").optional(),
|
||||||
|
arrayOf(
|
||||||
|
stringProperty("target").maxLength(EMAIL_ADDRESS_MAX_LENGTH).matchesRegEx(UNIX_USER_REGEX, EMAIL_ADDRESS_FULL_REGEX)
|
||||||
|
).required().minLength(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preprocessEntity(final HsHostingAssetEntity entity) {
|
||||||
|
super.preprocessEntity(entity);
|
||||||
|
super.preprocessEntity(entity);
|
||||||
|
if (entity.getIdentifier() == null) {
|
||||||
|
entity.setIdentifier(combineIdentifier(entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||||
|
return Pattern.compile("^"+ Pattern.quote(combineIdentifier(assetEntity)) + "$");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String combineIdentifier(final HsHostingAssetEntity emailAddressAssetEntity) {
|
||||||
|
return emailAddressAssetEntity.getDirectValue("local-part", String.class) +
|
||||||
|
ofNullable(emailAddressAssetEntity.getDirectValue("sub-domain", String.class)).map(s -> "." + s).orElse("") +
|
||||||
|
"@" +
|
||||||
|
emailAddressAssetEntity.getParentAsset().getIdentifier();
|
||||||
|
}
|
||||||
|
}
|
@ -335,6 +335,34 @@ public class HsHostingAssetControllerRestTest {
|
|||||||
"config": {}
|
"config": {}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
"""),
|
||||||
|
EMAIL_ADDRESS(
|
||||||
|
List.of(
|
||||||
|
HsHostingAssetEntity.builder()
|
||||||
|
.type(HsHostingAssetType.EMAIL_ADDRESS)
|
||||||
|
.parentAsset(HsHostingAssetEntity.builder()
|
||||||
|
.type(HsHostingAssetType.DOMAIN_EMAIL_MAILBOX_SETUP)
|
||||||
|
.identifier("example.org|MBOX")
|
||||||
|
.caption("some fake Domain-MBOX-Setup")
|
||||||
|
.build())
|
||||||
|
.identifier("office@example.org")
|
||||||
|
.caption("some fake EMail-Address")
|
||||||
|
.config(Map.ofEntries(
|
||||||
|
entry("target", Array.of("xyz00", "xyz00-abc", "office@example.com"))
|
||||||
|
))
|
||||||
|
.build()),
|
||||||
|
"""
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "EMAIL_ADDRESS",
|
||||||
|
"identifier": "office@example.org",
|
||||||
|
"caption": "some fake EMail-Address",
|
||||||
|
"alarmContact": null,
|
||||||
|
"config": {
|
||||||
|
"target": ["xyz00","xyz00-abc","office@example.com"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
""");
|
""");
|
||||||
|
|
||||||
final HsHostingAssetType assetType;
|
final HsHostingAssetType assetType;
|
||||||
|
@ -39,7 +39,9 @@ class HsHostingAssetPropsControllerAcceptanceTest {
|
|||||||
"DOMAIN_SETUP",
|
"DOMAIN_SETUP",
|
||||||
"DOMAIN_DNS_SETUP",
|
"DOMAIN_DNS_SETUP",
|
||||||
"DOMAIN_HTTP_SETUP",
|
"DOMAIN_HTTP_SETUP",
|
||||||
"DOMAIN_EMAIL_SUBMISSION_SETUP"
|
"DOMAIN_EMAIL_SUBMISSION_SETUP",
|
||||||
|
"DOMAIN_EMAIL_MAILBOX_SETUP",
|
||||||
|
"EMAIL_ADDRESS"
|
||||||
]
|
]
|
||||||
"""));
|
"""));
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
@ -37,7 +37,9 @@ class HostingAssetEntityValidatorRegistryUnitTest {
|
|||||||
HsHostingAssetType.DOMAIN_SETUP,
|
HsHostingAssetType.DOMAIN_SETUP,
|
||||||
HsHostingAssetType.DOMAIN_DNS_SETUP,
|
HsHostingAssetType.DOMAIN_DNS_SETUP,
|
||||||
HsHostingAssetType.DOMAIN_HTTP_SETUP,
|
HsHostingAssetType.DOMAIN_HTTP_SETUP,
|
||||||
HsHostingAssetType.DOMAIN_EMAIL_SUBMISSION_SETUP
|
HsHostingAssetType.DOMAIN_EMAIL_SUBMISSION_SETUP,
|
||||||
|
HsHostingAssetType.DOMAIN_EMAIL_MAILBOX_SETUP,
|
||||||
|
HsHostingAssetType.EMAIL_ADDRESS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,114 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||||
|
import net.hostsharing.hsadminng.mapper.Array;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static java.util.Map.entry;
|
||||||
|
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_SERVER_BOOKING_ITEM;
|
||||||
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_EMAIL_MAILBOX_SETUP;
|
||||||
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ADDRESS;
|
||||||
|
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_SERVER_HOSTING_ASSET;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class HsEMailAddressHostingAssetValidatorUnitTest {
|
||||||
|
|
||||||
|
final static HsHostingAssetEntity domainEmailMailboxSetup = HsHostingAssetEntity.builder()
|
||||||
|
.type(DOMAIN_EMAIL_MAILBOX_SETUP)
|
||||||
|
.identifier("example.org")
|
||||||
|
.build();
|
||||||
|
static HsHostingAssetEntity.HsHostingAssetEntityBuilder validEntityBuilder() {
|
||||||
|
return HsHostingAssetEntity.builder()
|
||||||
|
.type(EMAIL_ADDRESS)
|
||||||
|
.parentAsset(domainEmailMailboxSetup)
|
||||||
|
.identifier("test@example.org")
|
||||||
|
.config(Map.ofEntries(
|
||||||
|
entry("local-part", "test"),
|
||||||
|
entry("target", Array.of("xyz00", "xyz00-abc", "office@example.com"))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void containsAllValidations() {
|
||||||
|
// when
|
||||||
|
final var validator = HostingAssetEntityValidatorRegistry.forType(EMAIL_ADDRESS);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
||||||
|
"{type=string, propertyName=local-part, matchesRegEx=[^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+$], required=true}",
|
||||||
|
"{type=string, propertyName=sub-domain, matchesRegEx=[^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+$]}",
|
||||||
|
"{type=string[], propertyName=target, elementsOf={type=string, propertyName=target, matchesRegEx=[^[a-z][a-z0-9]{2}[0-9]{2}(-[a-z0-9]+)?$, ^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$], maxLength=320}, required=true, minLength=1}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void acceptsValidEntity() {
|
||||||
|
// given
|
||||||
|
final var emailAddressHostingAssetEntity = validEntityBuilder().build();
|
||||||
|
final var validator = HostingAssetEntityValidatorRegistry.forType(emailAddressHostingAssetEntity.getType());
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = validator.validateEntity(emailAddressHostingAssetEntity);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsInvalidProperties() {
|
||||||
|
// given
|
||||||
|
final var emailAddressHostingAssetEntity = validEntityBuilder()
|
||||||
|
.config(Map.ofEntries(
|
||||||
|
entry("local-part", "no@allowed"),
|
||||||
|
entry("sub-domain", "no@allowedeither"),
|
||||||
|
entry("target", Array.of("xyz00", "xyz00-abc", "garbage", "office@example.com"))))
|
||||||
|
.build();
|
||||||
|
final var validator = HostingAssetEntityValidatorRegistry.forType(emailAddressHostingAssetEntity.getType());
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = validator.validateEntity(emailAddressHostingAssetEntity);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).containsExactlyInAnyOrder(
|
||||||
|
"'EMAIL_ADDRESS:test@example.org.config.local-part' is expected to match any of [^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+$] but 'no@allowed' does not match",
|
||||||
|
"'EMAIL_ADDRESS:test@example.org.config.sub-domain' is expected to match any of [^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+$] but 'no@allowedeither' does not match",
|
||||||
|
"'EMAIL_ADDRESS:test@example.org.config.target' is expected to match any of [^[a-z][a-z0-9]{2}[0-9]{2}(-[a-z0-9]+)?$, ^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$] but 'garbage' does not match any");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsInvalidIdentifier() {
|
||||||
|
// given
|
||||||
|
final var emailAddressHostingAssetEntity = validEntityBuilder()
|
||||||
|
.identifier("abc00-office")
|
||||||
|
.build();
|
||||||
|
final var validator = HostingAssetEntityValidatorRegistry.forType(emailAddressHostingAssetEntity.getType());
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = validator.validateEntity(emailAddressHostingAssetEntity);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).containsExactlyInAnyOrder(
|
||||||
|
"'identifier' expected to match '^\\Qtest@example.org\\E$', but is 'abc00-office'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void validatesInvalidReferences() {
|
||||||
|
// given
|
||||||
|
final var emailAddressHostingAssetEntity = validEntityBuilder()
|
||||||
|
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
|
||||||
|
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
|
||||||
|
.assignedToAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
|
||||||
|
.build();
|
||||||
|
final var validator = HostingAssetEntityValidatorRegistry.forType(emailAddressHostingAssetEntity.getType());
|
||||||
|
|
||||||
|
// when
|
||||||
|
final var result = validator.validateEntity(emailAddressHostingAssetEntity);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(result).containsExactlyInAnyOrder(
|
||||||
|
"'EMAIL_ADDRESS:test@example.org.bookingItem' must be null but is of type MANAGED_SERVER",
|
||||||
|
"'EMAIL_ADDRESS:test@example.org.parentAsset' must be of type DOMAIN_EMAIL_MAILBOX_SETUP but is of type MANAGED_SERVER",
|
||||||
|
"'EMAIL_ADDRESS:test@example.org.assignedToAsset' must be null but is of type MANAGED_SERVER");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user
auch kürzere Namen