fix RBAC-generation (naming problem)

This commit is contained in:
Michael Hoennig 2024-08-04 13:18:45 +02:00
parent d179842730
commit 33166197a4
45 changed files with 150 additions and 131 deletions

View File

@ -121,8 +121,8 @@ WITH statements AS (
SELECT * FROM pg_stat_statements pss SELECT * FROM pg_stat_statements pss
) )
SELECT calls, SELECT calls,
total_exec_time::int/(60*1000) as total_exec_time_mins, total_exec_time::int/(60*1000) as total_mins,
mean_exec_time::int as mean_exec_time_millis, mean_exec_time::int as mean_millis,
query query
FROM statements FROM statements
WHERE calls > 100 AND shared_blks_hit > 0 WHERE calls > 100 AND shared_blks_hit > 0

View File

@ -15,7 +15,7 @@ import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper; import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
@ -71,7 +71,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class HsBookingItemEntity implements Stringifyable, RbacObject<HsBookingItemEntity>, PropertiesProvider { public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingItemEntity>, PropertiesProvider {
private static Stringify<HsBookingItemEntity> stringify = stringify(HsBookingItemEntity.class) private static Stringify<HsBookingItemEntity> stringify = stringify(HsBookingItemEntity.class)
.withProp(HsBookingItemEntity::getProject) .withProp(HsBookingItemEntity::getProject)

View File

@ -3,10 +3,10 @@ package net.hostsharing.hsadminng.hs.booking.project;
import lombok.*; import lombok.*;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity; import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
@ -34,7 +34,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class HsBookingProjectEntity implements Stringifyable, RbacObject<HsBookingProjectEntity> { public class HsBookingProjectEntity implements Stringifyable, BaseEntity<HsBookingProjectEntity> {
private static Stringify<HsBookingProjectEntity> stringify = stringify(HsBookingProjectEntity.class) private static Stringify<HsBookingProjectEntity> stringify = stringify(HsBookingProjectEntity.class)
.withProp(HsBookingProjectEntity::getDebitor) .withProp(HsBookingProjectEntity::getDebitor)
@ -81,7 +81,7 @@ public class HsBookingProjectEntity implements Stringifyable, RbacObject<HsBooki
directlyFetchedByDependsOnColumn(), directlyFetchedByDependsOnColumn(),
NOT_NULL) NOT_NULL)
.importEntityAlias("debitorRel", HsOfficeRelation.class, usingCase(DEBITOR), .importEntityAlias("debitorRel", HsOfficeRelationRbacEntity.class, usingCase(DEBITOR),
dependsOnColumn("debitorUuid"), dependsOnColumn("debitorUuid"),
fetchedBySql(""" fetchedBySql("""
SELECT ${columns} SELECT ${columns}

View File

@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity; import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactBareEntity; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactBareEntity;
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider; import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
@ -16,7 +16,7 @@ import java.util.UUID;
import static java.util.Collections.emptyMap; import static java.util.Collections.emptyMap;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify; import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
public interface HsHostingAsset extends Stringifyable, RbacObject<HsHostingAsset>, PropertiesProvider { public interface HsHostingAsset extends Stringifyable, BaseEntity<HsHostingAsset>, PropertiesProvider {
Stringify<HsHostingAsset> stringify = stringify(HsHostingAsset.class) Stringify<HsHostingAsset> stringify = stringify(HsHostingAsset.class)
.withProp(HsHostingAsset::getType) .withProp(HsHostingAsset::getType)

View File

@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.bankaccount;
import lombok.*; import lombok.*;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@AllArgsConstructor @AllArgsConstructor
@FieldNameConstants @FieldNameConstants
@DisplayName("BankAccount") @DisplayName("BankAccount")
public class HsOfficeBankAccountEntity implements RbacObject<HsOfficeBankAccountEntity>, Stringifyable { public class HsOfficeBankAccountEntity implements BaseEntity<HsOfficeBankAccountEntity>, Stringifyable {
private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount") private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount")
.withIdProp(HsOfficeBankAccountEntity::getIban) .withIdProp(HsOfficeBankAccountEntity::getIban)

View File

@ -11,7 +11,7 @@ import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper; import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
@ -37,7 +37,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@SuperBuilder(toBuilder = true) @SuperBuilder(toBuilder = true)
@FieldNameConstants @FieldNameConstants
@DisplayName("Contact") @DisplayName("Contact")
public class HsOfficeContact implements Stringifyable, RbacObject<HsOfficeContact> { public class HsOfficeContact implements Stringifyable, BaseEntity<HsOfficeContact> {
private static Stringify<HsOfficeContact> toString = stringify(HsOfficeContact.class, "contact") private static Stringify<HsOfficeContact> toString = stringify(HsOfficeContact.class, "contact")
.withProp(Fields.caption, HsOfficeContact::getCaption) .withProp(Fields.caption, HsOfficeContact::getCaption)

View File

@ -16,7 +16,6 @@ import jakarta.persistence.Table;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@SuperBuilder(toBuilder = true) @SuperBuilder(toBuilder = true)
@FieldNameConstants
@DisplayName("BareContact") @DisplayName("BareContact")
public class HsOfficeContactBareEntity extends HsOfficeContact { public class HsOfficeContactBareEntity extends HsOfficeContact {

View File

@ -22,11 +22,9 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@SuperBuilder(toBuilder = true) @SuperBuilder(toBuilder = true)
@FieldNameConstants
@DisplayName("RbacContact") @DisplayName("RbacContact")
public class HsOfficeContactRbacEntity extends HsOfficeContact { public class HsOfficeContactRbacEntity extends HsOfficeContact {
public static RbacView rbac() { public static RbacView rbac() {
return rbacViewFor("contact", HsOfficeContactRbacEntity.class) return rbacViewFor("contact", HsOfficeContactRbacEntity.class)
.withIdentityView(SQL.projection("caption")) .withIdentityView(SQL.projection("caption"))

View File

@ -8,7 +8,7 @@ import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
@ -41,7 +41,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("CoopAssetsTransaction") @DisplayName("CoopAssetsTransaction")
public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, RbacObject<HsOfficeCoopAssetsTransactionEntity> { public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseEntity<HsOfficeCoopAssetsTransactionEntity> {
private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class) private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class)
.withIdProp(HsOfficeCoopAssetsTransactionEntity::getTaggedMemberNumber) .withIdProp(HsOfficeCoopAssetsTransactionEntity::getTaggedMemberNumber)
@ -107,7 +107,7 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, RbacO
@Override @Override
public HsOfficeCoopAssetsTransactionEntity load() { public HsOfficeCoopAssetsTransactionEntity load() {
RbacObject.super.load(); BaseEntity.super.load();
membership.load(); membership.load();
return this; return this;
} }

View File

@ -8,7 +8,7 @@ import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity; import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
@ -39,7 +39,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("CoopShareTransaction") @DisplayName("CoopShareTransaction")
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, RbacObject<HsOfficeCoopSharesTransactionEntity> { public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, BaseEntity<HsOfficeCoopSharesTransactionEntity> {
private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class) private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class)
.withIdProp(HsOfficeCoopSharesTransactionEntity::getMemberNumberTagged) .withIdProp(HsOfficeCoopSharesTransactionEntity::getMemberNumberTagged)
@ -104,7 +104,7 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, RbacO
@Override @Override
public HsOfficeCoopSharesTransactionEntity load() { public HsOfficeCoopSharesTransactionEntity load() {
RbacObject.super.load(); BaseEntity.super.load();
membership.load(); membership.load();
return this; return this;
} }

View File

@ -6,6 +6,7 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebito
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareRepository;
import net.hostsharing.hsadminng.mapper.Mapper; import net.hostsharing.hsadminng.mapper.Mapper;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
@ -82,7 +83,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class); final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class);
if ( body.getDebitorRel() != null ) { if ( body.getDebitorRel() != null ) {
body.getDebitorRel().setType(DEBITOR.name()); body.getDebitorRel().setType(DEBITOR.name());
final var debitorRel = mapper.map(body.getDebitorRel(), HsOfficeRelation.class); final var debitorRel = mapper.map(body.getDebitorRel(), HsOfficeRelationBareEntity.class);
entityToSave.setDebitorRel(relBareRepo.save(debitorRel)); entityToSave.setDebitorRel(relBareRepo.save(debitorRel));
} else { } else {
final var debitorRelOptional = relBareRepo.findByUuid(body.getDebitorRelUuid()); final var debitorRelOptional = relBareRepo.findByUuid(body.getDebitorRelUuid());

View File

@ -10,7 +10,8 @@ import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
@ -59,7 +60,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("Debitor") @DisplayName("Debitor")
public class HsOfficeDebitorEntity implements RbacObject<HsOfficeDebitorEntity>, Stringifyable { public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>, Stringifyable {
public static final String DEBITOR_NUMBER_TAG = "D-"; public static final String DEBITOR_NUMBER_TAG = "D-";
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$"; public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
@ -129,7 +130,7 @@ public class HsOfficeDebitorEntity implements RbacObject<HsOfficeDebitorEntity>,
@Override @Override
public HsOfficeDebitorEntity load() { public HsOfficeDebitorEntity load() {
RbacObject.super.load(); BaseEntity.super.load();
if (partner != null) { if (partner != null) {
partner.load(); partner.load();
} }
@ -189,7 +190,7 @@ public class HsOfficeDebitorEntity implements RbacObject<HsOfficeDebitorEntity>,
"defaultPrefix") "defaultPrefix")
.toRole("global", ADMIN).grantPermission(INSERT) .toRole("global", ADMIN).grantPermission(INSERT)
.importRootEntityAliasProxy("debitorRel", HsOfficeRelation.class, usingCase(DEBITOR), .importRootEntityAliasProxy("debitorRel", HsOfficeRelationRbacEntity.class, usingCase(DEBITOR),
directlyFetchedByDependsOnColumn(), directlyFetchedByDependsOnColumn(),
dependsOnColumn("debitorRelUuid")) dependsOnColumn("debitorRelUuid"))
.createPermission(DELETE).grantedTo("debitorRel", OWNER) .createPermission(DELETE).grantedTo("debitorRel", OWNER)
@ -203,7 +204,7 @@ public class HsOfficeDebitorEntity implements RbacObject<HsOfficeDebitorEntity>,
.toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT) .toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT)
.toRole("debitorRel", AGENT).grantRole("refundBankAccount", REFERRER) .toRole("debitorRel", AGENT).grantRole("refundBankAccount", REFERRER)
.importEntityAlias("partnerRel", HsOfficeRelation.class, usingDefaultCase(), .importEntityAlias("partnerRel", HsOfficeRelationRbacEntity.class, usingDefaultCase(),
dependsOnColumn("debitorRelUuid"), dependsOnColumn("debitorRelUuid"),
fetchedBySql(""" fetchedBySql("""
SELECT ${columns} SELECT ${columns}

View File

@ -8,8 +8,8 @@ import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity; import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
@ -62,7 +62,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("Membership") @DisplayName("Membership")
public class HsOfficeMembershipEntity implements RbacObject<HsOfficeMembershipEntity>, Stringifyable { public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEntity>, Stringifyable {
public static final String MEMBER_NUMBER_TAG = "M-"; public static final String MEMBER_NUMBER_TAG = "M-";
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$"; public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
@ -102,7 +102,7 @@ public class HsOfficeMembershipEntity implements RbacObject<HsOfficeMembershipEn
@Override @Override
public HsOfficeMembershipEntity load() { public HsOfficeMembershipEntity load() {
RbacObject.super.load(); BaseEntity.super.load();
partner.load(); partner.load();
return this; return this;
} }
@ -165,7 +165,7 @@ public class HsOfficeMembershipEntity implements RbacObject<HsOfficeMembershipEn
.withRestrictedViewOrderBy(SQL.projection("validity")) .withRestrictedViewOrderBy(SQL.projection("validity"))
.withUpdatableColumns("validity", "membershipFeeBillable", "status") .withUpdatableColumns("validity", "membershipFeeBillable", "status")
.importEntityAlias("partnerRel", HsOfficeRelation.class, usingDefaultCase(), .importEntityAlias("partnerRel", HsOfficeRelationRbacEntity.class, usingDefaultCase(),
dependsOnColumn("partnerUuid"), dependsOnColumn("partnerUuid"),
fetchedBySql(""" fetchedBySql("""
SELECT ${columns} SELECT ${columns}

View File

@ -14,7 +14,7 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareRepository; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareRepository;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
import net.hostsharing.hsadminng.mapper.Mapper; import net.hostsharing.hsadminng.mapper.Mapper;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -142,7 +142,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
return ResponseEntity.ok(mapped); return ResponseEntity.ok(mapped);
} }
private void optionallyCreateExPartnerRelation(final HsOfficePartnerEntity saved, final HsOfficeRelation previousPartnerRel) { private void optionallyCreateExPartnerRelation(final HsOfficePartnerEntity saved, final HsOfficeRelationBareEntity previousPartnerRel) {
if (!saved.getPartnerRel().getUuid().equals(previousPartnerRel.getUuid())) { if (!saved.getPartnerRel().getUuid().equals(previousPartnerRel.getUuid())) {
relationRepo.save(previousPartnerRel.toBuilder().uuid(null).type(EX_PARTNER).build()); relationRepo.save(previousPartnerRel.toBuilder().uuid(null).type(EX_PARTNER).build());
} }
@ -166,7 +166,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
return entity; return entity;
} }
private <E extends RbacObject> E ref(final Class<E> entityClass, final UUID uuid) { private <E extends BaseEntity> E ref(final Class<E> entityClass, final UUID uuid) {
try { try {
return em.getReference(entityClass, uuid); return em.getReference(entityClass, uuid);
} catch (final Throwable exc) { } catch (final Throwable exc) {

View File

@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
import lombok.*; import lombok.*;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
@ -26,7 +26,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("PartnerDetails") @DisplayName("PartnerDetails")
public class HsOfficePartnerDetailsEntity implements RbacObject<HsOfficePartnerDetailsEntity>, Stringifyable { public class HsOfficePartnerDetailsEntity implements BaseEntity<HsOfficePartnerDetailsEntity>, Stringifyable {
private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify( private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify(
HsOfficePartnerDetailsEntity.class, HsOfficePartnerDetailsEntity.class,

View File

@ -9,7 +9,8 @@ import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
@ -41,7 +42,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("Partner") @DisplayName("Partner")
public class HsOfficePartnerEntity implements Stringifyable, RbacObject<HsOfficePartnerEntity> { public class HsOfficePartnerEntity implements Stringifyable, BaseEntity<HsOfficePartnerEntity> {
public static final String PARTNER_NUMBER_TAG = "P-"; public static final String PARTNER_NUMBER_TAG = "P-";
@ -78,7 +79,7 @@ public class HsOfficePartnerEntity implements Stringifyable, RbacObject<HsOffice
@Override @Override
public HsOfficePartnerEntity load() { public HsOfficePartnerEntity load() {
RbacObject.super.load(); BaseEntity.super.load();
partnerRel.load(); partnerRel.load();
details.load(); details.load();
return this; return this;
@ -104,7 +105,7 @@ public class HsOfficePartnerEntity implements Stringifyable, RbacObject<HsOffice
.withUpdatableColumns("partnerRelUuid") .withUpdatableColumns("partnerRelUuid")
.toRole("global", ADMIN).grantPermission(INSERT) .toRole("global", ADMIN).grantPermission(INSERT)
.importRootEntityAliasProxy("partnerRel", HsOfficeRelation.class, .importRootEntityAliasProxy("partnerRel", HsOfficeRelationRbacEntity.class,
usingDefaultCase(), usingDefaultCase(),
directlyFetchedByDependsOnColumn(), directlyFetchedByDependsOnColumn(),
dependsOnColumn("partnerRelUuid")) dependsOnColumn("partnerRelUuid"))

View File

@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.person;
import lombok.*; import lombok.*;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
@ -30,7 +30,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@AllArgsConstructor @AllArgsConstructor
@FieldNameConstants @FieldNameConstants
@DisplayName("Person") @DisplayName("Person")
public class HsOfficePersonEntity implements RbacObject<HsOfficePersonEntity>, Stringifyable { public class HsOfficePersonEntity implements BaseEntity<HsOfficePersonEntity>, Stringifyable {
private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person") private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person")
.withProp(Fields.personType, HsOfficePersonEntity::getPersonType) .withProp(Fields.personType, HsOfficePersonEntity::getPersonType)

View File

@ -5,7 +5,7 @@ import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactBareEntity; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactBareEntity;
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity; import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
@ -22,7 +22,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Setter @Setter
@SuperBuilder(toBuilder = true) @SuperBuilder(toBuilder = true)
@FieldNameConstants @FieldNameConstants
public class HsOfficeRelation implements RbacObject<HsOfficeRelation>, Stringifyable { public class HsOfficeRelation implements BaseEntity<HsOfficeRelation>, Stringifyable {
private static Stringify<HsOfficeRelation> toString = stringify(HsOfficeRelation.class, "rel") private static Stringify<HsOfficeRelation> toString = stringify(HsOfficeRelation.class, "rel")
.withProp(Fields.anchor, HsOfficeRelation::getAnchor) .withProp(Fields.anchor, HsOfficeRelation::getAnchor)
@ -64,7 +64,7 @@ public class HsOfficeRelation implements RbacObject<HsOfficeRelation>, Stringify
@Override @Override
public HsOfficeRelation load() { public HsOfficeRelation load() {
RbacObject.super.load(); BaseEntity.super.load();
anchor.load(); anchor.load();
holder.load(); holder.load();
contact.load(); contact.load();

View File

@ -17,19 +17,19 @@ public interface HsOfficeRelationBareRepository extends Repository<HsOfficeRelat
} }
@Query(value = """ @Query(value = """
SELECT p.* FROM hs_office_relation_rv AS p SELECT p.* FROM hs_office_relation AS p
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
""", nativeQuery = true) """, nativeQuery = true)
List<HsOfficeRelationBareEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid); List<HsOfficeRelationBareEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
@Query(value = """ @Query(value = """
SELECT p.* FROM hs_office_relation_rv AS p SELECT p.* FROM hs_office_relation AS p
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS HsOfficeRelationType)) WHERE (:relationType IS NULL OR p.type = cast(:relationType AS HsOfficeRelationType))
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid) AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid)
""", nativeQuery = true) """, nativeQuery = true)
List<HsOfficeRelationBareEntity> findRelationRelatedToPersonUuidAndRelationTypeString(@NotNull UUID personUuid, String relationType); List<HsOfficeRelationBareEntity> findRelationRelatedToPersonUuidAndRelationTypeString(@NotNull UUID personUuid, String relationType);
HsOfficeRelationBareEntity save(final HsOfficeRelation entity); HsOfficeRelationBareEntity save(final HsOfficeRelationBareEntity entity);
long count(); long count();

View File

@ -6,8 +6,8 @@ import lombok.*;
import net.hostsharing.hsadminng.errors.DisplayName; import net.hostsharing.hsadminng.errors.DisplayName;
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity; import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; import net.hostsharing.hsadminng.stringify.Stringifyable;
@ -40,7 +40,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@DisplayName("SEPA-Mandate") @DisplayName("SEPA-Mandate")
public class HsOfficeSepaMandateEntity implements Stringifyable, RbacObject<HsOfficeSepaMandateEntity> { public class HsOfficeSepaMandateEntity implements Stringifyable, BaseEntity<HsOfficeSepaMandateEntity> {
private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class) private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class)
.withProp(e -> e.getBankAccount().getIban()) .withProp(e -> e.getBankAccount().getIban())
@ -110,7 +110,7 @@ public class HsOfficeSepaMandateEntity implements Stringifyable, RbacObject<HsOf
.withRestrictedViewOrderBy(expression("validity")) .withRestrictedViewOrderBy(expression("validity"))
.withUpdatableColumns("reference", "agreement", "validity") .withUpdatableColumns("reference", "agreement", "validity")
.importEntityAlias("debitorRel", HsOfficeRelation.class, usingCase(DEBITOR), .importEntityAlias("debitorRel", HsOfficeRelationRbacEntity.class, usingCase(DEBITOR),
dependsOnColumn("debitorUuid"), dependsOnColumn("debitorUuid"),
fetchedBySql(""" fetchedBySql("""
SELECT ${columns} SELECT ${columns}

View File

@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.rbacdef;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import org.reflections.Reflections; import org.reflections.Reflections;
import org.reflections.scanners.TypeAnnotationsScanner; import org.reflections.scanners.TypeAnnotationsScanner;
@ -12,6 +12,7 @@ import jakarta.persistence.Version;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -89,11 +90,11 @@ public class RbacView {
* @param <E> * @param <E>
* a JPA entity class extending RbacObject * a JPA entity class extending RbacObject
*/ */
public static <E extends RbacObject> RbacView rbacViewFor(final String alias, final Class<E> entityClass) { public static <E extends BaseEntity> RbacView rbacViewFor(final String alias, final Class<E> entityClass) {
return new RbacView(alias, entityClass); return new RbacView(alias, entityClass);
} }
RbacView(final String alias, final Class<? extends RbacObject> entityClass) { RbacView(final String alias, final Class<? extends BaseEntity> entityClass) {
rootEntityAlias = new EntityAlias(alias, entityClass); rootEntityAlias = new EntityAlias(alias, entityClass);
entityAliases.put(alias, rootEntityAlias); entityAliases.put(alias, rootEntityAlias);
new RbacUserReference(CREATOR); new RbacUserReference(CREATOR);
@ -253,7 +254,7 @@ public class RbacView {
.orElseGet(() -> new RbacPermissionDefinition(entityAlias, permission, null, true)); .orElseGet(() -> new RbacPermissionDefinition(entityAlias, permission, null, true));
} }
public <EC extends RbacObject> RbacView declarePlaceholderEntityAliases(final String... aliasNames) { public <EC extends BaseEntity> RbacView declarePlaceholderEntityAliases(final String... aliasNames) {
for (String alias : aliasNames) { for (String alias : aliasNames) {
entityAliases.put(alias, new EntityAlias(alias)); entityAliases.put(alias, new EntityAlias(alias));
} }
@ -286,9 +287,9 @@ public class RbacView {
* @param <EC> * @param <EC>
* a JPA entity class extending RbacObject * a JPA entity class extending RbacObject
*/ */
public <EC extends RbacObject> RbacView importRootEntityAliasProxy( public <EC extends BaseEntity> RbacView importRootEntityAliasProxy(
final String aliasName, final String aliasName,
final Class<? extends RbacObject> entityClass, final Class<? extends BaseEntity> entityClass,
final ColumnValue forCase, final ColumnValue forCase,
final SQL fetchSql, final SQL fetchSql,
final Column dependsOnColum) { final Column dependsOnColum) {
@ -312,7 +313,7 @@ public class RbacView {
* a JPA entity class extending RbacObject * a JPA entity class extending RbacObject
*/ */
public RbacView importSubEntityAlias( public RbacView importSubEntityAlias(
final String aliasName, final Class<? extends RbacObject> entityClass, final String aliasName, final Class<? extends BaseEntity> entityClass,
final SQL fetchSql, final Column dependsOnColum) { final SQL fetchSql, final Column dependsOnColum) {
importEntityAliasImpl(aliasName, entityClass, usingDefaultCase(), fetchSql, dependsOnColum, true, NOT_NULL); importEntityAliasImpl(aliasName, entityClass, usingDefaultCase(), fetchSql, dependsOnColum, true, NOT_NULL);
return this; return this;
@ -349,14 +350,14 @@ public class RbacView {
* a JPA entity class extending RbacObject * a JPA entity class extending RbacObject
*/ */
public RbacView importEntityAlias( public RbacView importEntityAlias(
final String aliasName, final Class<? extends RbacObject> entityClass, final ColumnValue usingCase, final String aliasName, final Class<? extends BaseEntity> entityClass, final ColumnValue usingCase,
final Column dependsOnColum, final SQL fetchSql, final Nullable nullable) { final Column dependsOnColum, final SQL fetchSql, final Nullable nullable) {
importEntityAliasImpl(aliasName, entityClass, usingCase, fetchSql, dependsOnColum, false, nullable); importEntityAliasImpl(aliasName, entityClass, usingCase, fetchSql, dependsOnColum, false, nullable);
return this; return this;
} }
private EntityAlias importEntityAliasImpl( private EntityAlias importEntityAliasImpl(
final String aliasName, final Class<? extends RbacObject> entityClass, final ColumnValue usingCase, final String aliasName, final Class<? extends BaseEntity> entityClass, final ColumnValue usingCase,
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) { final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) {
final var entityAlias = ofNullable(entityAliases.get(aliasName)) final var entityAlias = ofNullable(entityAliases.get(aliasName))
@ -378,7 +379,7 @@ public class RbacView {
return entityAlias; return entityAlias;
} }
private static RbacView rbacDefinition(final Class<? extends RbacObject> entityClass) private static RbacView rbacDefinition(final Class<? extends BaseEntity> entityClass)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
return (RbacView) entityClass.getMethod("rbac").invoke(null); return (RbacView) entityClass.getMethod("rbac").invoke(null);
} }
@ -432,12 +433,22 @@ public class RbacView {
} }
private void verifyVersionColumnExists() { private void verifyVersionColumnExists() {
if (stream(rootEntityAlias.entityClass.getDeclaredFields()) final var clazz = rootEntityAlias.entityClass;
.noneMatch(f -> f.getAnnotation(Version.class) != null)) { if (!hasVersionColumn(clazz)) {
throw new IllegalArgumentException("@Version field required in updatable entity " + rootEntityAlias.entityClass); throw new IllegalArgumentException("@Version field required in updatable entity " + rootEntityAlias.entityClass);
} }
} }
private static boolean hasVersionColumn(final Class<?> clazz) {
if (stream(clazz.getDeclaredFields()).anyMatch(f -> f.getAnnotation(Version.class) != null)) {
return true;
}
if (clazz.getSuperclass() != null) {
return hasVersionColumn(clazz.getSuperclass());
}
return false;
}
/** /**
* Starts declaring a grant to a given role. * Starts declaring a grant to a given role.
* *
@ -900,13 +911,13 @@ public class RbacView {
return distinctGrantDef; return distinctGrantDef;
} }
record EntityAlias(String aliasName, Class<? extends RbacObject> entityClass, ColumnValue usingCase, SQL fetchSql, Column dependsOnColum, boolean isSubEntity, Nullable nullable) { record EntityAlias(String aliasName, Class<? extends BaseEntity> entityClass, ColumnValue usingCase, SQL fetchSql, Column dependsOnColum, boolean isSubEntity, Nullable nullable) {
public EntityAlias(final String aliasName) { public EntityAlias(final String aliasName) {
this(aliasName, null, null, null, null, false, null); this(aliasName, null, null, null, null, false, null);
} }
public EntityAlias(final String aliasName, final Class<? extends RbacObject> entityClass) { public EntityAlias(final String aliasName, final Class<? extends BaseEntity> entityClass) {
this(aliasName, entityClass, null, null, null, false, null); this(aliasName, entityClass, null, null, null, false, null);
} }
@ -936,6 +947,10 @@ public class RbacView {
} }
private String withoutEntitySuffix(final String simpleEntityName) { private String withoutEntitySuffix(final String simpleEntityName) {
// TODO.impl: maybe introduce an annotation like @RbacObjectName("hsOfficeContact")?
if ( simpleEntityName.endsWith("RbacEntity")) {
return simpleEntityName.substring(0, simpleEntityName.length() - "RbacEntity".length());
}
return simpleEntityName.substring(0, simpleEntityName.length() - "Entity".length()); return simpleEntityName.substring(0, simpleEntityName.length() - "Entity".length());
} }
@ -1210,7 +1225,7 @@ public class RbacView {
} }
} }
private static void generateRbacView(final Class<? extends RbacObject> c) { private static void generateRbacView(final Class<? extends BaseEntity> c) {
final Method mainMethod = stream(c.getMethods()).filter( final Method mainMethod = stream(c.getMethods()).filter(
m -> isStatic(m.getModifiers()) && m.getName().equals("main") m -> isStatic(m.getModifiers()) && m.getName().equals("main")
) )
@ -1227,17 +1242,20 @@ public class RbacView {
} }
} }
public static Set<Class<? extends RbacObject>> findRbacEntityClasses(String packageName) { public static Set<Class<? extends BaseEntity>> findRbacEntityClasses(String packageName) {
final var reflections = new Reflections(packageName, TypeAnnotationsScanner.class); final var reflections = new Reflections(packageName, TypeAnnotationsScanner.class);
return reflections.getTypesAnnotatedWith(Entity.class).stream() return reflections.getTypesAnnotatedWith(Entity.class).stream()
.filter(c -> stream(c.getInterfaces()).anyMatch(i -> i==RbacObject.class)) .filter(c -> stream(c.getInterfaces()).anyMatch(i -> i== BaseEntity.class))
.map(RbacView::castToSubclassOfRbacObject) .filter(c -> stream(c.getDeclaredMethods())
.anyMatch(m -> m.getName().equals("rbac") && Modifier.isStatic(m.getModifiers()))
)
.map(RbacView::castToSubclassOfBaseEntity)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static Class<? extends RbacObject> castToSubclassOfRbacObject(final Class<?> clazz) { private static Class<? extends BaseEntity> castToSubclassOfBaseEntity(final Class<?> clazz) {
return (Class<? extends RbacObject>) clazz; return (Class<? extends BaseEntity>) clazz;
} }
/** /**

View File

@ -5,7 +5,8 @@ import org.hibernate.Hibernate;
import java.util.UUID; import java.util.UUID;
public interface RbacObject<T extends RbacObject<?>> { // TODO.impl: this class does not really belong into this package, but there is no right place yet
public interface BaseEntity<T extends BaseEntity<?>> {
UUID getUuid(); UUID getUuid();
int getVersion(); int getVersion();

View File

@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
@ -24,7 +24,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class TestCustomerEntity implements RbacObject<TestCustomerEntity> { public class TestCustomerEntity implements BaseEntity<TestCustomerEntity> {
@Id @Id
@GeneratedValue @GeneratedValue

View File

@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.test.pac.TestPackageEntity; import net.hostsharing.hsadminng.rbac.test.pac.TestPackageEntity;
@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class TestDomainEntity implements RbacObject<TestDomainEntity> { public class TestDomainEntity implements BaseEntity<TestDomainEntity> {
@Id @Id
@GeneratedValue @GeneratedValue

View File

@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.test.cust.TestCustomerEntity; import net.hostsharing.hsadminng.rbac.test.cust.TestCustomerEntity;
@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class TestPackageEntity implements RbacObject<TestPackageEntity> { public class TestPackageEntity implements BaseEntity<TestPackageEntity> {
@Id @Id
@GeneratedValue @GeneratedValue

View File

@ -197,8 +197,7 @@ begin
from granted from granted
join RbacPermission perm on granted.descendantUuid = perm.uuid join RbacPermission perm on granted.descendantUuid = perm.uuid
join RbacObject obj on obj.uuid = perm.objectUuid join RbacObject obj on obj.uuid = perm.objectUuid
where perm.op = 'SELECT' where obj.objectTable = '%1$s' -- 'SELECT' permission is included in all other permissions
and obj.objectTable = '%1$s'
limit 8001 limit 8001
) )
select target.* select target.*

View File

@ -142,8 +142,8 @@ begin
return NEW; return NEW;
end if; end if;
raise exception '[403] insert into test_customer not allowed for current subjects % (%)', raise exception '[403] insert into test_customer values(%) not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger test_customer_insert_permission_check_tg create trigger test_customer_insert_permission_check_tg

View File

@ -207,8 +207,8 @@ begin
return NEW; return NEW;
end if; end if;
raise exception '[403] insert into test_package not allowed for current subjects % (%)', raise exception '[403] insert into test_package values(%) not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger test_package_insert_permission_check_tg create trigger test_package_insert_permission_check_tg

View File

@ -206,8 +206,8 @@ begin
return NEW; return NEW;
end if; end if;
raise exception '[403] insert into test_domain not allowed for current subjects % (%)', raise exception '[403] insert into test_domain values(%) not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger test_domain_insert_permission_check_tg create trigger test_domain_insert_permission_check_tg

View File

@ -219,8 +219,8 @@ begin
return NEW; return NEW;
end if; end if;
raise exception '[403] insert into hs_office_partner not allowed for current subjects % (%)', raise exception '[403] insert into hs_office_partner values(%) not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger hs_office_partner_insert_permission_check_tg create trigger hs_office_partner_insert_permission_check_tg

View File

@ -123,8 +123,8 @@ begin
return NEW; return NEW;
end if; end if;
raise exception '[403] insert into hs_office_partner_details not allowed for current subjects % (%)', raise exception '[403] insert into hs_office_partner_details values(%) not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger hs_office_partner_details_insert_permission_check_tg create trigger hs_office_partner_details_insert_permission_check_tg

View File

@ -192,8 +192,8 @@ begin
return NEW; return NEW;
end if; end if;
raise exception '[403] insert into hs_office_debitor not allowed for current subjects % (%)', raise exception '[403] insert into hs_office_debitor values(%) not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger hs_office_debitor_insert_permission_check_tg create trigger hs_office_debitor_insert_permission_check_tg

View File

@ -173,8 +173,8 @@ begin
return NEW; return NEW;
end if; end if;
raise exception '[403] insert into hs_office_sepamandate not allowed for current subjects % (%)', raise exception '[403] insert into hs_office_sepamandate values(%) not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger hs_office_sepamandate_insert_permission_check_tg create trigger hs_office_sepamandate_insert_permission_check_tg

View File

@ -154,8 +154,8 @@ begin
return NEW; return NEW;
end if; end if;
raise exception '[403] insert into hs_office_membership not allowed for current subjects % (%)', raise exception '[403] insert into hs_office_membership values(%) not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger hs_office_membership_insert_permission_check_tg create trigger hs_office_membership_insert_permission_check_tg

View File

@ -130,8 +130,8 @@ begin
return NEW; return NEW;
end if; end if;
raise exception '[403] insert into hs_office_coopsharestransaction not allowed for current subjects % (%)', raise exception '[403] insert into hs_office_coopsharestransaction values(%) not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger hs_office_coopsharestransaction_insert_permission_check_tg create trigger hs_office_coopsharestransaction_insert_permission_check_tg

View File

@ -130,8 +130,8 @@ begin
return NEW; return NEW;
end if; end if;
raise exception '[403] insert into hs_office_coopassetstransaction not allowed for current subjects % (%)', raise exception '[403] insert into hs_office_coopassetstransaction values(%) not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), currentSubjectsUuids();
end; $$; end; $$;
create trigger hs_office_coopassetstransaction_insert_permission_check_tg create trigger hs_office_coopassetstransaction_insert_permission_check_tg

View File

@ -12,7 +12,7 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest; import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService; import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import org.springframework.data.repository.Repository; import org.springframework.data.repository.Repository;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -346,7 +346,7 @@ public class ArchitectureTest {
static final ArchRule tableNamesOfRbacEntitiesShouldEndWith_rv = static final ArchRule tableNamesOfRbacEntitiesShouldEndWith_rv =
classes() classes()
.that().areAnnotatedWith(Table.class) .that().areAnnotatedWith(Table.class)
.and().areAssignableTo(RbacObject.class) .and().areAssignableTo(BaseEntity.class)
.should(haveTableNameEndingWith_rv()) .should(haveTableNameEndingWith_rv())
.because("it's required that the table names of RBAC entities end with '_rv'"); .because("it's required that the table names of RBAC entities end with '_rv'");

View File

@ -6,7 +6,7 @@ import com.opencsv.CSVReaderBuilder;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest; import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext;
@ -141,7 +141,7 @@ public class CsvDataImport extends ContextBasedTest {
return record; return record;
} }
public <T extends RbacObject> T persist(final Integer id, final T entity) { public <T extends BaseEntity> T persist(final Integer id, final T entity) {
try { try {
if (entity instanceof HsHostingAsset ha) { if (entity instanceof HsHostingAsset ha) {
//noinspection unchecked //noinspection unchecked
@ -155,7 +155,7 @@ public class CsvDataImport extends ContextBasedTest {
return entity; return entity;
} }
public <T extends RbacObject> T persistViaEM(final Integer id, final T entity) { public <T extends BaseEntity> T persistViaEM(final Integer id, final T entity) {
//System.out.println("persisting #" + entity.hashCode() + ": " + entity); //System.out.println("persisting #" + entity.hashCode() + ": " + entity);
em.persist(entity); em.persist(entity);
// uncomment for debugging purposes // uncomment for debugging purposes
@ -165,7 +165,7 @@ public class CsvDataImport extends ContextBasedTest {
} }
@SneakyThrows @SneakyThrows
public RbacObject<HsHostingAsset> persistViaSql(final Integer id, final HsHostingAsset entity) { public BaseEntity<HsHostingAsset> persistViaSql(final Integer id, final HsHostingAsset entity) {
if (entity.getUuid() == null) { if (entity.getUuid() == null) {
entity.setUuid(UUID.randomUUID()); entity.setUuid(UUID.randomUUID());
} }
@ -196,10 +196,10 @@ public class CsvDataImport extends ContextBasedTest {
""") """)
.setParameter("uuid", entity.getUuid()) .setParameter("uuid", entity.getUuid())
.setParameter("type", entity.getType().name()) .setParameter("type", entity.getType().name())
.setParameter("bookingitemuuid", ofNullable(entity.getBookingItem()).map(RbacObject::getUuid).orElse(null)) .setParameter("bookingitemuuid", ofNullable(entity.getBookingItem()).map(BaseEntity::getUuid).orElse(null))
.setParameter("parentassetuuid", ofNullable(entity.getParentAsset()).map(RbacObject::getUuid).orElse(null)) .setParameter("parentassetuuid", ofNullable(entity.getParentAsset()).map(BaseEntity::getUuid).orElse(null))
.setParameter("assignedtoassetuuid", ofNullable(entity.getAssignedToAsset()).map(RbacObject::getUuid).orElse(null)) .setParameter("assignedtoassetuuid", ofNullable(entity.getAssignedToAsset()).map(BaseEntity::getUuid).orElse(null))
.setParameter("alarmcontactuuid", ofNullable(entity.getAlarmContact()).map(RbacObject::getUuid).orElse(null)) .setParameter("alarmcontactuuid", ofNullable(entity.getAlarmContact()).map(BaseEntity::getUuid).orElse(null))
.setParameter("identifier", entity.getIdentifier()) .setParameter("identifier", entity.getIdentifier())
.setParameter("caption", entity.getCaption()) .setParameter("caption", entity.getCaption())
.setParameter("config", entity.getConfig().toString()) .setParameter("config", entity.getConfig().toString())

View File

@ -18,7 +18,7 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity; import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -698,7 +698,7 @@ public class ImportOfficeData extends CsvDataImport {
assumeThat(partners.size()).isLessThanOrEqualTo(MAX_NUMBER_OF_TEST_DATA_PARTNERS); assumeThat(partners.size()).isLessThanOrEqualTo(MAX_NUMBER_OF_TEST_DATA_PARTNERS);
} }
private <E extends RbacObject> void updateLegacyIds( private <E extends BaseEntity> void updateLegacyIds(
Map<Integer, E> entities, Map<Integer, E> entities,
final String legacyIdTable, final String legacyIdTable,
final String legacyIdColumn) { final String legacyIdColumn) {

View File

@ -65,7 +65,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
HsOfficePersonRepository personRepo; HsOfficePersonRepository personRepo;
@Autowired @Autowired
HsOfficeRelationBareRepository relRepo; HsOfficeRelationBareRepository relBareRepo;
@Autowired @Autowired
JpaAttempt jpaAttempt; JpaAttempt jpaAttempt;
@ -275,7 +275,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
final var givenDebitorRelUUid = jpaAttempt.transacted(() -> { final var givenDebitorRelUUid = jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
return relRepo.save(HsOfficeRelationRbacEntity.builder() return relBareRepo.save(HsOfficeRelationBareEntity.builder()
.type(DEBITOR) .type(DEBITOR)
.anchor(givenPartner.getPartnerRel().getHolder()) .anchor(givenPartner.getPartnerRel().getHolder())
.holder(givenBillingPerson) .holder(givenBillingPerson)
@ -435,7 +435,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
.post("http://localhost/api/hs/office/debitors") .post("http://localhost/api/hs/office/debitors")
.then().log().all().assertThat() .then().log().all().assertThat()
.statusCode(400) .statusCode(400)
.body("message", is("Unable to find HsOfficeRelationEntity with uuid 00000000-0000-0000-0000-000000000000")); .body("message", is("Unable to find HsOfficeRelationBareEntity with uuid 00000000-0000-0000-0000-000000000000"));
// @formatter:on // @formatter:on
} }
} }

View File

@ -161,7 +161,7 @@ class HsOfficePartnerControllerRestTest {
.andExpect(status().is4xxClientError()) .andExpect(status().is4xxClientError())
.andExpect(jsonPath("statusCode", is(400))) .andExpect(jsonPath("statusCode", is(400)))
.andExpect(jsonPath("statusPhrase", is("Bad Request"))) .andExpect(jsonPath("statusPhrase", is("Bad Request")))
.andExpect(jsonPath("message", startsWith("Cannot resolve HsOfficeContactEntity with uuid "))); .andExpect(jsonPath("message", startsWith("Cannot resolve HsOfficeContactBareEntity with uuid ")));
} }
} }

View File

@ -329,7 +329,8 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
// then // then
result.assertExceptionWithRootCauseMessage(JpaSystemException.class, result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
"[403] insert into hs_office_partner_details not allowed for current subjects {hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT}"); "ERROR: [403] insert into hs_office_partner_details ",
" not allowed for current subjects {hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT}");
} }
private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) { private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) {

View File

@ -1,7 +1,7 @@
package net.hostsharing.hsadminng.rbac.test; package net.hostsharing.hsadminng.rbac.test;
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest; import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantEntity; import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantEntity;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository; import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService; import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
@ -50,7 +50,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
@Autowired @Autowired
JpaAttempt jpaAttempt; JpaAttempt jpaAttempt;
private TreeMap<UUID, Class<? extends RbacObject>> entitiesToCleanup = new TreeMap<>(); private TreeMap<UUID, Class<? extends BaseEntity>> entitiesToCleanup = new TreeMap<>();
private static Long latestIntialTestDataSerialId; private static Long latestIntialTestDataSerialId;
private static boolean countersInitialized = false; private static boolean countersInitialized = false;
@ -64,19 +64,19 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
private TestInfo testInfo; private TestInfo testInfo;
public <T extends RbacObject> T refresh(final T entity) { public <T extends BaseEntity> T refresh(final T entity) {
final var merged = em.merge(entity); final var merged = em.merge(entity);
em.refresh(merged); em.refresh(merged);
return merged; return merged;
} }
public UUID toCleanup(final Class<? extends RbacObject> entityClass, final UUID uuidToCleanup) { public UUID toCleanup(final Class<? extends BaseEntity> entityClass, final UUID uuidToCleanup) {
out.println("toCleanup(" + entityClass.getSimpleName() + ", " + uuidToCleanup + ")"); out.println("toCleanup(" + entityClass.getSimpleName() + ", " + uuidToCleanup + ")");
entitiesToCleanup.put(uuidToCleanup, entityClass); entitiesToCleanup.put(uuidToCleanup, entityClass);
return uuidToCleanup; return uuidToCleanup;
} }
public <E extends RbacObject> E toCleanup(final E entity) { public <E extends BaseEntity> E toCleanup(final E entity) {
out.println("toCleanup(" + entity.getClass() + ", " + entity.getUuid()); out.println("toCleanup(" + entity.getClass() + ", " + entity.getUuid());
if ( entity.getUuid() == null ) { if ( entity.getUuid() == null ) {
throw new IllegalArgumentException("only persisted entities with valid uuid allowed"); throw new IllegalArgumentException("only persisted entities with valid uuid allowed");
@ -85,7 +85,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
return entity; return entity;
} }
protected void cleanupAllNew(final Class<? extends RbacObject> entityClass) { protected void cleanupAllNew(final Class<? extends BaseEntity> entityClass) {
if (initialRbacObjects == null) { if (initialRbacObjects == null) {
out.println("skipping cleanupAllNew: " + entityClass.getSimpleName()); out.println("skipping cleanupAllNew: " + entityClass.getSimpleName());
return; // TODO: seems @AfterEach is called without any @BeforeEach return; // TODO: seems @AfterEach is called without any @BeforeEach

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.rbac.test; package net.hostsharing.hsadminng.rbac.test;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import java.util.List; import java.util.List;
@ -8,7 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class EntityList { public class EntityList {
public static <E extends RbacObject> E one(final List<E> entities) { public static <E extends BaseEntity> E one(final List<E> entities) {
assertThat(entities).hasSize(1); assertThat(entities).hasSize(1);
return entities.stream().findFirst().orElseThrow(); return entities.stream().findFirst().orElseThrow();
} }

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.rbac.test; package net.hostsharing.hsadminng.rbac.test;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.mapper.EntityPatcher; import net.hostsharing.hsadminng.mapper.EntityPatcher;
import org.junit.jupiter.api.Named; import org.junit.jupiter.api.Named;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -233,7 +233,7 @@ public abstract class PatchUnitTestBase<R, E> {
} }
} }
protected static class JsonNullableProperty<R, RV, E extends RbacObject, EV> extends Property<R, RV, E, EV> { protected static class JsonNullableProperty<R, RV, E extends BaseEntity, EV> extends Property<R, RV, E, EV> {
private final BiConsumer<R, JsonNullable<RV>> resourceSetter; private final BiConsumer<R, JsonNullable<RV>> resourceSetter;
public final RV givenPatchValue; public final RV givenPatchValue;