From fcbbd13a7e363ebf620f80cc9793fb2a00ec1b56 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Tue, 2 Jul 2024 16:09:51 +0200 Subject: [PATCH] implements EMailAlias-Property with ArrayProperty+multi-RegEx --- .../hs/validation/ArrayProperty.java | 21 +++++++++++-------- .../hs/validation/StringProperty.java | 2 +- .../hs/validation/ValidatableProperty.java | 13 +++++++++--- ...ailAliasHostingAssetValidatorUnitTest.java | 13 +++++++----- ...gAssetEntityValidatorRegistryUnitTest.java | 3 ++- ...UnixUserHostingAssetValidatorUnitTest.java | 4 ++-- 6 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/ArrayProperty.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/ArrayProperty.java index 6d01b4ba..31503968 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/ArrayProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/ArrayProperty.java @@ -12,20 +12,22 @@ import static net.hostsharing.hsadminng.mapper.Array.insertAfterEntries; public class ArrayProperty

, E> extends ValidatableProperty, E[]> { private static final String[] KEY_ORDER = - insertAfterEntries(ValidatableProperty.KEY_ORDER, "required", "minLength" ,"maxLength"); - private final ValidatableProperty elementProperty; + insertAfterEntries( + insertAfterEntries(ValidatableProperty.KEY_ORDER, "required", "minLength" ,"maxLength"), + "propertyName", "elementProperty"); + private final ValidatableProperty elementsOf; private Integer minLength; private Integer maxLength; - private ArrayProperty(final ValidatableProperty elementProperty) { + private ArrayProperty(final ValidatableProperty elementsOf) { //noinspection unchecked - super((Class) elementProperty.type.arrayType(), elementProperty.propertyName, KEY_ORDER); - this.elementProperty = elementProperty; + super((Class) elementsOf.type.arrayType(), elementsOf.propertyName, KEY_ORDER); + this.elementsOf = elementsOf; } - public static ArrayProperty arrayOf(final ValidatableProperty elementProperty) { + public static ArrayProperty arrayOf(final ValidatableProperty elementsOf) { //noinspection unchecked - return (ArrayProperty) new ArrayProperty<>(elementProperty); + return (ArrayProperty) new ArrayProperty<>(elementsOf); } public ValidatableProperty minLength(final int minLength) { @@ -46,14 +48,15 @@ public class ArrayProperty

, E> extends Valid if (maxLength != null && propValue.length > maxLength) { result.add(propertyName + "' length is expected to be at max " + maxLength + " but length of " + display(propValue) + " is " + propValue.length); } - stream(propValue).forEach(e -> elementProperty.validate(result, e, propProvider)); + stream(propValue).forEach(e -> elementsOf.validate(result, e, propProvider)); } @Override protected String simpleTypeName() { - return elementProperty.simpleTypeName() + "[]"; + return elementsOf.simpleTypeName() + "[]"; } + @SafeVarargs private String display(final E... propValue) { return "[" + Arrays.toString(propValue) + "]"; } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java index 28e67f87..a92af7f8 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java @@ -69,7 +69,7 @@ public class StringProperty

> extends ValidatableProp result.add(propertyName + "' length is expected to be at max " + maxLength + " but length of " + display(propValue) + " is " + propValue.length()); } if (matchesRegEx != null && - stream(matchesRegEx).map(p -> p.matcher(propValue)).map(Matcher::matches).findAny().isEmpty()) { + stream(matchesRegEx).map(p -> p.matcher(propValue)).noneMatch(Matcher::matches)) { result.add(propertyName + "' is expected to match any of " + Arrays.toString(matchesRegEx) + " but " + display(propValue) + " does not match any"); } if (isReadOnly() && propValue != null) { diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/ValidatableProperty.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/ValidatableProperty.java index d2bf7056..346ee08b 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/ValidatableProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/ValidatableProperty.java @@ -1,15 +1,16 @@ package net.hostsharing.hsadminng.hs.validation; import com.fasterxml.jackson.annotation.JsonIgnore; -import lombok.experimental.Accessors; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; +import lombok.experimental.Accessors; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.mapper.Array; import org.apache.commons.lang3.function.TriFunction; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; @@ -22,6 +23,7 @@ import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; import static java.util.Collections.emptyList; import static java.util.Optional.ofNullable; +import static org.apache.commons.lang3.ObjectUtils.isArray; @Getter @RequiredArgsConstructor @@ -239,8 +241,8 @@ protected void setDeferredInit(final Function[], T[]> } private Object arrayToList(final Object value) { - if ( value instanceof String[]) { - return List.of((String[])value); + if (isArray(value)) { + return Arrays.stream((Object[])value).map(Object::toString).toList(); } return value; } @@ -265,4 +267,9 @@ protected void setDeferredInit(final Function[], T[]> public T compute(final E entity) { return computedBy.apply(entity); } + + @Override + public String toString() { + return toOrderedMap().toString(); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidatorUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidatorUnitTest.java index 0a3768d8..e9611845 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidatorUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidatorUnitTest.java @@ -36,7 +36,7 @@ class HsEMailAliasHostingAssetValidatorUnitTest { // then assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder( - "{type=string[], propertyName=target, required=true, minLength=1}"); + "{type=string[], propertyName=target, elementProperty={type=string, propertyName=target, matchesRegEx=[^[a-z]{3}[0-9]{2}(-[a-z0-9]+)?$, ^[a-zA-Z0-9_.±]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$], maxLength=320}, required=true, minLength=1}"); } @Test @@ -77,7 +77,7 @@ class HsEMailAliasHostingAssetValidatorUnitTest { // then assertThat(result).containsExactlyInAnyOrder( - "'EMAIL_ALIAS:xyz00-office.parentAsset' must be of type MANAGED_WEBSPACE but is of type MANAGED_SERVER"); + "'EMAIL_ALIAS:xyz00-office.config.target' is expected to match any of [^[a-z]{3}[0-9]{2}(-[a-z0-9]+)?$, ^[a-zA-Z0-9_.±]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$] but 'garbage' does not match any"); } @Test @@ -88,7 +88,7 @@ class HsEMailAliasHostingAssetValidatorUnitTest { .parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET) .identifier("abc00-office") .config(Map.ofEntries( - entry("target", Array.of("xyz00", "xyz00-abc", "garbage", "office@example.com")) + entry("target", Array.of("office@example.com")) )) .build(); final var validator = HsHostingAssetEntityValidatorRegistry.forType(emailAliasHostingAssetEntity.getType()); @@ -108,9 +108,10 @@ class HsEMailAliasHostingAssetValidatorUnitTest { .type(EMAIL_ALIAS) .bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM) .parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET) + .assignedToAsset(TEST_MANAGED_SERVER_HOSTING_ASSET) .identifier("abc00-office") .config(Map.ofEntries( - entry("target", Array.of("xyz00", "xyz00-abc", "garbage", "office@example.com")) + entry("target", Array.of("office@example.com")) )) .build(); final var validator = HsHostingAssetEntityValidatorRegistry.forType(emailAliasHostingAssetEntity.getType()); @@ -120,6 +121,8 @@ class HsEMailAliasHostingAssetValidatorUnitTest { // then assertThat(result).containsExactlyInAnyOrder( - "'identifier' expected to match '^xyz00$|^xyz00-[a-z0-9]+$', but is 'abc00-office'"); + "'EMAIL_ALIAS:abc00-office.bookingItem' must be null but is set to D-1234500:test project:test project booking item", + "'EMAIL_ALIAS:abc00-office.parentAsset' must be of type MANAGED_WEBSPACE but is of type MANAGED_SERVER", + "'EMAIL_ALIAS:abc00-office.assignedToAsset' must be null but is set to D-1234500:test project:test project booking item"); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidatorRegistryUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidatorRegistryUnitTest.java index 881b5c5f..b24a035c 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidatorRegistryUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidatorRegistryUnitTest.java @@ -32,7 +32,8 @@ class HsHostingAssetEntityValidatorRegistryUnitTest { HsHostingAssetType.CLOUD_SERVER, HsHostingAssetType.MANAGED_SERVER, HsHostingAssetType.MANAGED_WEBSPACE, - HsHostingAssetType.UNIX_USER + HsHostingAssetType.UNIX_USER, + HsHostingAssetType.EMAIL_ALIAS ); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidatorUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidatorUnitTest.java index 5ef61da9..ce1b5a1d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidatorUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidatorUnitTest.java @@ -110,7 +110,7 @@ class HsUnixUserHostingAssetValidatorUnitTest { "'UNIX_USER:abc00-temp.config.HDD soft quota' is expected to be at most 100 but is 200", "'UNIX_USER:abc00-temp.config.shell' is expected to be one of [/bin/false, /bin/bash, /bin/csh, /bin/dash, /usr/bin/tcsh, /usr/bin/zsh, /usr/bin/passwd] but is '/is/invalid'", "'UNIX_USER:abc00-temp.config.homedir' is readonly but given as '/is/read-only'", - "'UNIX_USER:abc00-temp.config.totpKey' is expected to be match ^0x([0-9A-Fa-f]{2})+$ but provided value does not match", + "'UNIX_USER:abc00-temp.config.totpKey' is expected to match any of [^0x([0-9A-Fa-f]{2})+$] but provided value does not match any", "'UNIX_USER:abc00-temp.config.password' length is expected to be at min 8 but length of provided value is 5", "'UNIX_USER:abc00-temp.config.password' must contain at least one character of at least 3 of the following groups: upper case letters, lower case letters, digits, special characters" ); @@ -168,7 +168,7 @@ class HsUnixUserHostingAssetValidatorUnitTest { "{type=integer, propertyName=HDD soft quota, unit=GB, maxFrom=HDD hard quota}", "{type=enumeration, propertyName=shell, values=[/bin/false, /bin/bash, /bin/csh, /bin/dash, /usr/bin/tcsh, /usr/bin/zsh, /usr/bin/passwd], defaultValue=/bin/false}", "{type=string, propertyName=homedir, readOnly=true, computed=true}", - "{type=string, propertyName=totpKey, matchesRegEx=^0x([0-9A-Fa-f]{2})+$, minLength=20, maxLength=256, writeOnly=true, undisclosed=true}", + "{type=string, propertyName=totpKey, matchesRegEx=[^0x([0-9A-Fa-f]{2})+$], minLength=20, maxLength=256, writeOnly=true, undisclosed=true}", "{type=password, propertyName=password, minLength=8, maxLength=40, writeOnly=true, computed=true, hashedUsing=SHA512, undisclosed=true}" ); }