integrate-sha512-password-hashing (#68)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/68 Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
package net.hostsharing.hsadminng.hash;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
import static net.hostsharing.hsadminng.hash.HashProcessor.Algorithm.SHA512;
|
||||
import static net.hostsharing.hsadminng.hash.HashProcessor.hashAlgorithm;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
|
||||
class HashProcessorUnitTest {
|
||||
|
||||
final String OTHER_PASSWORD = "other password";
|
||||
final String GIVEN_PASSWORD = "given password";
|
||||
final String GIVEN_PASSWORD_HASH = "foKDNQP0oZo0pjFpss5vNl0kfHOs6MKMaJUUbpJTg6hqI1WY+KbU/PKQIg2xt/mwDMmW5WR0pdUZnTv8RPTfhjprZUNqTXJsUXczQnczYUxE";
|
||||
final String GIVEN_SALT = "given salt";
|
||||
|
||||
@Test
|
||||
void verifiesHashedPasswordWithRandomSalt() {
|
||||
final var hash = hashAlgorithm(SHA512).withRandomSalt().generate(GIVEN_PASSWORD);
|
||||
hashAlgorithm(SHA512).withHash(hash).verify(GIVEN_PASSWORD); // throws exception if wrong
|
||||
}
|
||||
|
||||
@Test
|
||||
void verifiesHashedPasswordWithGivenSalt() {
|
||||
final var hash = hashAlgorithm(SHA512).withSalt(GIVEN_SALT).generate(GIVEN_PASSWORD);
|
||||
|
||||
final var decoded = new String(Base64.getDecoder().decode(hash));
|
||||
assertThat(decoded).endsWith(":" + GIVEN_SALT);
|
||||
hashAlgorithm(SHA512).withHash(hash).verify(GIVEN_PASSWORD); // throws exception if wrong
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwsExceptionForInvalidPassword() {
|
||||
final var throwable = catchThrowable(() ->
|
||||
hashAlgorithm(SHA512).withHash(GIVEN_PASSWORD_HASH).verify(OTHER_PASSWORD));
|
||||
|
||||
assertThat(throwable).hasMessage("invalid password");
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
package net.hostsharing.hsadminng.hash;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static net.hostsharing.hsadminng.hash.LinuxEtcShadowHashGenerator.Algorithm.SHA512;
|
||||
import static net.hostsharing.hsadminng.hash.LinuxEtcShadowHashGenerator.hash;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
|
||||
class LinuxEtcShadowHashGeneratorUnitTest {
|
||||
|
||||
final String GIVEN_PASSWORD = "given password";
|
||||
final String WRONG_PASSWORD = "wrong password";
|
||||
final String GIVEN_SALT = "0123456789abcdef";
|
||||
|
||||
// generated via mkpasswd for plaintext password GIVEN_PASSWORD (see above)
|
||||
final String GIVEN_SHA512_HASH = "$6$ooei1HK6JXVaI7KC$sY5d9fEOr36hjh4CYwIKLMfRKL1539bEmbVCZ.zPiH0sv7jJVnoIXb5YEefEtoSM2WWgDi9hr7vXRe3Nw8zJP/";
|
||||
final String GIVEN_YESCRYPT_HASH = "$y$j9T$wgYACPmBXvlMg2MzeZA0p1$KXUzd28nG.67GhPnBZ3aZsNNA5bWFdL/dyG4wS0iRw7";
|
||||
|
||||
@Test
|
||||
void verifiesPasswordAgainstSha512HashFromMkpasswd() {
|
||||
hash(GIVEN_PASSWORD).verify(GIVEN_SHA512_HASH); // throws exception if wrong
|
||||
}
|
||||
|
||||
@Test
|
||||
void verifiesPasswordAgainstYescryptHashFromMkpasswd() {
|
||||
hash(GIVEN_PASSWORD).verify(GIVEN_YESCRYPT_HASH); // throws exception if wrong
|
||||
}
|
||||
|
||||
@Test
|
||||
void verifiesHashedPasswordWithRandomSalt() {
|
||||
final var hash = hash(GIVEN_PASSWORD).using(SHA512).withRandomSalt().generate();
|
||||
hash(GIVEN_PASSWORD).verify(hash); // throws exception if wrong
|
||||
}
|
||||
|
||||
@Test
|
||||
void verifiesHashedPasswordWithGivenSalt() {
|
||||
final var givenPasswordHash =hash(GIVEN_PASSWORD).using(SHA512).withSalt(GIVEN_SALT).generate();
|
||||
hash(GIVEN_PASSWORD).verify(givenPasswordHash); // throws exception if wrong
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwsExceptionForInvalidPassword() {
|
||||
final var givenPasswordHash = hash(GIVEN_PASSWORD).using(SHA512).withRandomSalt().generate();
|
||||
|
||||
final var throwable = catchThrowable(() ->
|
||||
hash(WRONG_PASSWORD).verify(givenPasswordHash) // throws exception if wrong);
|
||||
);
|
||||
assertThat(throwable).hasMessage("invalid password");
|
||||
}
|
||||
}
|
@@ -16,6 +16,12 @@ public class TestHsBookingItem {
|
||||
.project(TEST_PROJECT)
|
||||
.type(HsBookingItemType.CLOUD_SERVER)
|
||||
.caption("test cloud server booking item")
|
||||
.resources(Map.ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 4),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 250)
|
||||
))
|
||||
.validity(Range.closedInfinite(LocalDate.of(2020, 1, 15)))
|
||||
.build();
|
||||
|
||||
|
@@ -55,13 +55,13 @@ class HsCloudServerBookingItemValidatorUnitTest {
|
||||
|
||||
// then
|
||||
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
||||
"{type=boolean, propertyName=active, required=false, defaultValue=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=CPUs, min=1, max=32, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=RAM, unit=GB, min=1, max=128, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=SSD, unit=GB, min=0, max=1000, step=25, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=HDD, unit=GB, min=0, max=4000, step=250, required=false, defaultValue=0, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=Traffic, unit=GB, min=250, max=10000, step=250, required=true, isTotalsValidator=false}",
|
||||
"{type=enumeration, propertyName=SLA-Infrastructure, values=[BASIC, EXT8H, EXT4H, EXT2H], required=false, isTotalsValidator=false}");
|
||||
"{type=boolean, propertyName=active, defaultValue=true}",
|
||||
"{type=integer, propertyName=CPUs, min=1, max=32, required=true}",
|
||||
"{type=integer, propertyName=RAM, unit=GB, min=1, max=128, required=true}",
|
||||
"{type=integer, propertyName=SSD, unit=GB, min=0, max=1000, step=25, required=true}",
|
||||
"{type=integer, propertyName=HDD, unit=GB, min=0, max=4000, step=250, defaultValue=0}",
|
||||
"{type=integer, propertyName=Traffic, unit=GB, min=250, max=10000, step=250, required=true}",
|
||||
"{type=enumeration, propertyName=SLA-Infrastructure, values=[BASIC, EXT8H, EXT4H, EXT2H]}");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -63,17 +63,17 @@ class HsManagedServerBookingItemValidatorUnitTest {
|
||||
|
||||
// then
|
||||
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
||||
"{type=integer, propertyName=CPUs, min=1, max=32, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=RAM, unit=GB, min=1, max=128, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=CPUs, min=1, max=32, required=true}",
|
||||
"{type=integer, propertyName=RAM, unit=GB, min=1, max=128, required=true}",
|
||||
"{type=integer, propertyName=SSD, unit=GB, min=25, max=1000, step=25, required=true, isTotalsValidator=true, thresholdPercentage=200}",
|
||||
"{type=integer, propertyName=HDD, unit=GB, min=0, max=4000, step=250, required=false, defaultValue=0, isTotalsValidator=true, thresholdPercentage=200}",
|
||||
"{type=integer, propertyName=HDD, unit=GB, min=0, max=4000, step=250, defaultValue=0, isTotalsValidator=true, thresholdPercentage=200}",
|
||||
"{type=integer, propertyName=Traffic, unit=GB, min=250, max=10000, step=250, required=true, isTotalsValidator=true, thresholdPercentage=200}",
|
||||
"{type=enumeration, propertyName=SLA-Platform, values=[BASIC, EXT8H, EXT4H, EXT2H], required=false, defaultValue=BASIC, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=SLA-EMail, required=false, defaultValue=false, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=SLA-Maria, required=false, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=SLA-PgSQL, required=false, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=SLA-Office, required=false, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=SLA-Web, required=false, isTotalsValidator=false}");
|
||||
"{type=enumeration, propertyName=SLA-Platform, values=[BASIC, EXT8H, EXT4H, EXT2H], defaultValue=BASIC}",
|
||||
"{type=boolean, propertyName=SLA-EMail}", // TODO.impl: falseIf-validation is missing in output
|
||||
"{type=boolean, propertyName=SLA-Maria}",
|
||||
"{type=boolean, propertyName=SLA-PgSQL}",
|
||||
"{type=boolean, propertyName=SLA-Office}",
|
||||
"{type=boolean, propertyName=SLA-Web}");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -55,12 +55,12 @@ class HsManagedWebspaceBookingItemValidatorUnitTest {
|
||||
|
||||
// then
|
||||
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
||||
"{type=integer, propertyName=SSD, unit=GB, min=1, max=100, step=1, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=HDD, unit=GB, min=0, max=250, step=10, required=false, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=Traffic, unit=GB, min=10, max=1000, step=10, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=Multi, min=1, max=100, step=1, required=false, defaultValue=1, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=Daemons, min=0, max=10, required=false, defaultValue=0, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=Online Office Server, required=false, isTotalsValidator=false}",
|
||||
"{type=enumeration, propertyName=SLA-Platform, values=[BASIC, EXT24H], required=false, defaultValue=BASIC, isTotalsValidator=false}");
|
||||
"{type=integer, propertyName=SSD, unit=GB, min=1, max=100, step=1, required=true}",
|
||||
"{type=integer, propertyName=HDD, unit=GB, min=0, max=250, step=10}",
|
||||
"{type=integer, propertyName=Traffic, unit=GB, min=10, max=1000, step=10, required=true}",
|
||||
"{type=integer, propertyName=Multi, min=1, max=100, step=1, defaultValue=1}",
|
||||
"{type=integer, propertyName=Daemons, min=0, max=10, defaultValue=0}",
|
||||
"{type=boolean, propertyName=Online Office Server}",
|
||||
"{type=enumeration, propertyName=SLA-Platform, values=[BASIC, EXT24H], defaultValue=BASIC}");
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||
import net.hostsharing.hsadminng.hash.LinuxEtcShadowHashGenerator;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
@@ -523,6 +524,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.identifier("fir01-temp")
|
||||
.caption("some test-unix-user")
|
||||
.build());
|
||||
LinuxEtcShadowHashGenerator.nextSalt("Jr5w/Y8zo8pCkqg7");
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
@@ -575,7 +577,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
assertThat(asset.getCaption()).isEqualTo("some patched test-unix-user");
|
||||
assertThat(asset.getConfig().toString()).isEqualTo("""
|
||||
{
|
||||
"password": "Ein Passwort mit 4 Zeichengruppen!",
|
||||
"password": "$6$Jr5w/Y8zo8pCkqg7$/rePRbvey3R6Sz/02YTlTQcRt5qdBPTj2h5.hz.rB8NfIoND8pFOjeB7orYcPs9JNf3JDxPP2V.6MQlE5BwAY/",
|
||||
"shell": "/bin/bash",
|
||||
"totpKey": "0x1234567890abcdef0123456789abcdef"
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
|
||||
|
||||
|
||||
// when
|
||||
final var result = validator.validate(cloudServerHostingAssetEntity);
|
||||
final var result = validator.validateEntity(cloudServerHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
@@ -49,7 +49,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
|
||||
|
||||
|
||||
// when
|
||||
final var result = validator.validate(cloudServerHostingAssetEntity);
|
||||
final var result = validator.validateEntity(cloudServerHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
@@ -76,7 +76,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedServerHostingAssetEntity);
|
||||
final var result = validator.validateEntity(mangedServerHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
@@ -96,7 +96,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedServerHostingAssetEntity);
|
||||
final var result = validator.validateEntity(mangedServerHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
|
@@ -1,16 +1,10 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
class HsHostingAssetEntityValidatorRegistryUnitTest {
|
||||
|
||||
@@ -41,24 +35,4 @@ class HsHostingAssetEntityValidatorRegistryUnitTest {
|
||||
HsHostingAssetType.UNIX_USER
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatedDoesNotThrowAnExceptionForValidEntity() {
|
||||
final var givenBookingItem = HsBookingItemEntity.builder()
|
||||
.type(HsBookingItemType.CLOUD_SERVER)
|
||||
.resources(Map.ofEntries(
|
||||
entry("CPUs", 4),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 250)
|
||||
))
|
||||
.build();
|
||||
final var validEntity = HsHostingAssetEntity.builder()
|
||||
.type(HsHostingAssetType.CLOUD_SERVER)
|
||||
.bookingItem(givenBookingItem)
|
||||
.identifier("vm1234")
|
||||
.caption("some valid cloud server")
|
||||
.build();
|
||||
HsHostingAssetEntityValidatorRegistry.validated(validEntity);
|
||||
}
|
||||
}
|
||||
|
@@ -1,35 +0,0 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
|
||||
class HsHostingAssetEntityValidatorUnitTest {
|
||||
|
||||
@Test
|
||||
void validThrowsException() {
|
||||
// given
|
||||
final var managedServerHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.identifier("vm1234")
|
||||
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_SERVER).build())
|
||||
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_SERVER).build())
|
||||
.assignedToAsset(HsHostingAssetEntity.builder().type(MANAGED_SERVER).build())
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = catchThrowable( ()-> HsHostingAssetEntityValidatorRegistry.validated(managedServerHostingAssetEntity));
|
||||
|
||||
// then
|
||||
assertThat(result.getMessage()).contains(
|
||||
"'MANAGED_SERVER:vm1234.parentAsset' must be null but is set to D-???????-?:null",
|
||||
"'MANAGED_SERVER:vm1234.assignedToAsset' must be null but is set to D-???????-?:null"
|
||||
);
|
||||
}
|
||||
}
|
@@ -8,6 +8,8 @@ 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_CLOUD_SERVER_BOOKING_ITEM;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_SERVER_BOOKING_ITEM;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -19,7 +21,7 @@ class HsManagedServerHostingAssetValidatorUnitTest {
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.identifier("vm1234")
|
||||
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_SERVER).build())
|
||||
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
|
||||
.parentAsset(HsHostingAssetEntity.builder().build())
|
||||
.assignedToAsset(HsHostingAssetEntity.builder().build())
|
||||
.config(Map.ofEntries(
|
||||
@@ -31,12 +33,12 @@ class HsManagedServerHostingAssetValidatorUnitTest {
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(mangedWebspaceHostingAssetEntity.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
||||
final var result = validator.validateEntity(mangedWebspaceHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'MANAGED_SERVER:vm1234.parentAsset' must be null but is set to D-???????-?:null",
|
||||
"'MANAGED_SERVER:vm1234.assignedToAsset' must be null but is set to D-???????-?:null",
|
||||
"'MANAGED_SERVER:vm1234.parentAsset' must be null but is set to D-1234500:test project:test project booking item",
|
||||
"'MANAGED_SERVER:vm1234.assignedToAsset' must be null but is set to D-1234500:test project:test project booking item",
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_cpu_usage' is expected to be at least 10 but is 2",
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_ram_usage' is expected to be at most 100 but is 101",
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_hdd_usage' is expected to be of type class java.lang.Integer, but is of type 'String'");
|
||||
@@ -53,7 +55,7 @@ class HsManagedServerHostingAssetValidatorUnitTest {
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedServerHostingAssetEntity);
|
||||
final var result = validator.validateEntity(mangedServerHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
@@ -68,17 +70,17 @@ class HsManagedServerHostingAssetValidatorUnitTest {
|
||||
.identifier("xyz00")
|
||||
.parentAsset(HsHostingAssetEntity.builder().build())
|
||||
.assignedToAsset(HsHostingAssetEntity.builder().build())
|
||||
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
|
||||
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
|
||||
.build();
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedServerHostingAssetEntity);
|
||||
final var result = validator.validateEntity(mangedServerHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'MANAGED_SERVER:xyz00.bookingItem' must be of type MANAGED_SERVER but is of type CLOUD_SERVER",
|
||||
"'MANAGED_SERVER:xyz00.parentAsset' must be null but is set to D-???????-?:null",
|
||||
"'MANAGED_SERVER:xyz00.assignedToAsset' must be null but is set to D-???????-?:null");
|
||||
"'MANAGED_SERVER:xyz00.parentAsset' must be null but is set to D-1234500:test project:test cloud server booking item",
|
||||
"'MANAGED_SERVER:xyz00.assignedToAsset' must be null but is set to D-1234500:test project:test cloud server booking item");
|
||||
}
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||
@@ -70,7 +71,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
||||
final var result = validator.validateContext(mangedWebspaceHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).isEmpty();
|
||||
@@ -88,7 +89,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
||||
final var result = validator.validateEntity(mangedWebspaceHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'identifier' expected to match '^abc[0-9][0-9]$', but is 'xyz00'");
|
||||
@@ -109,7 +110,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
||||
final var result = validator.validateEntity(mangedWebspaceHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'MANAGED_WEBSPACE:abc00.config.unknown' is not expected but is set to 'some value'");
|
||||
@@ -131,7 +132,10 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
||||
final var result = Stream.concat(
|
||||
validator.validateEntity(mangedWebspaceHostingAssetEntity).stream(),
|
||||
validator.validateContext(mangedWebspaceHostingAssetEntity).stream())
|
||||
.toList();
|
||||
|
||||
// then
|
||||
assertThat(result).isEmpty();
|
||||
@@ -154,7 +158,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
||||
final var result = validator.validateEntity(mangedWebspaceHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly(
|
||||
|
@@ -1,11 +1,14 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hash.LinuxEtcShadowHashGenerator;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Map.ofEntries;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_SERVER_BOOKING_ITEM;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_WEBSPACE_BOOKING_ITEM;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||
@@ -21,32 +24,55 @@ class HsUnixUserHostingAssetValidatorUnitTest {
|
||||
.caption("some managed server")
|
||||
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
|
||||
.build();
|
||||
private HsHostingAssetEntity TEST_MANAGED_WEBSPACE_HOSTING_ASSET = HsHostingAssetEntity.builder()
|
||||
private final HsHostingAssetEntity TEST_MANAGED_WEBSPACE_HOSTING_ASSET = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.bookingItem(TEST_MANAGED_WEBSPACE_BOOKING_ITEM)
|
||||
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
|
||||
.identifier("abc00")
|
||||
.build();;
|
||||
.build();
|
||||
private final HsHostingAssetEntity GIVEN_VALID_UNIX_USER_HOSTING_ASSET = HsHostingAssetEntity.builder()
|
||||
.type(UNIX_USER)
|
||||
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
|
||||
.identifier("abc00-temp")
|
||||
.caption("some valid test UnixUser")
|
||||
.config(new HashMap<>(ofEntries(
|
||||
entry("SSD hard quota", 50),
|
||||
entry("SSD soft quota", 40),
|
||||
entry("totpKey", "0x123456789abcdef01234"),
|
||||
entry("password", "Hallo Computer, lass mich rein!")
|
||||
)))
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void preparesUnixUser() {
|
||||
// given
|
||||
final var unixUserHostingAsset = GIVEN_VALID_UNIX_USER_HOSTING_ASSET;
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(unixUserHostingAsset.getType());
|
||||
|
||||
// when
|
||||
LinuxEtcShadowHashGenerator.nextSalt("Ly3LbsArtL5u4EVt");
|
||||
validator.prepareProperties(unixUserHostingAsset);
|
||||
|
||||
// then
|
||||
assertThat(unixUserHostingAsset.getConfig()).containsExactlyInAnyOrderEntriesOf(ofEntries(
|
||||
entry("SSD hard quota", 50),
|
||||
entry("SSD soft quota", 40),
|
||||
entry("totpKey", "0x123456789abcdef01234"),
|
||||
entry("password", "$6$Ly3LbsArtL5u4EVt$i/ayIEvm0y4bjkFB6wbg8imbRIaw4mAA4gqYRVyoSkj.iIxJKS3KiRkSjP8gweNcpKL0Q0N31EadT8fCnWErL.")
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesValidUnixUser() {
|
||||
// given
|
||||
final var unixUserHostingAsset = HsHostingAssetEntity.builder()
|
||||
.type(UNIX_USER)
|
||||
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
|
||||
.identifier("abc00-temp")
|
||||
.caption("some valid test UnixUser")
|
||||
.config(Map.ofEntries(
|
||||
entry("SSD hard quota", 50),
|
||||
entry("SSD soft quota", 40),
|
||||
entry("totpKey", "0x123456789abcdef01234"),
|
||||
entry("password", "Hallo Computer, lass mich rein!")
|
||||
))
|
||||
.build();
|
||||
final var unixUserHostingAsset = GIVEN_VALID_UNIX_USER_HOSTING_ASSET;
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(unixUserHostingAsset.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(unixUserHostingAsset);
|
||||
final var result = Stream.concat(
|
||||
validator.validateEntity(unixUserHostingAsset).stream(),
|
||||
validator.validateContext(unixUserHostingAsset).stream()
|
||||
).toList();
|
||||
|
||||
// then
|
||||
assertThat(result).isEmpty();
|
||||
@@ -60,7 +86,7 @@ class HsUnixUserHostingAssetValidatorUnitTest {
|
||||
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
|
||||
.identifier("abc00-temp")
|
||||
.caption("some test UnixUser with invalid properties")
|
||||
.config(Map.ofEntries(
|
||||
.config(ofEntries(
|
||||
entry("SSD hard quota", 100),
|
||||
entry("SSD soft quota", 200),
|
||||
entry("HDD hard quota", 100),
|
||||
@@ -74,7 +100,7 @@ class HsUnixUserHostingAssetValidatorUnitTest {
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(unixUserHostingAsset.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(unixUserHostingAsset);
|
||||
final var result = validator.validateEntity(unixUserHostingAsset);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
@@ -101,13 +127,31 @@ class HsUnixUserHostingAssetValidatorUnitTest {
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(unixUserHostingAsset.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(unixUserHostingAsset);
|
||||
final var result = validator.validateEntity(unixUserHostingAsset);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly(
|
||||
"'identifier' expected to match '^abc00$|^abc00-[a-z0-9]+$', but is 'xyz99-temp'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void revampsUnixUser() {
|
||||
// given
|
||||
final var unixUserHostingAsset = GIVEN_VALID_UNIX_USER_HOSTING_ASSET;
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(unixUserHostingAsset.getType());
|
||||
|
||||
// when
|
||||
LinuxEtcShadowHashGenerator.nextSalt("Ly3LbsArtL5u4EVt");
|
||||
final var result = validator.revampProperties(unixUserHostingAsset, unixUserHostingAsset.getConfig());
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrderEntriesOf(ofEntries(
|
||||
entry("SSD hard quota", 50),
|
||||
entry("SSD soft quota", 40),
|
||||
entry("homedir", "/home/pacs/abc00/users/temp")
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
void describesItsProperties() {
|
||||
// given
|
||||
@@ -125,7 +169,7 @@ class HsUnixUserHostingAssetValidatorUnitTest {
|
||||
"{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=password, propertyName=password, minLength=8, maxLength=40, writeOnly=true, hashedUsing=SHA512, undisclosed=true}"
|
||||
"{type=password, propertyName=password, minLength=8, maxLength=40, writeOnly=true, computed=true, hashedUsing=SHA512, undisclosed=true}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -8,8 +8,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static net.hostsharing.hsadminng.hash.HashProcessor.Algorithm.SHA512;
|
||||
import static net.hostsharing.hsadminng.hash.HashProcessor.hashAlgorithm;
|
||||
import static net.hostsharing.hsadminng.hash.LinuxEtcShadowHashGenerator.Algorithm.SHA512;
|
||||
import static net.hostsharing.hsadminng.hash.LinuxEtcShadowHashGenerator.hash;
|
||||
import static net.hostsharing.hsadminng.hs.validation.PasswordProperty.passwordProperty;
|
||||
import static net.hostsharing.hsadminng.mapper.PatchableMapWrapper.entry;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -115,6 +115,6 @@ class PasswordPropertyUnitTest {
|
||||
});
|
||||
|
||||
// then
|
||||
hashAlgorithm(SHA512).withHash(result).verify("some password"); // throws exception if wrong
|
||||
hash("some password").using(SHA512).withRandomSalt().generate(); // throws exception if wrong
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user