add-postgresql-instance-user-and-database-validation #76
@ -91,8 +91,7 @@ public enum HsHostingAssetType implements Node {
|
||||
|
||||
PGSQL_DATABASE( // named e.g. xyz00_abc
|
||||
inGroup("PostgreSQL"),
|
||||
requiredParent(PGSQL_USER), // thus, the PGSQL_USER_USER:Agent becomes RBAC owner
|
||||
assignedTo(PGSQL_INSTANCE)), // keep in mind: no RBAC grants implied
|
||||
requiredParent(PGSQL_USER)), // thus, the PGSQL_USER_USER:Agent becomes RBAC owner
|
||||
|
||||
MARIADB_INSTANCE( // TODO.spec: identifier to be specified
|
||||
inGroup("MariaDB"),
|
||||
@ -105,8 +104,7 @@ public enum HsHostingAssetType implements Node {
|
||||
|
||||
MARIADB_DATABASE( // named e.g. xyz00_abc
|
||||
inGroup("MariaDB"),
|
||||
requiredParent(MARIADB_USER), // thus, the MARIADB_USER:Agent becomes RBAC owner
|
||||
assignedTo(MARIADB_INSTANCE)),
|
||||
requiredParent(MARIADB_USER)), // thus, the MARIADB_USER:Agent becomes RBAC owner
|
||||
|
||||
IP_NUMBER(
|
||||
inGroup("Server"),
|
||||
|
@ -20,6 +20,6 @@ class HsMariaDbDatabaseHostingAssetValidator extends HostingAssetEntityValidator
|
||||
@Override
|
||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||
final var webspaceIdentifier = assetEntity.getParentAsset().getParentAsset().getIdentifier();
|
||||
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9]+$");
|
||||
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9_]+$");
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,6 @@ class HsMariaDbUserHostingAssetValidator extends HostingAssetEntityValidator {
|
||||
@Override
|
||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||
final var webspaceIdentifier = assetEntity.getParentAsset().getIdentifier();
|
||||
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9]+$");
|
||||
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9_]+$");
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,6 @@ class HsPostgreSqlDatabaseHostingAssetValidator extends HostingAssetEntityValida
|
||||
@Override
|
||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||
final var webspaceIdentifier = assetEntity.getParentAsset().getParentAsset().getIdentifier();
|
||||
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9]+$");
|
||||
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9_]+$");
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,6 @@ class HsPostgreSqlUserHostingAssetValidator extends HostingAssetEntityValidator
|
||||
@Override
|
||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||
final var webspaceIdentifier = assetEntity.getParentAsset().getIdentifier();
|
||||
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9]+$");
|
||||
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9_]+$");
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +132,6 @@ class HsHostingAssetTypeUnitTest {
|
||||
HA_MARIADB_USER *==> HA_MANAGED_WEBSPACE
|
||||
HA_MARIADB_USER o..> HA_MARIADB_INSTANCE
|
||||
HA_MARIADB_DATABASE *==> HA_MARIADB_USER
|
||||
HA_MARIADB_DATABASE o..> HA_MARIADB_INSTANCE
|
||||
HA_IP_NUMBER o..> HA_CLOUD_SERVER
|
||||
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
||||
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
||||
@ -194,7 +193,6 @@ class HsHostingAssetTypeUnitTest {
|
||||
HA_PGSQL_USER *==> HA_MANAGED_WEBSPACE
|
||||
HA_PGSQL_USER o..> HA_PGSQL_INSTANCE
|
||||
HA_PGSQL_DATABASE *==> HA_PGSQL_USER
|
||||
HA_PGSQL_DATABASE o..> HA_PGSQL_INSTANCE
|
||||
HA_IP_NUMBER o..> HA_CLOUD_SERVER
|
||||
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
||||
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
||||
|
@ -40,7 +40,6 @@ class HsMariaDbDatabaseHostingAssetValidatorUnitTest {
|
||||
return HsHostingAssetEntity.builder()
|
||||
.type(MARIADB_DATABASE)
|
||||
.parentAsset(GIVEN_MARIADB_USER)
|
||||
.assignedToAsset(GIVEN_MARIADB_INSTANCE)
|
||||
.identifier("xyz00_temp")
|
||||
.caption("some valid test MariaDB-Database")
|
||||
.config(new HashMap<>(ofEntries(
|
||||
@ -112,6 +111,6 @@ class HsMariaDbDatabaseHostingAssetValidatorUnitTest {
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly(
|
||||
"'identifier' expected to match '^xyz00$|^xyz00_[a-z0-9]+$', but is 'xyz99-temp'");
|
||||
"'identifier' expected to match '^xyz00$|^xyz00_[a-z0-9_]+$', but is 'xyz99-temp'");
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,6 @@ class HsMariaDbUserHostingAssetValidatorUnitTest {
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly(
|
||||
"'identifier' expected to match '^xyz00$|^xyz00_[a-z0-9]+$', but is 'xyz99-temp'");
|
||||
"'identifier' expected to match '^xyz00$|^xyz00_[a-z0-9_]+$', but is 'xyz99-temp'");
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
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.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -40,7 +42,6 @@ class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
|
||||
return HsHostingAssetEntity.builder()
|
||||
.type(PGSQL_DATABASE)
|
||||
.parentAsset(GIVEN_PGSQL_USER)
|
||||
.assignedToAsset(GIVEN_PGSQL_INSTANCE)
|
||||
.identifier("xyz00_temp")
|
||||
.caption("some valid test PgSql-Database")
|
||||
.config(new HashMap<>(ofEntries(
|
||||
@ -78,6 +79,26 @@ class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
|
||||
assertThat(result).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsInvalidReferences() {
|
||||
// given
|
||||
final var givenPgSqlUserHostingAsset = givenValidPgSqlDatabaseBuilder()
|
||||
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
|
||||
.parentAsset(HsHostingAssetEntity.builder().type(PGSQL_INSTANCE).build())
|
||||
.assignedToAsset(HsHostingAssetEntity.builder().type(PGSQL_INSTANCE).build())
|
||||
.build();
|
||||
final var validator = HostingAssetEntityValidatorRegistry.forType(givenPgSqlUserHostingAsset.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validateEntity(givenPgSqlUserHostingAsset);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'PGSQL_DATABASE:xyz00_temp.config.unknown' is not expected but is set to 'wrong'",
|
||||
"'PGSQL_DATABASE:xyz00_temp.config.encoding' is expected to be of type String, but is of type Integer"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsInvalidProperties() {
|
||||
// given
|
||||
@ -112,6 +133,6 @@ class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly(
|
||||
"'identifier' expected to match '^xyz00$|^xyz00_[a-z0-9]+$', but is 'xyz99-temp'");
|
||||
"'identifier' expected to match '^xyz00$|^xyz00_[a-z0-9_]+$', but is 'xyz99-temp'");
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,39 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hash.HashGenerator;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Map.ofEntries;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARIADB_INSTANCE;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARIADB_USER;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.PGSQL_INSTANCE;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.PGSQL_USER;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_SERVER_HOSTING_ASSET;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_WEBSPACE_HOSTING_ASSET;
|
||||
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsMariaPostgreSqlHostingAssetValidatorUnitTest {
|
||||
class HsPostgreSqlUserHostingAssetValidatorUnitTest {
|
||||
|
||||
private static final HsHostingAssetEntity GIVEN_MARIADB_INSTANCE = HsHostingAssetEntity.builder()
|
||||
.type(MARIADB_INSTANCE)
|
||||
private static final HsHostingAssetEntity GIVEN_PGSQL_INSTANCE = HsHostingAssetEntity.builder()
|
||||
.type(PGSQL_INSTANCE)
|
||||
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
|
||||
.identifier("vm1234|MariaDB.default")
|
||||
.caption("some valid test MariaDB-Instance")
|
||||
.identifier("vm1234|PgSql.default")
|
||||
.caption("some valid test PgSql-Instance")
|
||||
.build();
|
||||
|
||||
private static HsHostingAssetEntityBuilder givenValidMariaDbUserBuilder() {
|
||||
return HsHostingAssetEntity.builder()
|
||||
.type(MARIADB_USER)
|
||||
.type(PGSQL_USER)
|
||||
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
|
||||
.assignedToAsset(GIVEN_MARIADB_INSTANCE)
|
||||
.assignedToAsset(GIVEN_PGSQL_INSTANCE)
|
||||
.identifier("xyz00_temp")
|
||||
.caption("some valid test MariaDB-User")
|
||||
.caption("some valid test PgSql-User")
|
||||
.config(new HashMap<>(ofEntries(
|
||||
entry("password", "Test1234")
|
||||
)));
|
||||
@ -46,7 +49,7 @@ class HsMariaPostgreSqlHostingAssetValidatorUnitTest {
|
||||
|
||||
// then
|
||||
assertThat(props).extracting(Object::toString).containsExactlyInAnyOrder(
|
||||
"{type=password, propertyName=password, minLength=8, maxLength=40, writeOnly=true, computed=true, hashedUsing=MYSQL_NATIVE, undisclosed=true}"
|
||||
"{type=password, propertyName=password, minLength=8, maxLength=40, writeOnly=true, computed=true, hashedUsing=SCRAM_SHA256, undisclosed=true}"
|
||||
);
|
||||
}
|
||||
|
||||
@ -57,12 +60,12 @@ class HsMariaPostgreSqlHostingAssetValidatorUnitTest {
|
||||
final var validator = HostingAssetEntityValidatorRegistry.forType(givenMariaDbUserHostingAsset.getType());
|
||||
|
||||
// when
|
||||
// HashGenerator.nextSalt("Ly3LbsArtL5u4EVt"); // not needed for mysql_native_password
|
||||
HashGenerator.nextSalt(new String(Base64.getDecoder().decode("L1QxSVNyTU81b3NZS1djNg=="), Charset.forName("latin1")));
|
||||
validator.prepareProperties(givenMariaDbUserHostingAsset);
|
||||
|
||||
// then
|
||||
assertThat(givenMariaDbUserHostingAsset.getConfig()).containsExactlyInAnyOrderEntriesOf(ofEntries(
|
||||
entry("password", "*14F1A8C42F8B6D4662BB3ED290FD37BF135FE45C")
|
||||
entry("password", "SCRAM-SHA-256$4096:L1QxSVNyTU81b3NZS1djNg==$bB4PEqHpnkoB9FwYfOjh+8yJvLsCnrwxom3TGK0CVJM=:ACRgTfhJwIZLrzhVRbJ3Qif5YhErYWAfkBThvtouW+8=")
|
||||
));
|
||||
}
|
||||
|
||||
@ -98,9 +101,9 @@ class HsMariaPostgreSqlHostingAssetValidatorUnitTest {
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'MARIADB_USER:xyz00_temp.config.unknown' is not expected but is set to '100'",
|
||||
"'MARIADB_USER:xyz00_temp.config.password' length is expected to be at min 8 but length of provided value is 5",
|
||||
"'MARIADB_USER:xyz00_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"
|
||||
"'PGSQL_USER:xyz00_temp.config.unknown' is not expected but is set to '100'",
|
||||
"'PGSQL_USER:xyz00_temp.config.password' length is expected to be at min 8 but length of provided value is 5",
|
||||
"'PGSQL_USER:xyz00_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"
|
||||
);
|
||||
}
|
||||
|
||||
@ -117,6 +120,6 @@ class HsMariaPostgreSqlHostingAssetValidatorUnitTest {
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly(
|
||||
"'identifier' expected to match '^xyz00$|^xyz00_[a-z0-9]+$', but is 'xyz99-temp'");
|
||||
"'identifier' expected to match '^xyz00$|^xyz00_[a-z0-9_]+$', but is 'xyz99-temp'");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user