move Parter+Debitor person+contact to related Relationsship #20
@ -13,7 +13,10 @@ public interface HsOfficeDebitorRepository extends Repository<HsOfficeDebitorEnt
|
||||
|
||||
@Query("""
|
||||
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
||||
WHERE cast(debitor.partner.partnerNumber as integer) = :partnerNumber
|
||||
JOIN HsOfficePartnerEntity partner
|
||||
ON partner.partnerRole.relHolder = debitor.debitorRel.relAnchor
|
||||
AND partner.partnerRole.relType = 'PARTNER' AND debitor.debitorRel.relType = 'ACCOUNTING'
|
||||
WHERE cast(partner.partnerNumber as integer) = :partnerNumber
|
||||
AND cast(debitor.debitorNumberSuffix as integer) = :debitorNumberSuffix
|
||||
""")
|
||||
List<HsOfficeDebitorEntity> findDebitorByDebitorNumber(int partnerNumber, byte debitorNumberSuffix);
|
||||
@ -24,11 +27,15 @@ public interface HsOfficeDebitorRepository extends Repository<HsOfficeDebitorEnt
|
||||
|
||||
@Query("""
|
||||
SELECT debitor FROM HsOfficeDebitorEntity debitor
|
||||
JOIN HsOfficePartnerEntity partner ON partner.uuid = debitor.partner.uuid
|
||||
JOIN HsOfficeRelationshipEntity rel ON rel.uuid = partner.partnerRole.uuid
|
||||
JOIN HsOfficePersonEntity person ON person.uuid = rel.relHolder.uuid
|
||||
JOIN HsOfficePartnerEntity partner
|
||||
ON partner.partnerRole.relHolder = debitor.debitorRel.relAnchor
|
||||
AND partner.partnerRole.relType = 'PARTNER' AND debitor.debitorRel.relType = 'ACCOUNTING'
|
||||
JOIN HsOfficePersonEntity person
|
||||
ON person.uuid = partner.partnerRole.relHolder.uuid
|
||||
OR person.uuid = debitor.debitorRel.relHolder.uuid
|
||||
JOIN HsOfficeContactEntity contact
|
||||
ON contact.uuid = debitor.billingContact.uuid OR contact.uuid = rel.contact.uuid
|
||||
ON contact.uuid = debitor.debitorRel.contact.uuid
|
||||
OR contact.uuid = partner.partnerRole.contact.uuid
|
||||
WHERE :name is null
|
||||
OR partner.details.birthName like concat(cast(:name as text), '%')
|
||||
OR person.tradeName like concat(cast(:name as text), '%')
|
||||
|
@ -71,11 +71,12 @@ public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
|
||||
public static RbacView rbac() {
|
||||
return rbacViewFor("partnerDetails", HsOfficePartnerDetailsEntity.class)
|
||||
.withIdentityView(SQL.query("""
|
||||
SELECT partner_iv.idName || '-details'
|
||||
SELECT partnerDetails.uuid as uuid, partner_iv.idName || '-details' 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
|
||||
"""))
|
||||
.withRestrictedViewOrderBy(SQL.expression("uuid"))
|
||||
.withUpdatableColumns(
|
||||
"registrationOffice",
|
||||
"registrationNumber",
|
||||
@ -83,17 +84,7 @@ public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
|
||||
"birthName",
|
||||
"birthday",
|
||||
"dateOfDeath")
|
||||
.toRole("global", ADMIN).grantPermission("partner-details", INSERT)
|
||||
|
||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationshipEntity.class,
|
||||
fetchedBySql("""
|
||||
SELECT partnerRel.*
|
||||
FROM hs_office_relationship AS partnerRel
|
||||
JOIN hs_office_partner AS partner
|
||||
ON partner.detailsUuid = ${ref}.uuid
|
||||
WHERE partnerRel.uuid = partner.partnerRoleUuid
|
||||
"""),
|
||||
dependsOnColumn("partnerRoleUuid"))
|
||||
.toRole("global", ADMIN).grantPermission("partnerDetails", INSERT)
|
||||
|
||||
// The grants are defined in HsOfficePartnerEntity.rbac()
|
||||
// because they have to be changed when its partnerRel changes,
|
||||
@ -102,6 +93,6 @@ public class HsOfficePartnerDetailsEntity implements HasUuid, Stringifyable {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
rbac().generateWithBaseFileName("234-hs-office-partner-details-rbac-generated");
|
||||
rbac().generateWithBaseFileName("234-hs-office-partner-details-rbac");
|
||||
}
|
||||
}
|
||||
|
@ -94,16 +94,8 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
||||
|
||||
public static RbacView rbac() {
|
||||
return rbacViewFor("partner", HsOfficePartnerEntity.class)
|
||||
.withIdentityView(SQL.query("""
|
||||
SELECT partner.partnerNumber
|
||||
|| ':' || (SELECT idName FROM hs_office_person_iv p WHERE p.uuid = partner.personUuid)
|
||||
|| '-' || (SELECT idName FROM hs_office_contact_iv c WHERE c.uuid = partner.contactUuid)
|
||||
FROM hs_office_partner AS partner
|
||||
"""))
|
||||
.withUpdatableColumns(
|
||||
"partnerRoleUuid",
|
||||
"personUuid",
|
||||
"contactUuid")
|
||||
.withIdentityView(SQL.projection("'P-' || partnerNumber"))
|
||||
.withUpdatableColumns("partnerroleuuid")
|
||||
.toRole("global", ADMIN).grantPermission("partner", INSERT) // FIXME: global -> partnerRel.relAnchor?
|
||||
|
||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationshipEntity.class,
|
||||
@ -122,6 +114,6 @@ public class HsOfficePartnerEntity implements Stringifyable, HasUuid {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
rbac().generateWithBaseFileName("233-hs-office-partner-rbac-generated");
|
||||
rbac().generateWithBaseFileName("233-hs-office-partner-rbac");
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hibernate.annotations.JoinFormula;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
@ -55,15 +56,17 @@ public class HsOfficePersonEntity implements HasUuid, Stringifyable {
|
||||
@Column(name = "givenname")
|
||||
private String givenName;
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL)
|
||||
@JoinTable(name = "hs_office_relationship",
|
||||
joinColumns =
|
||||
{ @JoinColumn(name = "uuid", referencedColumnName = "relanchoruuid") },
|
||||
inverseJoinColumns =
|
||||
{ @JoinColumn(name = "relanchoruuid", referencedColumnName = "uuid") })
|
||||
private HsOfficePartnerEntity optionalPartner;
|
||||
|
||||
@Override
|
||||
@ManyToOne(cascade = CascadeType.ALL)
|
||||
@JoinFormula(
|
||||
referencedColumnName = "uuid",
|
||||
value = """
|
||||
(SELECT partner.uuid AS uuid
|
||||
FROM hs_office_partner partner
|
||||
JOIN hs_office_relationship partnerRel
|
||||
ON partnerRel.uuid = partner.partnerRoleUuid AND partnerRel.relType = 'PARTNER'
|
||||
WHERE partnerRel.relHolderUuid = h1_0.uuid)
|
||||
""") // FIXME: h1_0 is the generated self-reference, I should find a better solution
|
||||
private HsOfficePartnerEntity optionalPartner; @Override
|
||||
public String toString() {
|
||||
return toString.apply(this);
|
||||
}
|
||||
|
@ -698,6 +698,7 @@ declare
|
||||
superRoleId uuid;
|
||||
subRoleId uuid;
|
||||
begin
|
||||
if ( superRoleId is null ) then return; end if;
|
||||
superRoleId := findRoleId(superRole);
|
||||
if ( subRoleId is null ) then return; end if;
|
||||
subRoleId := findRoleId(subRole);
|
||||
|
45
src/main/resources/db/changelog/213-hs-office-person-rbac.md
Normal file
45
src/main/resources/db/changelog/213-hs-office-person-rbac.md
Normal file
@ -0,0 +1,45 @@
|
||||
### rbac person
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-13T15:28:12.347550922.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph person["`**person**`"]
|
||||
direction TB
|
||||
style person fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph person:roles[ ]
|
||||
style person:roles fill:#dd4901,stroke:white
|
||||
|
||||
role:person:owner[[person:owner]]
|
||||
role:person:admin[[person:admin]]
|
||||
role:person:referrer[[person:referrer]]
|
||||
end
|
||||
|
||||
subgraph person:permissions[ ]
|
||||
style person:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:person:INSERT{{person:INSERT}}
|
||||
perm:person:DELETE{{person:DELETE}}
|
||||
perm:person:UPDATE{{person:UPDATE}}
|
||||
perm:person:SELECT{{person:SELECT}}
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to users
|
||||
user:creator ==> role:person:owner
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:admin ==> role:person:owner
|
||||
role:person:owner ==> role:person:admin
|
||||
role:person:admin ==> role:person:referrer
|
||||
|
||||
%% granting permissions to roles
|
||||
role:global:guest ==> perm:person:INSERT
|
||||
role:person:owner ==> perm:person:DELETE
|
||||
role:person:admin ==> perm:person:UPDATE
|
||||
role:person:referrer ==> perm:person:SELECT
|
||||
|
||||
```
|
@ -1,5 +1,6 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-11T15:13:04.479330676.
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-13T15:28:12.357028926.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-OBJECT:1 endDelimiter:--//
|
||||
@ -72,9 +73,9 @@ create trigger insertTriggerForHsOfficePerson_tg
|
||||
after insert on hs_office_person
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficePerson_tf();
|
||||
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
@ -108,8 +109,8 @@ create or replace function hs_office_person_global_insert_tf()
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_person'),
|
||||
globalGuest());
|
||||
globalGuest(),
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_person'));
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
@ -128,8 +129,8 @@ begin
|
||||
raise exception '[403] insert into hs_office_person not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
@ -137,19 +138,20 @@ end; $$;
|
||||
call generateRbacIdentityViewFromProjection('hs_office_person', $idName$
|
||||
concat(tradeName, familyName, givenName)
|
||||
$idName$);
|
||||
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_person',
|
||||
'concat(tradeName, familyName, givenName)',
|
||||
$orderBy$
|
||||
concat(tradeName, familyName, givenName)
|
||||
$orderBy$,
|
||||
$updates$
|
||||
personType = new.personType,
|
||||
personType = new.personType,
|
||||
tradeName = new.tradeName,
|
||||
givenName = new.givenName,
|
||||
familyName = new.familyName
|
||||
$updates$);
|
||||
--//
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
### rbac partner
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-11T15:29:41.494727519.
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-13T15:28:17.873062752.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
@ -26,7 +26,7 @@ subgraph partner["`**partner**`"]
|
||||
subgraph partner:permissions[ ]
|
||||
style partner:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:partner:new-partner{{partner:new-partner}}
|
||||
perm:partner:INSERT{{partner:INSERT}}
|
||||
perm:partner:DELETE{{partner:DELETE}}
|
||||
perm:partner:UPDATE{{partner:UPDATE}}
|
||||
perm:partner:SELECT{{partner:SELECT}}
|
||||
@ -147,7 +147,7 @@ role:partnerRel:tenant -.-> role:partnerRel.holderPerson:referrer
|
||||
role:partnerRel:tenant -.-> role:partnerRel.contact:referrer
|
||||
|
||||
%% granting permissions to roles
|
||||
role:global:admin ==> perm:partner:new-partner
|
||||
role:global:admin ==> perm:partner:INSERT
|
||||
role:partnerRel:admin ==> perm:partner:DELETE
|
||||
role:partnerRel:agent ==> perm:partner:UPDATE
|
||||
role:partnerRel:tenant ==> perm:partner:SELECT
|
||||
|
@ -1,4 +1,6 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-13T15:28:17.881206014.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-OBJECT:1 endDelimiter:--//
|
||||
@ -8,245 +10,147 @@ call generateRelatedRbacObject('hs_office_partner');
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-ROLES-CREATION:1 endDelimiter:--//
|
||||
--changeset hs-office-partner-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates and updates the roles and their assignments for partner entities.
|
||||
*/
|
||||
|
||||
create or replace function hsOfficePartnerRbacRolesTrigger()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
declare
|
||||
partnerUuid uuid default new.uuid;
|
||||
partnerDetailsUuid uuid default new.detailsUuid;
|
||||
oldPartnerRel hs_office_relationship;
|
||||
newPartnerRel hs_office_relationship;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
select * from hs_office_relationship as r where r.uuid = NEW.partnerroleuuid into newPartnerRel;
|
||||
|
||||
if TG_OP = 'INSERT' then
|
||||
|
||||
-- Permissions and Grants for Partner
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipOwner(newPartnerRel)),
|
||||
createPermissions(partnerUuid, array ['DELETE'])
|
||||
);
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipAdmin(newPartnerRel)),
|
||||
createPermissions(partnerUuid, array ['UPDATE'])
|
||||
);
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipTenant(newPartnerRel)),
|
||||
createPermissions(partnerUuid, array ['SELECT'])
|
||||
);
|
||||
|
||||
-- Permissions and Grants for PartnerDetails
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipOwner(newPartnerRel)),
|
||||
createPermissions(partnerDetailsUuid, array ['DELETE'])
|
||||
);
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipAdmin(newPartnerRel)),
|
||||
createPermissions(partnerDetailsUuid, array ['UPDATE'])
|
||||
);
|
||||
|
||||
call grantPermissionsToRole(
|
||||
-- Yes, here hsOfficePartnerAGENT is used, not hsOfficeRelationshipTENANT.
|
||||
-- Do NOT grant view permission on partner-details to hsOfficeRelationshipTENANT!
|
||||
-- Otherwise package-admins etc. would be able to read the data.
|
||||
getRoleId(hsOfficeRelationshipAgent(newPartnerRel)),
|
||||
createPermissions(partnerDetailsUuid, array ['SELECT'])
|
||||
);
|
||||
|
||||
|
||||
elsif TG_OP = 'UPDATE' then
|
||||
|
||||
if OLD.partnerRoleUuid <> NEW.partnerRoleUuid then
|
||||
select * from hs_office_relationship as r where r.uuid = OLD.partnerRoleUuid into oldPartnerRel;
|
||||
|
||||
-- Revokes from Partner
|
||||
|
||||
call revokePermissionFromRole(
|
||||
findPermissionId(partnerUuid, 'SELECT'),
|
||||
hsOfficeRelationshipTenant(oldPartnerRel)
|
||||
);
|
||||
|
||||
-- call revokePermissionFromRole(
|
||||
-- findPermissionId(partnerUuid, 'edit'),
|
||||
-- hsOfficeRelationshipAdmin(oldPartnerRel)
|
||||
-- );
|
||||
--
|
||||
-- call revokePermissionFromRole(
|
||||
-- findPermissionId(partnerUuid, '*'),
|
||||
-- hsOfficeRelationshipOwner(oldPartnerRel)
|
||||
-- );
|
||||
|
||||
-- Grants for Partner
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipOwner(newPartnerRel)),
|
||||
array[findPermissionId(partnerUuid, 'DELETE')]
|
||||
);
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipAdmin(newPartnerRel)),
|
||||
array[findPermissionId(partnerUuid, 'UPDATE')]
|
||||
);
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipTenant(newPartnerRel)),
|
||||
array[findPermissionId(partnerUuid, 'SELECT')]
|
||||
);
|
||||
|
||||
-- Revokes from PartnerDetails
|
||||
|
||||
-- call revokePermissionFromRole(
|
||||
-- findPermissionId(partnerDetailsUuid, 'SELECT'),
|
||||
-- hsOfficeRelationshipAgent(oldPartnerRel)
|
||||
-- );
|
||||
--
|
||||
-- call revokePermissionFromRole(
|
||||
-- findPermissionId(partnerDetailsUuid, 'UPDATE'),
|
||||
-- hsOfficeRelationshipAdmin(oldPartnerRel)
|
||||
-- );
|
||||
--
|
||||
-- call revokePermissionFromRole(
|
||||
-- findPermissionId(partnerDetailsUuid, 'DELETE'),
|
||||
-- hsOfficeRelationshipOwner(oldPartnerRel)
|
||||
-- );
|
||||
|
||||
-- Grants for PartnerDetails
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipOwner(newPartnerRel)),
|
||||
array[findPermissionId(partnerDetailsUuid, 'DELETE')]
|
||||
);
|
||||
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeRelationshipAdmin(newPartnerRel)),
|
||||
array[findPermissionId(partnerDetailsUuid, 'UPDATE')]
|
||||
);
|
||||
|
||||
call grantPermissionsToRole(
|
||||
-- Yes, here hsOfficePartnerAGENT is used, not hsOfficePartnerTENANT.
|
||||
-- Do NOT grant view permission on partner-details to hsOfficeRelationshipTENANT!
|
||||
-- Otherwise package-admins etc. would be able to read the data.
|
||||
getRoleId(hsOfficeRelationshipAgent(newPartnerRel)),
|
||||
array[findPermissionId(partnerDetailsUuid, 'SELECT')]
|
||||
);
|
||||
|
||||
end if;
|
||||
|
||||
else
|
||||
raise exception 'invalid usage of TRIGGER';
|
||||
end if;
|
||||
|
||||
call leaveTriggerForObjectUuid(partnerUuid);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
An AFTER INSERT TRIGGER which creates the role structure for a new customer.
|
||||
*/
|
||||
create trigger createRbacRolesForHsOfficePartner_Trigger
|
||||
after insert
|
||||
on hs_office_partner
|
||||
for each row
|
||||
execute procedure hsOfficePartnerRbacRolesTrigger();
|
||||
|
||||
/*
|
||||
An AFTER UPDATE TRIGGER which updates the role structure of a customer.
|
||||
*/
|
||||
create trigger updateRbacRolesForHsOfficePartner_Trigger
|
||||
after update
|
||||
on hs_office_partner
|
||||
for each row
|
||||
execute procedure hsOfficePartnerRbacRolesTrigger();
|
||||
call generateRbacRoleDescriptors('hsOfficePartner', 'hs_office_partner');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
--changeset hs-office-partner-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityViewFromProjection('hs_office_partner', $idName$
|
||||
partnerNumber || ':' ||
|
||||
(select idName
|
||||
from hs_office_person_iv p
|
||||
left join hs_office_relationship r on r.uuid = target.partnerRoleUuid
|
||||
where p.uuid = r.relHolderUuid)
|
||||
|| '-' ||
|
||||
(select idName
|
||||
from hs_office_contact_iv c
|
||||
left join hs_office_relationship r on r.uuid = target.partnerRoleUuid
|
||||
where c.uuid = r.contactUuid)
|
||||
$idName$);
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficePartner(
|
||||
NEW hs_office_partner
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
newPartnerRel hs_office_relationship;
|
||||
newPartnerDetails hs_office_partner_details;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM hs_office_relationship AS r WHERE r.uuid = NEW.partnerRoleUuid INTO newPartnerRel;
|
||||
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerRelUuid = %s', NEW.partnerRelUuid);
|
||||
|
||||
SELECT * FROM hs_office_partner_details AS d WHERE d.uuid = NEW.detailsUuid INTO newPartnerDetails;
|
||||
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid);
|
||||
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationshipAdmin(newPartnerRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationshipTenant(newPartnerRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationshipAgent(newPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationshipAdmin(newPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'SELECT'), hsOfficeRelationshipAgent(newPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationshipAgent(newPartnerRel));
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_partner row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficePartner_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficePartner(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForHsOfficePartner_tg
|
||||
after insert on hs_office_partner
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficePartner_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_partner permissions for the related global rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_partner permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
roleUuid := findRoleId(globalAdmin());
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_partner');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_partner INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function hs_office_partner_global_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
globalAdmin(),
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_partner'));
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_partner_global_insert_tg
|
||||
after insert on global
|
||||
for each row
|
||||
execute procedure hs_office_partner_global_insert_tf();
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_partner.
|
||||
*/
|
||||
create or replace function hs_office_partner_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into hs_office_partner not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_partner_insert_permission_check_tg
|
||||
before insert on hs_office_partner
|
||||
for each row
|
||||
when ( not isGlobalAdmin() )
|
||||
execute procedure hs_office_partner_insert_permission_missing_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityViewFromProjection('hs_office_partner', $idName$
|
||||
'P-' || partnerNumber
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_partner',
|
||||
'target.partnerNumber',
|
||||
$orderBy$
|
||||
'P-' || partnerNumber
|
||||
$orderBy$,
|
||||
$updates$
|
||||
partnerRoleUuid = new.partnerRoleUuid
|
||||
partnerroleuuid = new.partnerroleuuid
|
||||
$updates$);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-NEW-PARTNER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Creates a global permission for new-partner and assigns it to the Hostsharing admins role.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
addCustomerPermissions uuid[];
|
||||
globalObjectUuid uuid;
|
||||
globalAdminRoleUuid uuid ;
|
||||
begin
|
||||
call defineContext('granting global new-partner permission to global admin role', null, null, null);
|
||||
|
||||
globalAdminRoleUuid := findRoleId(globalAdmin());
|
||||
globalObjectUuid := (select uuid from global);
|
||||
addCustomerPermissions := createPermissions(globalObjectUuid, array ['new-partner']);
|
||||
call grantPermissionsToRole(globalAdminRoleUuid, addCustomerPermissions);
|
||||
end;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Used by the trigger to prevent the add-customer to current user respectively assumed roles.
|
||||
*/
|
||||
create or replace function addHsOfficePartnerNotAllowedForCurrentSubjects()
|
||||
returns trigger
|
||||
language PLPGSQL
|
||||
as $$
|
||||
begin
|
||||
raise exception '[403] new-partner not permitted for %',
|
||||
array_to_string(currentSubjects(), ';', 'null');
|
||||
end; $$;
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to create a new customer.
|
||||
*/
|
||||
create trigger hs_office_partner_insert_trigger
|
||||
before insert
|
||||
on hs_office_partner
|
||||
for each row
|
||||
-- TODO.spec: who is allowed to create new partners
|
||||
when ( not hasAssumedRole() )
|
||||
execute procedure addHsOfficePartnerNotAllowedForCurrentSubjects();
|
||||
--//
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
### rbac partnerDetails
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator at 2024-03-13T15:35:19.438833295.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph partnerDetails["`**partnerDetails**`"]
|
||||
direction TB
|
||||
style partnerDetails fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerDetails:permissions[ ]
|
||||
style partnerDetails:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:partnerDetails:INSERT{{partnerDetails:INSERT}}
|
||||
end
|
||||
end
|
||||
|
||||
%% granting permissions to roles
|
||||
role:global:admin ==> perm:partnerDetails:INSERT
|
||||
|
||||
```
|
@ -1,4 +1,6 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator at 2024-03-13T15:35:19.446996853.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-details-rbac-OBJECT:1 endDelimiter:--//
|
||||
@ -8,76 +10,141 @@ call generateRelatedRbacObject('hs_office_partner_details');
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-details-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
--changeset hs-office-partner-details-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacIdentityViewFromProjection('hs_office_partner_details', $idName$
|
||||
(select idName || '-details' from hs_office_partner_iv partner_iv
|
||||
join hs_office_partner partner on (partner_iv.uuid = partner.uuid)
|
||||
where partner.detailsUuid = target.uuid)
|
||||
$idName$);
|
||||
call generateRbacRoleDescriptors('hsOfficePartnerDetails', 'hs_office_partner_details');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-details-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficePartnerDetails(
|
||||
NEW hs_office_partner_details
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_partner_details row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficePartnerDetails_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficePartnerDetails(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForHsOfficePartnerDetails_tg
|
||||
after insert on hs_office_partner_details
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficePartnerDetails_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-details-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_partner_details permissions for the related global rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_partner_details permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
roleUuid := findRoleId(globalAdmin());
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_partner_details');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_partner_details INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function hs_office_partner_details_global_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
globalAdmin(),
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_partner_details'));
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_partner_details_global_insert_tg
|
||||
after insert on global
|
||||
for each row
|
||||
execute procedure hs_office_partner_details_global_insert_tf();
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_partner_details.
|
||||
*/
|
||||
create or replace function hs_office_partner_details_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into hs_office_partner_details not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_partner_details_insert_permission_check_tg
|
||||
before insert on hs_office_partner_details
|
||||
for each row
|
||||
when ( not isGlobalAdmin() )
|
||||
execute procedure hs_office_partner_details_insert_permission_missing_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-details-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityViewFromQuery('hs_office_partner_details', $idName$
|
||||
SELECT partnerDetails.uuid as uuid, partner_iv.idName || '-details' 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
|
||||
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-details-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_partner_details',
|
||||
'target.uuid', -- no specific order required
|
||||
$orderBy$
|
||||
uuid
|
||||
$orderBy$,
|
||||
$updates$
|
||||
registrationOffice = new.registrationOffice,
|
||||
registrationOffice = new.registrationOffice,
|
||||
registrationNumber = new.registrationNumber,
|
||||
birthPlace = new.birthPlace,
|
||||
birthName = new.birthName,
|
||||
birthday = new.birthday,
|
||||
dateOfDeath = new.dateOfDeath
|
||||
birthPlace = new.birthPlace,
|
||||
birthName = new.birthName,
|
||||
birthday = new.birthday,
|
||||
dateOfDeath = new.dateOfDeath
|
||||
$updates$);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-details-rbac-NEW-PARTNER-DETAILS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Creates a global permission for new-partner-details and assigns it to the hostsharing admins role.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
addCustomerPermissions uuid[];
|
||||
globalObjectUuid uuid;
|
||||
globalAdminRoleUuid uuid ;
|
||||
begin
|
||||
call defineContext('granting global new-partner-details permission to global admin role', null, null, null);
|
||||
|
||||
globalAdminRoleUuid := findRoleId(globalAdmin());
|
||||
globalObjectUuid := (select uuid from global);
|
||||
addCustomerPermissions := createPermissions(globalObjectUuid, array ['new-partner-details']);
|
||||
call grantPermissionsToRole(globalAdminRoleUuid, addCustomerPermissions);
|
||||
end;
|
||||
$$;
|
||||
|
||||
-- TODO.refa: the code below could be moved to a generator, maybe even the code above.
|
||||
-- Additionally, the code below is not necessary for all entities, specify when it is!
|
||||
|
||||
/**
|
||||
Used by the trigger to prevent the add-partner-details to current user respectively assumed roles.
|
||||
*/
|
||||
create or replace function addHsOfficePartnerDetailsNotAllowedForCurrentSubjects()
|
||||
returns trigger
|
||||
language PLPGSQL
|
||||
as $$
|
||||
begin
|
||||
raise exception '[403] new-partner-details not permitted for %',
|
||||
array_to_string(currentSubjects(), ';', 'null');
|
||||
end; $$;
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to create new partner-details.
|
||||
*/
|
||||
create trigger hs_office_partner_details_insert_trigger
|
||||
before insert
|
||||
on hs_office_partner_details
|
||||
for each row
|
||||
when ( not hasAssumedRole() )
|
||||
execute procedure addHsOfficePartnerDetailsNotAllowedForCurrentSubjects();
|
||||
--//
|
||||
|
||||
|
@ -42,7 +42,7 @@ begin
|
||||
|
||||
-- coopsharestransactions cannot be edited nor deleted, just created+viewed
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeMembershipTenant(newHsOfficeMembership)),
|
||||
getRoleId(hsOfficeMembershipReferrer(newHsOfficeMembership)),
|
||||
createPermissions(NEW.uuid, array ['SELECT'])
|
||||
);
|
||||
|
||||
|
@ -42,7 +42,7 @@ begin
|
||||
|
||||
-- coopassetstransactions cannot be edited nor deleted, just created+viewed
|
||||
call grantPermissionsToRole(
|
||||
getRoleId(hsOfficeMembershipTenant(newHsOfficeMembership)),
|
||||
getRoleId(hsOfficeMembershipReferrer(newHsOfficeMembership)),
|
||||
createPermissions(NEW.uuid, array ['SELECT'])
|
||||
);
|
||||
|
||||
|
@ -286,7 +286,6 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
"hs_office_person#ErbenBesslerMelBessler.admin");
|
||||
assertThatPartnerActuallyInDatabase(givenPartner);
|
||||
|
||||
|
||||
// when
|
||||
final var result = jpaAttempt.transacted(() -> {
|
||||
context("superuser-alex@hostsharing.net");
|
||||
@ -332,7 +331,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
|
||||
private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) {
|
||||
final var found = partnerRepo.findByUuid(saved.getUuid());
|
||||
assertThat(found).isNotEmpty().get().isNotSameAs(saved).usingRecursiveComparison().isEqualTo(saved);
|
||||
assertThat(found).isNotEmpty().get().isNotSameAs(saved).extracting(HsOfficePartnerEntity::toString).isEqualTo(saved.toString());
|
||||
}
|
||||
|
||||
private void assertThatPartnerIsVisibleForUserWithRole(
|
||||
|
@ -110,11 +110,9 @@ class HsOfficePersonRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
||||
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(
|
||||
Array.from(
|
||||
initialGrantNames,
|
||||
"{ grant perm * on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.owner by system and assume }",
|
||||
"{ grant role hs_office_person#anothernewperson.owner to user selfregistered-user-drew@hostsharing.org by global#global.admin and assume }",
|
||||
"{ grant role hs_office_person#anothernewperson.owner to user selfregistered-user-drew@hostsharing.org by hs_office_person#anothernewperson.owner and assume }",
|
||||
"{ grant role hs_office_person#anothernewperson.owner to role global#global.admin by system and assume }",
|
||||
"{ grant perm UPDATE on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.admin by system and assume }",
|
||||
"{ grant role hs_office_person#anothernewperson.tenant to role hs_office_person#anothernewperson.admin by system and assume }",
|
||||
"{ grant perm DELETE on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.owner by system and assume }",
|
||||
"{ grant role hs_office_person#anothernewperson.admin to role hs_office_person#anothernewperson.owner by system and assume }",
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user