diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAsset.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAsset.java index 53e3f992..abe56085 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAsset.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAsset.java @@ -34,6 +34,7 @@ import jakarta.persistence.OneToOne; import jakarta.persistence.PostLoad; import jakarta.persistence.Transient; import jakarta.persistence.Version; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -115,6 +116,13 @@ public abstract class HsHostingAsset implements Stringifyable, BaseEntity getSubHostingAssets() { + if (subHostingAssets == null) { + subHostingAssets = new ArrayList<>(); + } + return subHostingAssets; + } + public PatchableMapWrapper getConfig() { return PatchableMapWrapper.of(configWrapper, (newWrapper) -> {configWrapper = newWrapper;}, config); } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HostingAssetEntitySaveProcessor.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HostingAssetEntitySaveProcessor.java index c5951f45..09628919 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HostingAssetEntitySaveProcessor.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HostingAssetEntitySaveProcessor.java @@ -66,6 +66,8 @@ public class HostingAssetEntitySaveProcessor { public HostingAssetEntitySaveProcessor saveUsing(final Function saveFunction) { step("saveUsing", "validateContext"); entity = saveFunction.apply(entity); + em.flush(); // makes RbacEntity available as RealEntity if needed + validator.postPersist(em, entity); return this; } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedWebspaceHostingAssetValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedWebspaceHostingAssetValidator.java index dc0ece36..ca10ee7c 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedWebspaceHostingAssetValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedWebspaceHostingAssetValidator.java @@ -1,10 +1,13 @@ package net.hostsharing.hsadminng.hs.hosting.asset.validators; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset; +import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity; +import jakarta.persistence.EntityManager; import java.util.regex.Pattern; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE; +import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX_USER; class HsManagedWebspaceHostingAssetValidator extends HostingAssetEntityValidator { public HsManagedWebspaceHostingAssetValidator() { @@ -22,4 +25,32 @@ class HsManagedWebspaceHostingAssetValidator extends HostingAssetEntityValidator : "[a-z][a-z0-9][a-z0-9]"; return Pattern.compile("^" + prefixPattern + "[0-9][0-9]$"); } + + @Override + public void postPersist(final EntityManager em, final HsHostingAsset webspaceAsset) { + if (!webspaceAsset.isLoaded()) { + final var unixUserAsset = HsHostingAssetRealEntity.builder() + .type(UNIX_USER) + .parentAsset(em.find(HsHostingAssetRealEntity.class, webspaceAsset.getUuid())) + .identifier(webspaceAsset.getIdentifier()) + .caption(webspaceAsset.getIdentifier() + " webspace user") + .build(); + webspaceAsset.getSubHostingAssets().add(unixUserAsset); + final var emw = new EntityManagerWrapper(em); + new HostingAssetEntitySaveProcessor(em, unixUserAsset) + .preprocessEntity() + .validateEntity() + .prepareForSave() + .saveUsing(emw::persist) + .validateContext(); + } + } +} + +record EntityManagerWrapper(EntityManager em) { + + HsHostingAsset persist(HsHostingAsset hsHostingAsset) { + em.persist(hsHostingAsset); + return hsHostingAsset; + } } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java index ce353a7d..b2fa8a02 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/validation/HsEntityValidator.java @@ -160,4 +160,7 @@ public abstract class HsEntityValidator { public ValidatableProperty getProperty(final String propertyName) { return stream(propertyValidators).filter(pv -> pv.propertyName().equals(propertyName)).findFirst().orElse(null); } + + public void postPersist(final EntityManager em, final E entity) { + } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerAcceptanceTest.java index 9f689591..9647166b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerAcceptanceTest.java @@ -182,11 +182,23 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup .header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*")) .extract().header("Location"); // @formatter:on - // finally, the new asset can be accessed under the generated UUID - final var newWebspace = UUID.fromString( + // the new asset can be accessed under the generated UUID + final var newWebspaceUuid = UUID.fromString( location.substring(location.lastIndexOf('/') + 1)); - assertThat(newWebspace).isNotNull(); - toCleanup(HsHostingAssetRbacEntity.class, newWebspace); + assertThat(newWebspaceUuid).isNotNull(); + toCleanup(HsHostingAssetRbacEntity.class, newWebspaceUuid); + + // and a default user got created + final var webspaceUnixUser = em.createQuery("SELECT ha FROM HsHostingAssetRealEntity ha WHERE ha.parentAsset.uuid=:webspaceUUID") + .setParameter("webspaceUUID", newWebspaceUuid) + .getSingleResult(); + assertThat(webspaceUnixUser).isNotNull().extracting(Object::toString) + .isEqualTo(""" + HsHostingAsset(UNIX_USER, fir10, fir10 webspace user, MANAGED_WEBSPACE:fir10, { + "password" : null, + "userid" : 1000000 + }) + """.trim()); } @Test @@ -325,7 +337,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup jpaAttempt.transacted(() -> { context.define("superuser-alex@hostsharing.net"); - for (int n = 0; n < UNIX_USER_PER_MULTI_OPTION -preExistingUnixUserCount+1; ++n) { + for (int n = 0; n < UNIX_USER_PER_MULTI_OPTION-preExistingUnixUserCount; ++n) { toCleanup(realAssetRepo.save( HsHostingAssetRealEntity.builder() .type(UNIX_USER)