From 98c1dbe9be1644431bfe7bbb582c3802a9915cab Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Thu, 1 Aug 2024 12:07:47 +0200 Subject: [PATCH] allow /dev/null as alias target and remove single quotes --- .../HsEMailAliasHostingAssetValidator.java | 3 +- ...ailAliasHostingAssetValidatorUnitTest.java | 28 ++++++++++++++----- .../hsadminng/hs/migration/CsvDataImport.java | 2 +- .../hs/migration/ImportHostingAssets.java | 9 ++---- .../migration/hosting/emailalias.csv | 1 + 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidator.java index ab0cb77c..f6c412bb 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidator.java @@ -14,6 +14,7 @@ class HsEMailAliasHostingAssetValidator extends HostingAssetEntityValidator { private static final String EMAIL_ADDRESS_REGEX = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$"; // RFC 5322 private static final String INCLUDE_REGEX = "^:include:/.*$"; private static final String PIPE_REGEX = "^\\|.*$"; + private static final String DEV_NULL_REGEX = "^/dev/null$"; public static final int EMAIL_ADDRESS_MAX_LENGTH = 320; // according to RFC 5321 and RFC 5322 HsEMailAliasHostingAssetValidator() { @@ -21,7 +22,7 @@ class HsEMailAliasHostingAssetValidator extends HostingAssetEntityValidator { AlarmContact.isOptional(), arrayOf( - stringProperty("target").maxLength(EMAIL_ADDRESS_MAX_LENGTH).matchesRegEx(UNIX_USER_REGEX, EMAIL_ADDRESS_REGEX, INCLUDE_REGEX, PIPE_REGEX) + stringProperty("target").maxLength(EMAIL_ADDRESS_MAX_LENGTH).matchesRegEx(UNIX_USER_REGEX, EMAIL_ADDRESS_REGEX, INCLUDE_REGEX, PIPE_REGEX, DEV_NULL_REGEX) ).required().minLength(1)); } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidatorUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidatorUnitTest.java index 9d9422ab..06237102 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidatorUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsEMailAliasHostingAssetValidatorUnitTest.java @@ -22,18 +22,24 @@ class HsEMailAliasHostingAssetValidatorUnitTest { // then assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder( - "{type=string[], propertyName=target, elementsOf={type=string, propertyName=target, matchesRegEx=[^[a-z][a-z0-9]{2}[0-9]{2}(-[a-z0-9][a-z0-9\\._-]*)?$, ^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$, ^:include:/.*$, ^\\|.*$], maxLength=320}, required=true, minLength=1}"); + "{type=string[], propertyName=target, elementsOf={type=string, propertyName=target, matchesRegEx=[^[a-z][a-z0-9]{2}[0-9]{2}(-[a-z0-9][a-z0-9\\._-]*)?$, ^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$, ^:include:/.*$, ^\\|.*$, ^/dev/null$], maxLength=320}, required=true, minLength=1}"); } @Test - void validatesValidEntity() { + void acceptsValidEntity() { // given final var emailAliasHostingAssetEntity = HsHostingAssetEntity.builder() .type(EMAIL_ALIAS) .parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET) .identifier("xyz00-office") .config(Map.ofEntries( - entry("target", Array.of("xyz00", "xyz00-abc", "office@example.com")) + entry("target", Array.of( + "xyz00", + "xyz00-abc", + "office@example.com", + "/dev/null", + "|/home/pacs/xyz00/mailinglists/ecartis -s xyz00-intern" + )) )) .build(); final var validator = HostingAssetEntityValidatorRegistry.forType(emailAliasHostingAssetEntity.getType()); @@ -46,14 +52,22 @@ class HsEMailAliasHostingAssetValidatorUnitTest { } @Test - void validatesProperties() { + void rejectsInvalidConfig() { // given final var emailAliasHostingAssetEntity = HsHostingAssetEntity.builder() .type(EMAIL_ALIAS) .parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET) .identifier("xyz00-office") .config(Map.ofEntries( - entry("target", Array.of("xyz00", "xyz00-abc", "garbage", "office@example.com")) + entry("target", Array.of( + "/dev/null", + "xyz00", + "xyz00-abc", + "garbage", + "office@example.com", + ":include:/home/pacs/xyz00/mailinglists/textfile", + "|/home/pacs/xyz00/mailinglists/executable" + )) )) .build(); final var validator = HostingAssetEntityValidatorRegistry.forType(emailAliasHostingAssetEntity.getType()); @@ -63,11 +77,11 @@ class HsEMailAliasHostingAssetValidatorUnitTest { // then assertThat(result).containsExactlyInAnyOrder( - "'EMAIL_ALIAS:xyz00-office.config.target' is expected to match any of [^[a-z][a-z0-9]{2}[0-9]{2}(-[a-z0-9][a-z0-9\\._-]*)?$, ^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$, ^:include:/.*$, ^\\|.*$] but 'garbage' does not match any"); + "'EMAIL_ALIAS:xyz00-office.config.target' is expected to match any of [^[a-z][a-z0-9]{2}[0-9]{2}(-[a-z0-9][a-z0-9\\._-]*)?$, ^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$, ^:include:/.*$, ^\\|.*$, ^/dev/null$] but 'garbage' does not match any"); } @Test - void validatesInvalidIdentifier() { + void rejectsInvalidIndentifier() { // given final var emailAliasHostingAssetEntity = HsHostingAssetEntity.builder() .type(EMAIL_ALIAS) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java index e1dd13c5..6405d543 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java @@ -126,11 +126,11 @@ public class CsvDataImport extends ContextBasedTest { try (final var reader = new CSVReader(new StringReader(csvLine))) { return stream(ofNullable(reader.readNext()).orElse(emptyArray(String.class))) .map(String::trim) + .map(target -> target.startsWith("'") && target.endsWith("'") ? target.substring(1, target.length()-1) : target) .toArray(String[]::new); } } - String[] trimAll(final String[] record) { for (int i = 0; i < record.length; ++i) { if (record[i] != null) { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java index 3d03ab3a..3092dd85 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/ImportHostingAssets.java @@ -327,7 +327,8 @@ public class ImportHostingAssets extends ImportOfficeData { 5002452=HsHostingAssetRawEntity(EMAIL_ALIAS, mim00-empty, mim00-empty, MANAGED_WEBSPACE:mim00, { "target": "[]"}), 5002453=HsHostingAssetRawEntity(EMAIL_ALIAS, mim00-0_entries, mim00-0_entries, MANAGED_WEBSPACE:mim00, { "target": "[]"}), 5002454=HsHostingAssetRawEntity(EMAIL_ALIAS, mim00-dev.null, mim00-dev.null, MANAGED_WEBSPACE:mim00, { "target": "[/dev/null]"}), - 5002455=HsHostingAssetRawEntity(EMAIL_ALIAS, mim00-1_with_space, mim00-1_with_space, MANAGED_WEBSPACE:mim00, { "target": "[|/home/pacs/mim00/install/corpslistar/listar]"}) + 5002455=HsHostingAssetRawEntity(EMAIL_ALIAS, mim00-1_with_space, mim00-1_with_space, MANAGED_WEBSPACE:mim00, { "target": "[|/home/pacs/mim00/install/corpslistar/listar]"}), + 5002456=HsHostingAssetRawEntity(EMAIL_ALIAS, mim00-1_with_single_quotes, mim00-1_with_single_quotes, MANAGED_WEBSPACE:mim00, { "target": "[|/home/pacs/rir00/mailinglist/ecartis -r kybs06-intern]"}) } """); } @@ -500,11 +501,7 @@ public class ImportHostingAssets extends ImportOfficeData { validation failed for id:5002453( HsHostingAssetRawEntity(EMAIL_ALIAS, mim00-0_entries, mim00-0_entries, MANAGED_WEBSPACE:mim00, { "target": "[]" } - )): ['EMAIL_ALIAS:mim00-0_entries.config.target' length is expected to be at min 1 but length of [[]] is 0]""", - """ - validation failed for id:5002454( HsHostingAssetRawEntity(EMAIL_ALIAS, mim00-dev.null, mim00-dev.null, MANAGED_WEBSPACE:mim00, { - "target": "[/dev/null]" - })): ['EMAIL_ALIAS:mim00-dev.null.config.target' is expected to match any of [^[a-z][a-z0-9]{2}[0-9]{2}(-[a-z0-9][a-z0-9\\._-]*)?$,^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$,^:include:/.*$,^\\|.*$] but '/dev/null' does not match any]""" + )): ['EMAIL_ALIAS:mim00-0_entries.config.target' length is expected to be at min 1 but length of [[]] is 0]""" ); } else { super.logErrors(); diff --git a/src/test/resources/migration/hosting/emailalias.csv b/src/test/resources/migration/hosting/emailalias.csv index 7d5cd887..6b007ce3 100644 --- a/src/test/resources/migration/hosting/emailalias.csv +++ b/src/test/resources/migration/hosting/emailalias.csv @@ -9,3 +9,4 @@ emailalias_id;pac_id;name;target 2453;1112;mim00-0_entries;"" 2454;1112;mim00-dev.null; /dev/null 2455;1112;mim00-1_with_space;" ""|/home/pacs/mim00/install/corpslistar/listar""" +2456;1112;mim00-1_with_single_quotes;'|/home/pacs/rir00/mailinglist/ecartis -r kybs06-intern'