implement password-hashing (not fully integrated yet) #67
@ -16,7 +16,7 @@ import static java.util.Optional.ofNullable;
|
||||
|
||||
public class HsBookingItemEntityValidator extends HsEntityValidator<HsBookingItemEntity> {
|
||||
|
||||
public HsBookingItemEntityValidator(final ValidatableProperty<?>... properties) {
|
||||
public HsBookingItemEntityValidator(final ValidatableProperty<?, ?>... properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ public class HsBookingItemEntityValidator extends HsEntityValidator<HsBookingIte
|
||||
// TODO.refa: convert into generic shape like multi-options validator
|
||||
private static String validateMaxTotalValue(
|
||||
final HsBookingItemEntity bookingItem,
|
||||
final ValidatableProperty<?> propDef) {
|
||||
final ValidatableProperty<?, ?> propDef) {
|
||||
final var propName = propDef.propertyName();
|
||||
final var propUnit = ofNullable(propDef.unit()).map(u -> " " + u).orElse("");
|
||||
final var totalValue = ofNullable(bookingItem.getSubBookingItems()).orElse(emptyList())
|
||||
|
@ -24,7 +24,7 @@ import static java.util.Optional.ofNullable;
|
||||
|
||||
public abstract class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAssetEntity> {
|
||||
|
||||
static final ValidatableProperty<?>[] NO_EXTRA_PROPERTIES = new ValidatableProperty<?>[0];
|
||||
static final ValidatableProperty<?, ?>[] NO_EXTRA_PROPERTIES = new ValidatableProperty<?, ?>[0];
|
||||
|
||||
private final HsHostingAssetEntityValidator.BookingItem bookingItemValidation;
|
||||
private final HsHostingAssetEntityValidator.ParentAsset parentAssetValidation;
|
||||
@ -36,7 +36,7 @@ public abstract class HsHostingAssetEntityValidator extends HsEntityValidator<Hs
|
||||
@NotNull final ParentAsset parentAssetValidation,
|
||||
@NotNull final AssignedToAsset assignedToAssetValidation,
|
||||
@NotNull final AlarmContact alarmContactValidation,
|
||||
final ValidatableProperty<?>... properties) {
|
||||
final ValidatableProperty<?, ?>... properties) {
|
||||
super(properties);
|
||||
this.bookingItemValidation = bookingItemValidation;
|
||||
this.parentAssetValidation = parentAssetValidation;
|
||||
@ -105,7 +105,7 @@ public abstract class HsHostingAssetEntityValidator extends HsEntityValidator<Hs
|
||||
// TODO.test: check, if there are any hosting assets which need this validation at all
|
||||
private String validateMaxTotalValue(
|
||||
final HsHostingAssetEntity hostingAsset,
|
||||
final ValidatableProperty<?> propDef) {
|
||||
final ValidatableProperty<?, ?> propDef) {
|
||||
final var propName = propDef.propertyName();
|
||||
final var propUnit = ofNullable(propDef.unit()).map(u -> " " + u).orElse("");
|
||||
final var totalValue = ofNullable(hostingAsset.getSubHostingAssets()).orElse(emptyList())
|
||||
|
@ -30,7 +30,7 @@ class HsUnixUserHostingAssetValidator extends HsHostingAssetEntityValidator {
|
||||
.withDefault("/bin/false"),
|
||||
stringProperty("homedir").readOnly().computedBy(HsUnixUserHostingAssetValidator::computeHomedir),
|
||||
stringProperty("totpKey").matchesRegEx("^0x([0-9A-Fa-f]{2})+$").minLength(20).maxLength(256).undisclosed().writeOnly().optional(),
|
||||
passwordProperty("password").minLength(8).maxLength(40).writeOnly());
|
||||
passwordProperty("password").minLength(8).maxLength(40).hashedUsing("SHA-512").writeOnly());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -9,7 +9,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Setter
|
||||
public class BooleanProperty extends ValidatableProperty<Boolean> {
|
||||
public class BooleanProperty extends ValidatableProperty<BooleanProperty, Boolean> {
|
||||
|
||||
private static final String[] KEY_ORDER = Array.join(ValidatableProperty.KEY_ORDER_HEAD, ValidatableProperty.KEY_ORDER_TAIL);
|
||||
|
||||
@ -23,7 +23,7 @@ public class BooleanProperty extends ValidatableProperty<Boolean> {
|
||||
return new BooleanProperty(propertyName);
|
||||
}
|
||||
|
||||
public ValidatableProperty<Boolean> falseIf(final String refPropertyName, final String refPropertyValue) {
|
||||
public BooleanProperty falseIf(final String refPropertyName, final String refPropertyValue) {
|
||||
this.falseIf = new AbstractMap.SimpleImmutableEntry<>(refPropertyName, refPropertyValue);
|
||||
return this;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import java.util.List;
|
||||
import static java.util.Arrays.stream;
|
||||
|
||||
@Setter
|
||||
public class EnumerationProperty extends ValidatableProperty<String> {
|
||||
public class EnumerationProperty extends ValidatableProperty<EnumerationProperty, String> {
|
||||
|
||||
private static final String[] KEY_ORDER = Array.join(
|
||||
ValidatableProperty.KEY_ORDER_HEAD,
|
||||
@ -26,12 +26,12 @@ public class EnumerationProperty extends ValidatableProperty<String> {
|
||||
return new EnumerationProperty(propertyName);
|
||||
}
|
||||
|
||||
public ValidatableProperty<String> values(final String... values) {
|
||||
public EnumerationProperty values(final String... values) {
|
||||
this.values = values;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void deferredInit(final ValidatableProperty<?>[] allProperties) {
|
||||
public void deferredInit(final ValidatableProperty<?, ?>[] allProperties) {
|
||||
if (hasDeferredInit()) {
|
||||
if (this.values != null) {
|
||||
throw new IllegalStateException("property " + this + " already has values");
|
||||
@ -40,8 +40,8 @@ public class EnumerationProperty extends ValidatableProperty<String> {
|
||||
}
|
||||
}
|
||||
|
||||
public ValidatableProperty<String> valuesFromProperties(final String propertyNamePrefix) {
|
||||
this.setDeferredInit( (ValidatableProperty<?>[] allProperties) -> stream(allProperties)
|
||||
public EnumerationProperty valuesFromProperties(final String propertyNamePrefix) {
|
||||
this.setDeferredInit( (ValidatableProperty<?, ?>[] allProperties) -> stream(allProperties)
|
||||
.map(ValidatableProperty::propertyName)
|
||||
.filter(name -> name.startsWith(propertyNamePrefix))
|
||||
.map(name -> name.substring(propertyNamePrefix.length()))
|
||||
|
@ -14,9 +14,9 @@ import static java.util.Collections.emptyList;
|
||||
// TODO.refa: rename to HsEntityProcessor, also subclasses
|
||||
public abstract class HsEntityValidator<E extends PropertiesProvider> {
|
||||
|
||||
public final ValidatableProperty<?>[] propertyValidators;
|
||||
public final ValidatableProperty<?, ?>[] propertyValidators;
|
||||
|
||||
public HsEntityValidator(final ValidatableProperty<?>... validators) {
|
||||
public HsEntityValidator(final ValidatableProperty<?, ?>... validators) {
|
||||
propertyValidators = validators;
|
||||
stream(propertyValidators).forEach(p -> p.deferredInit(propertyValidators));
|
||||
}
|
||||
@ -68,7 +68,7 @@ public abstract class HsEntityValidator<E extends PropertiesProvider> {
|
||||
.orElse(emptyList()));
|
||||
}
|
||||
|
||||
protected static Integer getIntegerValueWithDefault0(final ValidatableProperty<?> prop, final Map<String, Object> propValues) {
|
||||
protected static Integer getIntegerValueWithDefault0(final ValidatableProperty<?, ?> prop, final Map<String, Object> propValues) {
|
||||
final var value = prop.getValue(propValues);
|
||||
if (value instanceof Integer) {
|
||||
return (Integer) value;
|
||||
|
@ -7,7 +7,7 @@ import org.apache.commons.lang3.Validate;
|
||||
import java.util.List;
|
||||
|
||||
@Setter
|
||||
public class IntegerProperty extends ValidatableProperty<Integer> {
|
||||
public class IntegerProperty extends ValidatableProperty<IntegerProperty, Integer> {
|
||||
|
||||
private final static String[] KEY_ORDER = Array.join(
|
||||
ValidatableProperty.KEY_ORDER_HEAD,
|
||||
@ -30,7 +30,7 @@ public class IntegerProperty extends ValidatableProperty<Integer> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deferredInit(final ValidatableProperty<?>[] allProperties) {
|
||||
public void deferredInit(final ValidatableProperty<?, ?>[] allProperties) {
|
||||
Validate.isTrue(min == null || minFrom == null, "min and minFrom are exclusive, but both are given");
|
||||
Validate.isTrue(max == null || maxFrom == null, "max and maxFrom are exclusive, but both are given");
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Setter
|
||||
public class PasswordProperty extends StringProperty {
|
||||
public class PasswordProperty extends StringProperty<PasswordProperty> {
|
||||
|
||||
private PasswordProperty(final String propertyName) {
|
||||
super(propertyName);
|
||||
@ -23,7 +23,9 @@ public class PasswordProperty extends StringProperty {
|
||||
validatePassword(result, propValue);
|
||||
}
|
||||
|
||||
// TODO.impl: only a SHA512 hash should be stored in the database, not the password itself
|
||||
public PasswordProperty hashedUsing(final String hashAlgoritm) {
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String simpleTypeName() {
|
||||
@ -60,6 +62,5 @@ public class PasswordProperty extends StringProperty {
|
||||
if (containsColon) {
|
||||
result.add(propertyName + "' must not contain colon (':')");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
|
||||
@Setter
|
||||
public class StringProperty extends ValidatableProperty<String> {
|
||||
public class StringProperty<P extends StringProperty<P>> extends ValidatableProperty<P, String> {
|
||||
|
||||
private static final String[] KEY_ORDER = Array.join(
|
||||
ValidatableProperty.KEY_ORDER_HEAD,
|
||||
@ -24,23 +24,23 @@ public class StringProperty extends ValidatableProperty<String> {
|
||||
super(String.class, propertyName, KEY_ORDER);
|
||||
}
|
||||
|
||||
public static StringProperty stringProperty(final String propertyName) {
|
||||
return new StringProperty(propertyName);
|
||||
public static StringProperty<?> stringProperty(final String propertyName) {
|
||||
return new StringProperty<>(propertyName);
|
||||
}
|
||||
|
||||
public StringProperty minLength(final int minLength) {
|
||||
public P minLength(final int minLength) {
|
||||
this.minLength = minLength;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
public StringProperty maxLength(final int maxLength) {
|
||||
public P maxLength(final int maxLength) {
|
||||
this.maxLength = maxLength;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
public StringProperty matchesRegEx(final String regExPattern) {
|
||||
public P matchesRegEx(final String regExPattern) {
|
||||
this.matchesRegEx = Pattern.compile(regExPattern);
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,9 +48,9 @@ public class StringProperty extends ValidatableProperty<String> {
|
||||
*
|
||||
* @return this;
|
||||
*/
|
||||
public StringProperty undisclosed() {
|
||||
public P undisclosed() {
|
||||
this.undisclosed = true;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,7 +25,7 @@ import static java.util.Optional.ofNullable;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public abstract class ValidatableProperty<T> {
|
||||
public abstract class ValidatableProperty<P extends ValidatableProperty<?, ?>, T> {
|
||||
|
||||
protected static final String[] KEY_ORDER_HEAD = Array.of("propertyName");
|
||||
protected static final String[] KEY_ORDER_TAIL = Array.of("required", "defaultValue", "readOnly", "writeOnly", "computed", "isTotalsValidator", "thresholdPercentage");
|
||||
@ -51,7 +51,7 @@ public abstract class ValidatableProperty<T> {
|
||||
@Accessors(makeFinal = true, chain = true, fluent = false)
|
||||
private boolean writeOnly;
|
||||
|
||||
private Function<ValidatableProperty<?>[], T[]> deferredInit;
|
||||
private Function<ValidatableProperty<?, ?>[], T[]> deferredInit;
|
||||
private boolean isTotalsValidator = false;
|
||||
|
||||
@JsonIgnore
|
||||
@ -59,11 +59,16 @@ public abstract class ValidatableProperty<T> {
|
||||
|
||||
private Integer thresholdPercentage; // TODO.impl: move to IntegerProperty
|
||||
|
||||
public final P self() {
|
||||
//noinspection unchecked
|
||||
return (P) this;
|
||||
}
|
||||
|
||||
public String unit() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void setDeferredInit(final Function<ValidatableProperty<?>[], T[]> function) {
|
||||
protected void setDeferredInit(final Function<ValidatableProperty<?, ?>[], T[]> function) {
|
||||
this.deferredInit = function;
|
||||
}
|
||||
|
||||
@ -71,47 +76,47 @@ public abstract class ValidatableProperty<T> {
|
||||
return deferredInit != null;
|
||||
}
|
||||
|
||||
public T[] doDeferredInit(final ValidatableProperty<?>[] allProperties) {
|
||||
public T[] doDeferredInit(final ValidatableProperty<?, ?>[] allProperties) {
|
||||
return deferredInit.apply(allProperties);
|
||||
}
|
||||
|
||||
public ValidatableProperty<T> writeOnly() {
|
||||
public P writeOnly() {
|
||||
this.writeOnly = true;
|
||||
optional();
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
public ValidatableProperty<T> readOnly() {
|
||||
public P readOnly() {
|
||||
this.readOnly = true;
|
||||
optional();
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
public ValidatableProperty<T> required() {
|
||||
public P required() {
|
||||
required = TRUE;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
public ValidatableProperty<T> optional() {
|
||||
public ValidatableProperty<P, T> optional() {
|
||||
required = FALSE;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ValidatableProperty<T> withDefault(final T value) {
|
||||
public P withDefault(final T value) {
|
||||
defaultValue = value;
|
||||
required = FALSE;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
public void deferredInit(final ValidatableProperty<?>[] allProperties) {
|
||||
public void deferredInit(final ValidatableProperty<?, ?>[] allProperties) {
|
||||
}
|
||||
|
||||
public ValidatableProperty<T> asTotalLimit() {
|
||||
public P asTotalLimit() {
|
||||
isTotalsValidator = true;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
public ValidatableProperty<T> asTotalLimitFor(final String propertyName, final String propertyValue) {
|
||||
public P asTotalLimitFor(final String propertyName, final String propertyValue) {
|
||||
if (asTotalLimitValidators == null) {
|
||||
asTotalLimitValidators = new ArrayList<>();
|
||||
}
|
||||
@ -132,7 +137,7 @@ public abstract class ValidatableProperty<T> {
|
||||
return emptyList();
|
||||
};
|
||||
asTotalLimitValidators.add((final HsBookingItemEntity entity) -> validator.apply(entity, (IntegerProperty)this, 1));
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
public String propertyName() {
|
||||
@ -147,7 +152,7 @@ public abstract class ValidatableProperty<T> {
|
||||
return thresholdPercentage;
|
||||
}
|
||||
|
||||
public ValidatableProperty<T> eachComprising(final int factor, final TriFunction<HsBookingItemEntity, IntegerProperty, Integer, List<String>> validator) {
|
||||
public ValidatableProperty<P, T> eachComprising(final int factor, final TriFunction<HsBookingItemEntity, IntegerProperty, Integer, List<String>> validator) {
|
||||
if (asTotalLimitValidators == null) {
|
||||
asTotalLimitValidators = new ArrayList<>();
|
||||
}
|
||||
@ -155,9 +160,9 @@ public abstract class ValidatableProperty<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ValidatableProperty<?> withThreshold(final Integer percentage) {
|
||||
public P withThreshold(final Integer percentage) {
|
||||
this.thresholdPercentage = percentage;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
public final List<String> validate(final PropertiesProvider propsProvider) {
|
||||
@ -250,10 +255,10 @@ public abstract class ValidatableProperty<T> {
|
||||
.toList();
|
||||
}
|
||||
|
||||
public ValidatableProperty<T> computedBy(final Function<PropertiesProvider, T> compute) {
|
||||
public P computedBy(final Function<PropertiesProvider, T> compute) {
|
||||
this.computedBy = compute;
|
||||
this.computed = true;
|
||||
return this;
|
||||
return self();
|
||||
}
|
||||
|
||||
public <E extends PropertiesProvider> T compute(final E entity) {
|
||||
|
@ -12,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class PasswordPropertyUnitTest {
|
||||
|
||||
private final ValidatableProperty<String> passwordProp = passwordProperty("password").minLength(8).maxLength(40).writeOnly();
|
||||
private final ValidatableProperty<PasswordProperty, String> passwordProp = passwordProperty("password").minLength(8).maxLength(40).writeOnly();
|
||||
private final List<String> violations = new ArrayList<>();
|
||||
|
||||
@ParameterizedTest
|
||||
|
Loading…
Reference in New Issue
Block a user