add-postgresql-instance-user-and-database-validation #76
@ -91,8 +91,7 @@ public enum HsHostingAssetType implements Node {
|
|||||||
|
|
||||||
PGSQL_DATABASE( // named e.g. xyz00_abc
|
PGSQL_DATABASE( // named e.g. xyz00_abc
|
||||||
inGroup("PostgreSQL"),
|
inGroup("PostgreSQL"),
|
||||||
requiredParent(PGSQL_USER), // thus, the PGSQL_USER_USER:Agent becomes RBAC owner
|
requiredParent(PGSQL_USER)), // thus, the PGSQL_USER_USER:Agent becomes RBAC owner
|
||||||
assignedTo(PGSQL_INSTANCE)), // keep in mind: no RBAC grants implied
|
|
||||||
|
|
||||||
hsh-michaelhoennig marked this conversation as resolved
Outdated
|
|||||||
MARIADB_INSTANCE( // TODO.spec: identifier to be specified
|
MARIADB_INSTANCE( // TODO.spec: identifier to be specified
|
||||||
inGroup("MariaDB"),
|
inGroup("MariaDB"),
|
||||||
@ -105,8 +104,7 @@ public enum HsHostingAssetType implements Node {
|
|||||||
|
|
||||||
MARIADB_DATABASE( // named e.g. xyz00_abc
|
MARIADB_DATABASE( // named e.g. xyz00_abc
|
||||||
inGroup("MariaDB"),
|
inGroup("MariaDB"),
|
||||||
requiredParent(MARIADB_USER), // thus, the MARIADB_USER:Agent becomes RBAC owner
|
requiredParent(MARIADB_USER)), // thus, the MARIADB_USER:Agent becomes RBAC owner
|
||||||
assignedTo(MARIADB_INSTANCE)),
|
|
||||||
|
|
||||||
IP_NUMBER(
|
IP_NUMBER(
|
||||||
inGroup("Server"),
|
inGroup("Server"),
|
||||||
|
@ -20,6 +20,6 @@ class HsMariaDbDatabaseHostingAssetValidator extends HostingAssetEntityValidator
|
|||||||
@Override
|
@Override
|
||||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||||
final var webspaceIdentifier = assetEntity.getParentAsset().getParentAsset().getIdentifier();
|
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
|
@Override
|
||||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||||
final var webspaceIdentifier = assetEntity.getParentAsset().getIdentifier();
|
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
|
@Override
|
||||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||||
final var webspaceIdentifier = assetEntity.getParentAsset().getParentAsset().getIdentifier();
|
final var webspaceIdentifier = assetEntity.getParentAsset().getParentAsset().getIdentifier();
|
||||||
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9]+$");
|
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9_]+$");
|
||||||
hsh-michaelhoennig marked this conversation as resolved
Outdated
hsh-marcsandlus
commented
underscore auch möglich underscore auch möglich
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,6 @@ class HsPostgreSqlUserHostingAssetValidator extends HostingAssetEntityValidator
|
|||||||
@Override
|
@Override
|
||||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||||
final var webspaceIdentifier = assetEntity.getParentAsset().getIdentifier();
|
final var webspaceIdentifier = assetEntity.getParentAsset().getIdentifier();
|
||||||
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9]+$");
|
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"_[a-z0-9_]+$");
|
||||||
hsh-michaelhoennig marked this conversation as resolved
Outdated
hsh-marcsandlus
commented
underscore underscore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,6 @@ class HsHostingAssetTypeUnitTest {
|
|||||||
HA_MARIADB_USER *==> HA_MANAGED_WEBSPACE
|
HA_MARIADB_USER *==> HA_MANAGED_WEBSPACE
|
||||||
HA_MARIADB_USER o..> HA_MARIADB_INSTANCE
|
HA_MARIADB_USER o..> HA_MARIADB_INSTANCE
|
||||||
HA_MARIADB_DATABASE *==> HA_MARIADB_USER
|
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_CLOUD_SERVER
|
||||||
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
||||||
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
||||||
@ -194,7 +193,6 @@ class HsHostingAssetTypeUnitTest {
|
|||||||
HA_PGSQL_USER *==> HA_MANAGED_WEBSPACE
|
HA_PGSQL_USER *==> HA_MANAGED_WEBSPACE
|
||||||
HA_PGSQL_USER o..> HA_PGSQL_INSTANCE
|
HA_PGSQL_USER o..> HA_PGSQL_INSTANCE
|
||||||
HA_PGSQL_DATABASE *==> HA_PGSQL_USER
|
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_CLOUD_SERVER
|
||||||
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
HA_IP_NUMBER o..> HA_MANAGED_SERVER
|
||||||
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
HA_IP_NUMBER o..> HA_MANAGED_WEBSPACE
|
||||||
|
@ -40,7 +40,6 @@ class HsMariaDbDatabaseHostingAssetValidatorUnitTest {
|
|||||||
return HsHostingAssetEntity.builder()
|
return HsHostingAssetEntity.builder()
|
||||||
.type(MARIADB_DATABASE)
|
.type(MARIADB_DATABASE)
|
||||||
.parentAsset(GIVEN_MARIADB_USER)
|
.parentAsset(GIVEN_MARIADB_USER)
|
||||||
.assignedToAsset(GIVEN_MARIADB_INSTANCE)
|
|
||||||
.identifier("xyz00_temp")
|
.identifier("xyz00_temp")
|
||||||
.caption("some valid test MariaDB-Database")
|
.caption("some valid test MariaDB-Database")
|
||||||
.config(new HashMap<>(ofEntries(
|
.config(new HashMap<>(ofEntries(
|
||||||
@ -112,6 +111,6 @@ class HsMariaDbDatabaseHostingAssetValidatorUnitTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).containsExactly(
|
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
|
// then
|
||||||
assertThat(result).containsExactly(
|
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;
|
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;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -40,7 +42,6 @@ class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
|
|||||||
return HsHostingAssetEntity.builder()
|
return HsHostingAssetEntity.builder()
|
||||||
.type(PGSQL_DATABASE)
|
.type(PGSQL_DATABASE)
|
||||||
.parentAsset(GIVEN_PGSQL_USER)
|
.parentAsset(GIVEN_PGSQL_USER)
|
||||||
.assignedToAsset(GIVEN_PGSQL_INSTANCE)
|
|
||||||
.identifier("xyz00_temp")
|
.identifier("xyz00_temp")
|
||||||
.caption("some valid test PgSql-Database")
|
.caption("some valid test PgSql-Database")
|
||||||
.config(new HashMap<>(ofEntries(
|
.config(new HashMap<>(ofEntries(
|
||||||
@ -78,6 +79,26 @@ class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
|
|||||||
assertThat(result).isEmpty();
|
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
|
@Test
|
||||||
void rejectsInvalidProperties() {
|
void rejectsInvalidProperties() {
|
||||||
// given
|
// given
|
||||||
@ -112,6 +133,6 @@ class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).containsExactly(
|
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;
|
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;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static java.util.Map.ofEntries;
|
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.PGSQL_INSTANCE;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARIADB_USER;
|
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_SERVER_HOSTING_ASSET;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_WEBSPACE_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 net.hostsharing.hsadminng.mapper.PatchMap.entry;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
class HsMariaPostgreSqlHostingAssetValidatorUnitTest {
|
class HsPostgreSqlUserHostingAssetValidatorUnitTest {
|
||||||
|
|
||||||
private static final HsHostingAssetEntity GIVEN_MARIADB_INSTANCE = HsHostingAssetEntity.builder()
|
private static final HsHostingAssetEntity GIVEN_PGSQL_INSTANCE = HsHostingAssetEntity.builder()
|
||||||
.type(MARIADB_INSTANCE)
|
.type(PGSQL_INSTANCE)
|
||||||
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
|
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
|
||||||
.identifier("vm1234|MariaDB.default")
|
.identifier("vm1234|PgSql.default")
|
||||||
.caption("some valid test MariaDB-Instance")
|
.caption("some valid test PgSql-Instance")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
private static HsHostingAssetEntityBuilder givenValidMariaDbUserBuilder() {
|
private static HsHostingAssetEntityBuilder givenValidMariaDbUserBuilder() {
|
||||||
return HsHostingAssetEntity.builder()
|
return HsHostingAssetEntity.builder()
|
||||||
.type(MARIADB_USER)
|
.type(PGSQL_USER)
|
||||||
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
|
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
|
||||||
.assignedToAsset(GIVEN_MARIADB_INSTANCE)
|
.assignedToAsset(GIVEN_PGSQL_INSTANCE)
|
||||||
.identifier("xyz00_temp")
|
.identifier("xyz00_temp")
|
||||||
.caption("some valid test MariaDB-User")
|
.caption("some valid test PgSql-User")
|
||||||
.config(new HashMap<>(ofEntries(
|
.config(new HashMap<>(ofEntries(
|
||||||
entry("password", "Test1234")
|
entry("password", "Test1234")
|
||||||
)));
|
)));
|
||||||
@ -46,7 +49,7 @@ class HsMariaPostgreSqlHostingAssetValidatorUnitTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(props).extracting(Object::toString).containsExactlyInAnyOrder(
|
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());
|
final var validator = HostingAssetEntityValidatorRegistry.forType(givenMariaDbUserHostingAsset.getType());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
// HashGenerator.nextSalt("Ly3LbsArtL5u4EVt"); // not needed for mysql_native_password
|
HashGenerator.nextSalt(new String(Base64.getDecoder().decode("L1QxSVNyTU81b3NZS1djNg=="), Charset.forName("latin1")));
|
||||||
validator.prepareProperties(givenMariaDbUserHostingAsset);
|
validator.prepareProperties(givenMariaDbUserHostingAsset);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(givenMariaDbUserHostingAsset.getConfig()).containsExactlyInAnyOrderEntriesOf(ofEntries(
|
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
|
// then
|
||||||
assertThat(result).containsExactlyInAnyOrder(
|
assertThat(result).containsExactlyInAnyOrder(
|
||||||
"'MARIADB_USER:xyz00_temp.config.unknown' is not expected but is set to '100'",
|
"'PGSQL_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",
|
"'PGSQL_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.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
|
// then
|
||||||
assertThat(result).containsExactly(
|
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
evtl. rausnehmen, erreichbar über user