From c9e1101035e3ff74957862bda5af55052c85cbe8 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 3 Jul 2024 13:57:39 +0200 Subject: [PATCH] add domain setup validation --- .../hs/hosting/asset/HsHostingAssetType.java | 7 +- .../HsDomainSetupHostingAssetValidator.java | 27 +++++ ...HsHostingAssetEntityValidatorRegistry.java | 1 + .../hs-hosting/hs-hosting-asset-schemas.yaml | 1 + .../7010-hs-hosting-asset.sql | 10 +- .../7018-hs-hosting-asset-test-data.sql | 5 +- .../HsHostingAssetControllerRestTest.java | 18 +++ ...ingAssetPropsControllerAcceptanceTest.java | 3 +- ...ainSetupHostingAssetValidatorUnitTest.java | 111 ++++++++++++++++++ ...gAssetEntityValidatorRegistryUnitTest.java | 3 +- 10 files changed, 176 insertions(+), 10 deletions(-) create mode 100644 src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsDomainSetupHostingAssetValidator.java create mode 100644 src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsDomainSetupHostingAssetValidatorUnitTest.java diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetType.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetType.java index f02a50f0..88ccca45 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetType.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetType.java @@ -6,9 +6,10 @@ public enum HsHostingAssetType { MANAGED_SERVER, // named e.g. vm1234 MANAGED_WEBSPACE(MANAGED_SERVER), // named eg. xyz00 UNIX_USER(MANAGED_WEBSPACE), // named e.g. xyz00-abc - DOMAIN_DNS_SETUP(MANAGED_WEBSPACE), // named e.g. example.org - DOMAIN_HTTP_SETUP(MANAGED_WEBSPACE), // named e.g. example.org - DOMAIN_EMAIL_SETUP(MANAGED_WEBSPACE), // named e.g. example.org + DOMAIN_SETUP, // named e.g. example.org + DOMAIN_DNS_SETUP(DOMAIN_SETUP), // named e.g. example.org + DOMAIN_HTTP_SETUP(DOMAIN_SETUP), // named e.g. example.org + DOMAIN_EMAIL_SETUP(DOMAIN_SETUP), // named e.g. example.org // TODO.spec: SECURE_MX EMAIL_ALIAS(MANAGED_WEBSPACE), // named e.g. xyz00-abc diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsDomainSetupHostingAssetValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsDomainSetupHostingAssetValidator.java new file mode 100644 index 00000000..af671f46 --- /dev/null +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsDomainSetupHostingAssetValidator.java @@ -0,0 +1,27 @@ +package net.hostsharing.hsadminng.hs.hosting.asset.validators; + +import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity; + +import java.util.regex.Pattern; + +class HsDomainSetupHostingAssetValidator extends HsHostingAssetEntityValidator { + + private static final String DOMAIN_NAME_REGEX = "^((?!-)[A-Za-z0-9-]{1,63}(? type, final HsEntityValidator validator) { diff --git a/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml b/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml index 934c9647..a9ab7f64 100644 --- a/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml +++ b/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml @@ -10,6 +10,7 @@ components: - MANAGED_SERVER - MANAGED_WEBSPACE - UNIX_USER + - DOMAIN_SETUP - DOMAIN_DNS_SETUP - DOMAIN_HTTP_SETUP - DOMAIN_EMAIL_SETUP diff --git a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql index bd6ff6e4..eb335238 100644 --- a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql +++ b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql @@ -9,6 +9,7 @@ create type HsHostingAssetType as enum ( 'MANAGED_SERVER', 'MANAGED_WEBSPACE', 'UNIX_USER', + 'DOMAIN_SETUP', 'DOMAIN_DNS_SETUP', 'DOMAIN_HTTP_SETUP', 'DOMAIN_EMAIL_SETUP', @@ -36,7 +37,7 @@ create table if not exists hs_hosting_asset alarmContactUuid uuid null references hs_office_contact(uuid) initially deferred, constraint chk_hs_hosting_asset_has_booking_item_or_parent_asset - check (bookingItemUuid is not null or parentAssetUuid is not null) + check (bookingItemUuid is not null or parentAssetUuid is not null or type='DOMAIN_SETUP') ); --// @@ -63,9 +64,10 @@ begin when 'MANAGED_SERVER' then null when 'MANAGED_WEBSPACE' then 'MANAGED_SERVER' when 'UNIX_USER' then 'MANAGED_WEBSPACE' - when 'DOMAIN_DNS_SETUP' then 'MANAGED_WEBSPACE' - when 'DOMAIN_HTTP_SETUP' then 'MANAGED_WEBSPACE' - when 'DOMAIN_EMAIL_SETUP' then 'MANAGED_WEBSPACE' + when 'DOMAIN_SETUP' then null + when 'DOMAIN_DNS_SETUP' then 'DOMAIN_SETUP' + when 'DOMAIN_HTTP_SETUP' then 'DOMAIN_SETUP' + when 'DOMAIN_EMAIL_SETUP' then 'DOMAIN_SETUP' when 'EMAIL_ALIAS' then 'MANAGED_WEBSPACE' when 'EMAIL_ADDRESS' then 'DOMAIN_EMAIL_SETUP' when 'PGSQL_USER' then 'MANAGED_WEBSPACE' diff --git a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql index 32f2804a..91f9e1dd 100644 --- a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql +++ b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql @@ -23,6 +23,7 @@ declare managedServerUuid uuid; managedWebspaceUuid uuid; webUnixUserUuid uuid; + domainSetupUuid uuid; begin currentTask := 'creating hosting-asset test-data ' || givenProjectCaption; call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN'); @@ -65,6 +66,7 @@ begin select uuid_generate_v4() into managedServerUuid; select uuid_generate_v4() into managedWebspaceUuid; select uuid_generate_v4() into webUnixUserUuid; + select uuid_generate_v4() into domainSetupUuid; debitorNumberSuffix := relatedDebitor.debitorNumberSuffix; defaultPrefix := relatedDebitor.defaultPrefix; @@ -75,7 +77,8 @@ begin (managedWebspaceUuid, relatedManagedWebspaceBookingItem.uuid, 'MANAGED_WEBSPACE', managedServerUuid, null, defaultPrefix || '01', 'some Webspace', '{}'::jsonb), (uuid_generate_v4(), null, 'EMAIL_ALIAS', managedWebspaceUuid, null, defaultPrefix || '01-web', 'some E-Mail-Alias', '{ "target": [ "office@example.org", "archive@example.com" ] }'::jsonb), (webUnixUserUuid, null, 'UNIX_USER', managedWebspaceUuid, null, defaultPrefix || '01-web', 'some UnixUser for Website', '{ "SSD-soft-quota": "128", "SSD-hard-quota": "256", "HDD-soft-quota": "512", "HDD-hard-quota": "1024"}'::jsonb), - (uuid_generate_v4(), null, 'DOMAIN_HTTP_SETUP', managedWebspaceUuid, webUnixUserUuid, defaultPrefix || '.example.org', 'some Domain-HTTP-Setup', '{ "option-htdocsfallback": true, "use-fcgiphpbin": "/usr/lib/cgi-bin/php", "validsubdomainnames": "*"}'::jsonb); + (domainSetupUuid, null, 'DOMAIN_SETUP', null, null, defaultPrefix || '.example.org', 'some Domain-Setup', '{}'::jsonb), + (uuid_generate_v4(), null, 'DOMAIN_HTTP_SETUP', domainSetupUuid, webUnixUserUuid, defaultPrefix || '.example.org', 'some Domain-HTTP-Setup', '{ "option-htdocsfallback": true, "use-fcgiphpbin": "/usr/lib/cgi-bin/php", "validsubdomainnames": "*"}'::jsonb); end; $$; --// diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java index 529d34cd..ef70f2c3 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerRestTest.java @@ -185,6 +185,24 @@ public class HsHostingAssetControllerRestTest { } } ] + """), + DOMAIN_SETUP( + List.of( + HsHostingAssetEntity.builder() + .type(HsHostingAssetType.DOMAIN_SETUP) + .identifier("example.org") + .caption("some fake Domain-Setup") + .build()), + """ + [ + { + "type": "DOMAIN_SETUP", + "identifier": "example.org", + "caption": "some fake Domain-Setup", + "alarmContact": null, + "config": {} + } + ] """); final HsHostingAssetType assetType; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetPropsControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetPropsControllerAcceptanceTest.java index e8323839..1a3d2e0d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetPropsControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetPropsControllerAcceptanceTest.java @@ -35,7 +35,8 @@ class HsHostingAssetPropsControllerAcceptanceTest { "MANAGED_WEBSPACE", "CLOUD_SERVER", "UNIX_USER", - "EMAIL_ALIAS" + "EMAIL_ALIAS", + "DOMAIN_SETUP" ] """)); // @formatter:on diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsDomainSetupHostingAssetValidatorUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsDomainSetupHostingAssetValidatorUnitTest.java new file mode 100644 index 00000000..b7d78567 --- /dev/null +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsDomainSetupHostingAssetValidatorUnitTest.java @@ -0,0 +1,111 @@ +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; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +import java.util.Map; + +import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER; +import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SETUP; +import static org.assertj.core.api.Assertions.assertThat; + +class HsDomainSetupHostingAssetValidatorUnitTest { + + static HsHostingAssetEntityBuilder validEntityBuilder() { + return HsHostingAssetEntity.builder() + .type(DOMAIN_SETUP) + .identifier("example.org"); + } + + enum InvalidDomainNameIdentifier { + EMPTY(""), + TOO_LONG("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456890123456789.de"), + DASH_AT_BEGINNING("-example.com"), + DOT_AT_BEGINNING(".example.com"), + DOT_AT_END("example.com."); + + final String domainName; + + InvalidDomainNameIdentifier(final String domainName) { + this.domainName = domainName; + } + } + + @ParameterizedTest + @EnumSource(InvalidDomainNameIdentifier.class) + void rejectsInvalidIdentifier(final InvalidDomainNameIdentifier testCase) { + // given + final var givenEntity = validEntityBuilder().identifier(testCase.domainName).build(); + final var validator = HsHostingAssetEntityValidatorRegistry.forType(givenEntity.getType()); + + // when + final var result = validator.validateEntity(givenEntity); + + // then + assertThat(result).containsExactly( + "'identifier' expected to match '^((?!-)[A-Za-z0-9-]{1,63}(?