introduce-separate-database-schema-hs-office-and-amend-generators (#105)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/105 Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
+2
-2
@@ -4,7 +4,7 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
|
||||
@@ -49,7 +49,7 @@ public class HsBookingItemRbacEntity extends HsBookingItem {
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(DELETE)
|
||||
|
||||
.importEntityAlias("project", HsBookingProject.class, usingDefaultCase(),
|
||||
.importEntityAlias("project", HsBookingProjectRbacEntity.class, usingDefaultCase(),
|
||||
dependsOnColumn("projectUuid"),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
NULLABLE)
|
||||
|
||||
@@ -68,11 +68,11 @@ public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBo
|
||||
}
|
||||
|
||||
public static RbacView rbac() {
|
||||
return rbacViewFor("project", HsBookingProject.class)
|
||||
return rbacViewFor("project", HsBookingProjectRbacEntity.class)
|
||||
.withIdentityView(SQL.query("""
|
||||
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || base.cleanIdentifier(bookingProject.caption) as idName
|
||||
FROM hs_booking_project bookingProject
|
||||
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
|
||||
JOIN hs_office.debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
|
||||
"""))
|
||||
.withRestrictedViewOrderBy(SQL.expression("caption"))
|
||||
.withUpdatableColumns("version", "caption")
|
||||
@@ -86,8 +86,8 @@ public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBo
|
||||
dependsOnColumn("debitorUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT ${columns}
|
||||
FROM hs_office_relation debitorRel
|
||||
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||
FROM hs_office.relation debitorRel
|
||||
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||
WHERE debitor.uuid = ${REF}.debitorUuid
|
||||
"""),
|
||||
NOT_NULL)
|
||||
|
||||
+3
-3
@@ -44,7 +44,7 @@ public class HsBookingProjectRbacEntity extends HsBookingProject {
|
||||
.withIdentityView(SQL.query("""
|
||||
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || base.cleanIdentifier(bookingProject.caption) as idName
|
||||
FROM hs_booking_project bookingProject
|
||||
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
|
||||
JOIN hs_office.debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
|
||||
"""))
|
||||
.withRestrictedViewOrderBy(SQL.expression("caption"))
|
||||
.withUpdatableColumns("version", "caption")
|
||||
@@ -58,8 +58,8 @@ public class HsBookingProjectRbacEntity extends HsBookingProject {
|
||||
dependsOnColumn("debitorUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT ${columns}
|
||||
FROM hs_office_relation debitorRel
|
||||
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||
FROM hs_office.relation debitorRel
|
||||
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||
WHERE debitor.uuid = ${REF}.debitorUuid
|
||||
"""),
|
||||
NOT_NULL)
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRbacEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
@@ -47,7 +47,7 @@ public class HsHostingAssetRbacEntity extends HsHostingAsset {
|
||||
.withUpdatableColumns("version", "caption", "config", "assignedToAssetUuid", "alarmContactUuid")
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
|
||||
|
||||
.importEntityAlias("bookingItem", HsBookingItem.class, usingDefaultCase(),
|
||||
.importEntityAlias("bookingItem", HsBookingItemRbacEntity.class, usingDefaultCase(),
|
||||
dependsOnColumn("bookingItemUuid"),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
NULLABLE)
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_bankaccount_rv")
|
||||
@Table(schema = "hs_office", name = "bankaccount_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_contact_rv")
|
||||
@Table(schema = "hs_office", name = "contact_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_contact")
|
||||
@Table(schema = "hs_office", name = "contact")
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_coopassetstransaction_rv")
|
||||
@Table(schema = "hs_office", name = "coopassetstransaction_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_coopsharestransaction_rv")
|
||||
@Table(schema = "hs_office", name = "coopsharestransaction_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
|
||||
+10
-10
@@ -54,7 +54,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_debitor_rv")
|
||||
@Table(schema = "hs_office", name = "debitor_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder(toBuilder = true)
|
||||
@@ -87,10 +87,10 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
||||
value = """
|
||||
(
|
||||
SELECT DISTINCT partner.uuid
|
||||
FROM hs_office_partner_rv partner
|
||||
JOIN hs_office_relation_rv dRel
|
||||
FROM hs_office.partner_rv partner
|
||||
JOIN hs_office.relation_rv dRel
|
||||
ON dRel.uuid = debitorreluuid AND dRel.type = 'DEBITOR'
|
||||
JOIN hs_office_relation_rv pRel
|
||||
JOIN hs_office.relation_rv pRel
|
||||
ON pRel.uuid = partner.partnerRelUuid AND pRel.type = 'PARTNER'
|
||||
WHERE pRel.holderUuid = dRel.anchorUuid
|
||||
)
|
||||
@@ -170,14 +170,14 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
||||
.withIdentityView(SQL.query("""
|
||||
SELECT debitor.uuid AS uuid,
|
||||
'D-' || (SELECT partner.partnerNumber
|
||||
FROM hs_office_partner partner
|
||||
JOIN hs_office_relation partnerRel
|
||||
FROM hs_office.partner partner
|
||||
JOIN hs_office.relation partnerRel
|
||||
ON partnerRel.uuid = partner.partnerRelUUid AND partnerRel.type = 'PARTNER'
|
||||
JOIN hs_office_relation debitorRel
|
||||
JOIN hs_office.relation debitorRel
|
||||
ON debitorRel.anchorUuid = partnerRel.holderUuid AND debitorRel.type = 'DEBITOR'
|
||||
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
||||
|| debitorNumberSuffix as idName
|
||||
FROM hs_office_debitor AS debitor
|
||||
FROM hs_office.debitor AS debitor
|
||||
"""))
|
||||
.withRestrictedViewOrderBy(SQL.projection("defaultPrefix"))
|
||||
.withUpdatableColumns(
|
||||
@@ -209,8 +209,8 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
||||
dependsOnColumn("debitorRelUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT ${columns}
|
||||
FROM hs_office_relation AS partnerRel
|
||||
JOIN hs_office_relation AS debitorRel
|
||||
FROM hs_office.relation AS partnerRel
|
||||
JOIN hs_office.relation AS debitorRel
|
||||
ON debitorRel.type = 'DEBITOR' AND debitorRel.anchorUuid = partnerRel.holderUuid
|
||||
WHERE partnerRel.type = 'PARTNER'
|
||||
AND ${REF}.debitorRelUuid = debitorRel.uuid
|
||||
|
||||
+5
-5
@@ -56,7 +56,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_membership_rv")
|
||||
@Table(schema = "hs_office", name = "membership_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@@ -160,8 +160,8 @@ public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEn
|
||||
.withIdentityView(SQL.query("""
|
||||
SELECT m.uuid AS uuid,
|
||||
'M-' || p.partnerNumber || m.memberNumberSuffix as idName
|
||||
FROM hs_office_membership AS m
|
||||
JOIN hs_office_partner AS p ON p.uuid = m.partnerUuid
|
||||
FROM hs_office.membership AS m
|
||||
JOIN hs_office.partner AS p ON p.uuid = m.partnerUuid
|
||||
"""))
|
||||
.withRestrictedViewOrderBy(SQL.projection("validity"))
|
||||
.withUpdatableColumns("validity", "membershipFeeBillable", "status")
|
||||
@@ -170,8 +170,8 @@ public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEn
|
||||
dependsOnColumn("partnerUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT ${columns}
|
||||
FROM hs_office_partner AS partner
|
||||
JOIN hs_office_relation AS partnerRel ON partnerRel.uuid = partner.partnerRelUuid
|
||||
FROM hs_office.partner AS partner
|
||||
JOIN hs_office.relation AS partnerRel ON partnerRel.uuid = partner.partnerRelUuid
|
||||
WHERE partner.uuid = ${REF}.partnerUuid
|
||||
"""),
|
||||
NOT_NULL)
|
||||
|
||||
+4
-4
@@ -20,7 +20,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_partner_details_rv")
|
||||
@Table(schema = "hs_office", name = "partner_details_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@@ -71,9 +71,9 @@ public class HsOfficePartnerDetailsEntity implements BaseEntity<HsOfficePartnerD
|
||||
return rbacViewFor("partnerDetails", HsOfficePartnerDetailsEntity.class)
|
||||
.withIdentityView(SQL.query("""
|
||||
SELECT partnerDetails.uuid as uuid, partner_iv.idName as idName
|
||||
FROM hs_office_partner_details AS partnerDetails
|
||||
JOIN hs_office_partner partner ON partner.detailsUuid = partnerDetails.uuid
|
||||
JOIN hs_office_partner_iv partner_iv ON partner_iv.uuid = partner.uuid
|
||||
FROM hs_office.partner_details AS partnerDetails
|
||||
JOIN hs_office.partner partner ON partner.detailsUuid = partnerDetails.uuid
|
||||
JOIN hs_office.partner_iv partner_iv ON partner_iv.uuid = partner.uuid
|
||||
"""))
|
||||
.withRestrictedViewOrderBy(SQL.expression("uuid"))
|
||||
.withUpdatableColumns(
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ import static java.util.Optional.ofNullable;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_partner_rv")
|
||||
@Table(schema = "hs_office", name = "partner_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
|
||||
@@ -22,7 +22,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_person_rv")
|
||||
@Table(schema = "hs_office", name = "person_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
|
||||
+4
-4
@@ -34,7 +34,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetc
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_relation_rv")
|
||||
@Table(schema = "hs_office", name = "relation_rv")
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
@@ -45,12 +45,12 @@ public class HsOfficeRelationRbacEntity extends HsOfficeRelation {
|
||||
public static RbacView rbac() {
|
||||
return rbacViewFor("relation", HsOfficeRelationRbacEntity.class)
|
||||
.withIdentityView(SQL.projection("""
|
||||
(select idName from hs_office_person_iv p where p.uuid = anchorUuid)
|
||||
(select idName from hs_office.person_iv p where p.uuid = anchorUuid)
|
||||
|| '-with-' || target.type || '-'
|
||||
|| (select idName from hs_office_person_iv p where p.uuid = holderUuid)
|
||||
|| (select idName from hs_office.person_iv p where p.uuid = holderUuid)
|
||||
"""))
|
||||
.withRestrictedViewOrderBy(SQL.expression(
|
||||
"(select idName from hs_office_person_iv p where p.uuid = target.holderUuid)"))
|
||||
"(select idName from hs_office.person_iv p where p.uuid = target.holderUuid)"))
|
||||
.withUpdatableColumns("contactUuid")
|
||||
.importEntityAlias("anchorPerson", HsOfficePersonEntity.class, usingDefaultCase(),
|
||||
dependsOnColumn("anchorUuid"),
|
||||
|
||||
+2
-2
@@ -17,13 +17,13 @@ public interface HsOfficeRelationRbacRepository extends Repository<HsOfficeRelat
|
||||
}
|
||||
|
||||
@Query(value = """
|
||||
SELECT p.* FROM hs_office_relation_rv AS p
|
||||
SELECT p.* FROM hs_office.relation_rv AS p
|
||||
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
|
||||
""", nativeQuery = true)
|
||||
List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
|
||||
|
||||
@Query(value = """
|
||||
SELECT p.* FROM hs_office_relation_rv AS p
|
||||
SELECT p.* FROM hs_office.relation_rv AS p
|
||||
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS HsOfficeRelationType))
|
||||
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid)
|
||||
""", nativeQuery = true)
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import jakarta.persistence.Table;
|
||||
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_relation")
|
||||
@Table(schema = "hs_office", name = "relation")
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
|
||||
+2
-2
@@ -17,13 +17,13 @@ public interface HsOfficeRelationRealRepository extends Repository<HsOfficeRelat
|
||||
}
|
||||
|
||||
@Query(value = """
|
||||
SELECT p.* FROM hs_office_relation AS p
|
||||
SELECT p.* FROM hs_office.relation AS p
|
||||
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
|
||||
""", nativeQuery = true)
|
||||
List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
|
||||
|
||||
@Query(value = """
|
||||
SELECT p.* FROM hs_office_relation AS p
|
||||
SELECT p.* FROM hs_office.relation AS p
|
||||
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS HsOfficeRelationType))
|
||||
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid)
|
||||
""", nativeQuery = true)
|
||||
|
||||
+5
-5
@@ -33,7 +33,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_sepamandate_rv")
|
||||
@Table(schema = "hs_office", name = "sepamandate_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@@ -104,8 +104,8 @@ public class HsOfficeSepaMandateEntity implements Stringifyable, BaseEntity<HsOf
|
||||
return rbacViewFor("sepaMandate", HsOfficeSepaMandateEntity.class)
|
||||
.withIdentityView(query("""
|
||||
select sm.uuid as uuid, ba.iban || '-' || sm.validity as idName
|
||||
from hs_office_sepamandate sm
|
||||
join hs_office_bankaccount ba on ba.uuid = sm.bankAccountUuid
|
||||
from hs_office.sepamandate sm
|
||||
join hs_office.bankaccount ba on ba.uuid = sm.bankAccountUuid
|
||||
"""))
|
||||
.withRestrictedViewOrderBy(expression("validity"))
|
||||
.withUpdatableColumns("reference", "agreement", "validity")
|
||||
@@ -114,8 +114,8 @@ public class HsOfficeSepaMandateEntity implements Stringifyable, BaseEntity<HsOf
|
||||
dependsOnColumn("debitorUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT ${columns}
|
||||
FROM hs_office_relation debitorRel
|
||||
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||
FROM hs_office.relation debitorRel
|
||||
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||
WHERE debitor.uuid = ${REF}.debitorUuid
|
||||
"""),
|
||||
NOT_NULL)
|
||||
|
||||
@@ -213,7 +213,7 @@ public class InsertTriggerGenerator {
|
||||
if (g.getSuperRoleDef().isGlobal(GUEST)) {
|
||||
plPgSql.writeLn(
|
||||
"""
|
||||
-- check INSERT INSERT permission for rbac.global anyone
|
||||
-- check INSERT permission for rbac.global anyone
|
||||
if ${caseCondition}true then
|
||||
return NEW;
|
||||
end if;
|
||||
@@ -222,7 +222,7 @@ public class InsertTriggerGenerator {
|
||||
} else if (g.getSuperRoleDef().isGlobal(ADMIN)) {
|
||||
plPgSql.writeLn(
|
||||
"""
|
||||
-- check INSERT INSERT if rbac.global ADMIN
|
||||
-- check INSERT permission if rbac.global ADMIN
|
||||
if ${caseCondition}rbac.isGlobalAdmin() then
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
@@ -12,7 +12,6 @@ import jakarta.persistence.Version;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
@@ -983,10 +982,10 @@ public class RbacView {
|
||||
|
||||
String getRawTableShortName() {
|
||||
// TODO.impl: some combined function and trigger names are too long
|
||||
// maybe we should shorten the table name e.g. hs_office_coopsharestransaction -> hsof.coopsharetx
|
||||
// maybe we should shorten the table name e.g. hs_office.coopsharestransaction -> hsof.coopsharetx
|
||||
// this is just a workaround:
|
||||
return getRawTableName()
|
||||
.replace("hs_office_", "hsof_")
|
||||
.replace("hs_office.", "hsof.")
|
||||
.replace("hs_booking_", "hsbk_")
|
||||
.replace("hs_hosting_", "hsho_")
|
||||
.replace("coopsharestransaction", "coopsharetx")
|
||||
@@ -1274,13 +1273,14 @@ public class RbacView {
|
||||
|
||||
public static Set<Class<? extends BaseEntity>> findRbacEntityClasses(String packageName) {
|
||||
final var reflections = new Reflections(packageName, TypeAnnotationsScanner.class);
|
||||
return reflections.getTypesAnnotatedWith(Entity.class).stream()
|
||||
.filter(c -> stream(c.getInterfaces()).anyMatch(i -> i== BaseEntity.class))
|
||||
final Set<Class<? extends BaseEntity>> rbacEntityClasses = reflections.getTypesAnnotatedWith(Entity.class).stream()
|
||||
.filter(BaseEntity.class::isAssignableFrom)
|
||||
.filter(c -> stream(c.getDeclaredMethods())
|
||||
.anyMatch(m -> m.getName().equals("rbac") && Modifier.isStatic(m.getModifiers()))
|
||||
.anyMatch(m -> m.getName().equals("rbac") && isStatic(m.getModifiers()))
|
||||
)
|
||||
.map(RbacView::castToSubclassOfBaseEntity)
|
||||
.collect(Collectors.toSet());
|
||||
return rbacEntityClasses;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
+38
-35
@@ -29,7 +29,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
private final String liquibaseTagPrefix;
|
||||
private final String simpleEntityName;
|
||||
private final String simpleEntityVarName;
|
||||
private final String rawTableName;
|
||||
private final String qualifiedRawTableName;
|
||||
|
||||
RolesGrantsAndPermissionsGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) {
|
||||
this.rbacDef = rbacDef;
|
||||
@@ -40,7 +40,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
|
||||
simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
|
||||
simpleEntityName = capitalize(simpleEntityVarName);
|
||||
rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
|
||||
qualifiedRawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
|
||||
}
|
||||
|
||||
void generateTo(final StringWriter plPgSql) {
|
||||
@@ -66,13 +66,12 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemFor${simpleEntityName}(
|
||||
NEW ${rawTableName}
|
||||
create or replace procedure ${rawTableQualifiedName}_build_rbac_system(
|
||||
NEW ${rawTableQualifiedName}
|
||||
)
|
||||
language plpgsql as $$
|
||||
"""
|
||||
.replace("${simpleEntityName}", simpleEntityName)
|
||||
.replace("${rawTableName}", rawTableName));
|
||||
.replace("${rawTableQualifiedName}", qualifiedRawTableName));
|
||||
|
||||
plPgSql.writeLn("declare");
|
||||
plPgSql.indented(() -> {
|
||||
@@ -106,21 +105,21 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
|
||||
*/
|
||||
|
||||
create or replace procedure updateRbacRulesFor${simpleEntityName}(
|
||||
OLD ${rawTableName},
|
||||
NEW ${rawTableName}
|
||||
create or replace procedure ${rawTableQualifiedName}_update_rbac_system(
|
||||
OLD ${rawTableQualifiedName},
|
||||
NEW ${rawTableQualifiedName}
|
||||
)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
|
||||
if ${updateConditions} then
|
||||
delete from rbac.grants g where g.grantedbytriggerof = OLD.uuid;
|
||||
call buildRbacSystemFor${simpleEntityName}(NEW);
|
||||
call ${rawTableQualifiedName}_build_rbac_system(NEW);
|
||||
end if;
|
||||
end; $$;
|
||||
""",
|
||||
with("simpleEntityName", simpleEntityName),
|
||||
with("rawTableName", rawTableName),
|
||||
with("rawTableQualifiedName", qualifiedRawTableName),
|
||||
with("updateConditions", updateConditions));
|
||||
}
|
||||
|
||||
@@ -130,16 +129,15 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
|
||||
*/
|
||||
|
||||
create or replace procedure updateRbacRulesFor${simpleEntityName}(
|
||||
OLD ${rawTableName},
|
||||
NEW ${rawTableName}
|
||||
create or replace procedure ${rawTableQualifiedName}_update_rbac_system(
|
||||
OLD ${rawTableQualifiedName},
|
||||
NEW ${rawTableQualifiedName}
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
"""
|
||||
.replace("${simpleEntityName}", simpleEntityName)
|
||||
.replace("${rawTableName}", rawTableName));
|
||||
""",
|
||||
with("rawTableQualifiedName", qualifiedRawTableName));
|
||||
|
||||
plPgSql.chopEmptyLines();
|
||||
plPgSql.indented(() -> {
|
||||
@@ -514,25 +512,25 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
|
||||
plPgSql.writeLn("""
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new ${rawTableName} row.
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new ${rawTableQualifiedName} row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerFor${simpleEntityName}_tf()
|
||||
create or replace function ${rawTableQualifiedName}_build_rbac_system_after_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemFor${simpleEntityName}(NEW);
|
||||
call ${rawTableQualifiedName}_build_rbac_system(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerFor${simpleEntityName}_tg
|
||||
after insert on ${rawTableName}
|
||||
create trigger build_rbac_system_after_insert_tg
|
||||
after insert on ${rawTableQualifiedName}
|
||||
for each row
|
||||
execute procedure insertTriggerFor${simpleEntityName}_tf();
|
||||
execute procedure ${rawTableQualifiedName}_build_rbac_system_after_insert_tf();
|
||||
"""
|
||||
.replace("${simpleEntityName}", simpleEntityName)
|
||||
.replace("${rawTableName}", rawTableName)
|
||||
.replace("${schemaPrefix}", schemaPrefix(qualifiedRawTableName))
|
||||
.replace("${rawTableQualifiedName}", qualifiedRawTableName)
|
||||
);
|
||||
|
||||
generateFooter(plPgSql);
|
||||
@@ -549,30 +547,35 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
|
||||
plPgSql.writeLn("""
|
||||
/*
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new ${rawTableName} row.
|
||||
AFTER UPDATE TRIGGER to re-wire the grant structure for a new ${rawTableQualifiedName} row.
|
||||
*/
|
||||
|
||||
create or replace function updateTriggerFor${simpleEntityName}_tf()
|
||||
|
||||
create or replace function ${rawTableQualifiedName}_update_rbac_system_after_update_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call updateRbacRulesFor${simpleEntityName}(OLD, NEW);
|
||||
call ${rawTableQualifiedName}_update_rbac_system(OLD, NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger updateTriggerFor${simpleEntityName}_tg
|
||||
after update on ${rawTableName}
|
||||
|
||||
create trigger update_rbac_system_after_update_tg
|
||||
after update on ${rawTableQualifiedName}
|
||||
for each row
|
||||
execute procedure updateTriggerFor${simpleEntityName}_tf();
|
||||
execute procedure ${rawTableQualifiedName}_update_rbac_system_after_update_tf();
|
||||
"""
|
||||
.replace("${simpleEntityName}", simpleEntityName)
|
||||
.replace("${rawTableName}", rawTableName)
|
||||
.replace("${rawTableQualifiedName}", qualifiedRawTableName)
|
||||
);
|
||||
|
||||
generateFooter(plPgSql);
|
||||
}
|
||||
|
||||
private String schemaPrefix(final String qualifiedIdentifier) {
|
||||
return qualifiedIdentifier.contains(".")
|
||||
? qualifiedIdentifier.split("\\.")[0] + "."
|
||||
: "";
|
||||
}
|
||||
|
||||
private static void generateFooter(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("--//");
|
||||
plPgSql.writeLn();
|
||||
|
||||
Reference in New Issue
Block a user