diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java index 6b390767..74e59965 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsUnixUserHostingAssetValidator.java @@ -29,7 +29,7 @@ class HsUnixUserHostingAssetValidator extends HsHostingAssetEntityValidator { .values("/bin/false", "/bin/bash", "/bin/csh", "/bin/dash", "/usr/bin/tcsh", "/usr/bin/zsh", "/usr/bin/passwd") .withDefault("/bin/false"), stringProperty("homedir").readOnly().computedBy(HsUnixUserHostingAssetValidator::computeHomedir), - stringProperty("totpKey").matchesRegEx("^0x([0-9A-Fa-f]{2})+$").minLength(20).maxLength(256).hidden().writeOnly().optional(), + stringProperty("totpKey").matchesRegEx("^0x([0-9A-Fa-f]{2})+$").minLength(20).maxLength(256).undisclosed().writeOnly().optional(), passwordProperty("password").minLength(8).maxLength(40).writeOnly()); } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/EnumerationProperty.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/EnumerationProperty.java index 0266e003..60af1b73 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/EnumerationProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/EnumerationProperty.java @@ -32,20 +32,20 @@ public class EnumerationProperty extends ValidatableProperty { } public void deferredInit(final ValidatableProperty[] allProperties) { - if (deferredInit != null) { + if (hasDeferredInit()) { if (this.values != null) { throw new IllegalStateException("property " + this + " already has values"); } - this.values = deferredInit.apply(allProperties); + this.values = doDeferredInit(allProperties); } } public ValidatableProperty valuesFromProperties(final String propertyNamePrefix) { - this.deferredInit = (ValidatableProperty[] allProperties) -> stream(allProperties) + this.setDeferredInit( (ValidatableProperty[] allProperties) -> stream(allProperties) .map(ValidatableProperty::propertyName) .filter(name -> name.startsWith(propertyNamePrefix)) .map(name -> name.substring(propertyNamePrefix.length())) - .toArray(String[]::new); + .toArray(String[]::new)); return this; } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java index fb197cd7..5af7118d 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java @@ -92,7 +92,7 @@ public abstract class HsEntityValidator { public Map postProcess(final E entity, final Map config) { final var copy = new HashMap<>(config); stream(propertyValidators).forEach(p -> { - if ( p.writeOnly) { + if ( p.isWriteOnly()) { copy.remove(p.propertyName); } if (p.isComputed()) { diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/PasswordProperty.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/PasswordProperty.java index 441f0d06..92cafb9a 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/PasswordProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/PasswordProperty.java @@ -10,7 +10,7 @@ public class PasswordProperty extends StringProperty { private PasswordProperty(final String propertyName) { super(propertyName); - hidden(); + undisclosed(); } public static PasswordProperty passwordProperty(final String propertyName) { 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 616ff26c..a499d951 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/StringProperty.java @@ -6,7 +6,6 @@ import net.hostsharing.hsadminng.mapper.Array; import java.util.List; import java.util.regex.Pattern; - @Setter public class StringProperty extends ValidatableProperty { @@ -14,11 +13,11 @@ public class StringProperty extends ValidatableProperty { ValidatableProperty.KEY_ORDER_HEAD, Array.of("matchesRegEx", "minLength", "maxLength"), ValidatableProperty.KEY_ORDER_TAIL, - Array.of("hidden")); + Array.of("undisclosed")); private Pattern matchesRegEx; private Integer minLength; private Integer maxLength; - private boolean hidden; + private boolean undisclosed; protected StringProperty(final String propertyName) { super(String.class, propertyName, KEY_ORDER); @@ -43,8 +42,13 @@ public class StringProperty extends ValidatableProperty { return this; } - public StringProperty hidden() { - this.hidden = true; + /** + * The property value is not disclosed in error messages. + * + * @return this; + */ + public StringProperty undisclosed() { + this.undisclosed = true; return this; } @@ -59,13 +63,13 @@ public class StringProperty extends ValidatableProperty { if (matchesRegEx != null && !matchesRegEx.matcher(propValue).matches()) { result.add(propertyName + "' is expected to be match " + matchesRegEx + " but " + display(propValue) + " does not match"); } - if (readOnly && propValue != null) { + if (isReadOnly() && propValue != null) { result.add(propertyName + "' is readonly but given as " + display(propValue)); } } private String display(final String propValue) { - return hidden ? "provided value" : ("'" + propValue + "'"); + return undisclosed ? "provided value" : ("'" + propValue + "'"); } @Override 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 259bff9d..b34eb8fa 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/ValidatableProperty.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/ValidatableProperty.java @@ -1,6 +1,8 @@ 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 net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; @@ -21,6 +23,7 @@ import static java.lang.Boolean.TRUE; import static java.util.Collections.emptyList; import static java.util.Optional.ofNullable; +@Getter @RequiredArgsConstructor public abstract class ValidatableProperty { @@ -29,16 +32,28 @@ public abstract class ValidatableProperty { final Class type; final String propertyName; + + @JsonIgnore private final String[] keyOrder; + private Boolean required; private T defaultValue; - protected Function computedBy; - protected boolean computed; // used in descriptor, because computedBy cannot be rendered to a text string - protected boolean readOnly; - protected boolean writeOnly; - protected Function[], T[]> deferredInit; + @JsonIgnore + private Function computedBy; + + @Accessors(makeFinal = true, chain = true, fluent = false) + private boolean computed; // used in descriptor, because computedBy cannot be rendered to a text string + + @Accessors(makeFinal = true, chain = true, fluent = false) + private boolean readOnly; + + @Accessors(makeFinal = true, chain = true, fluent = false) + private boolean writeOnly; + + private Function[], T[]> deferredInit; private boolean isTotalsValidator = false; + @JsonIgnore private List>> asTotalLimitValidators; // TODO.impl: move to BookingItemIntegerProperty @@ -48,6 +63,17 @@ public abstract class ValidatableProperty { return null; } + protected void setDeferredInit(final Function[], T[]> function) { + this.deferredInit = function; + } + + public boolean hasDeferredInit() { + return deferredInit != null; + } + + public T[] doDeferredInit(final ValidatableProperty[] allProperties) { + return deferredInit.apply(allProperties); + } public ValidatableProperty writeOnly() { this.writeOnly = true; @@ -61,7 +87,6 @@ public abstract class ValidatableProperty { return this; } - public ValidatableProperty required() { required = TRUE; return this; @@ -231,10 +256,6 @@ public abstract class ValidatableProperty { return this; } - public boolean isComputed() { - return computedBy != null; - } - public T compute(final E entity) { return computedBy.apply(entity); } 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 c8b818f3..8ed76743 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 @@ -124,8 +124,8 @@ 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, hidden=true}", - "{type=password, propertyName=password, minLength=8, maxLength=40, writeOnly=true, hidden=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, undisclosed=true}" ); } }