structured-liquibase-files (#29)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/29 Reviewed-by: Timotheus Pokorra <timotheus.pokorra@hostsharing.net>
This commit is contained in:
@ -0,0 +1,23 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-MAIN-TABLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create table if not exists hs_office_contact
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||
label varchar(128) not null,
|
||||
postalAddress text,
|
||||
emailAddresses text, -- TODO.feat: change to json
|
||||
phoneNumbers text -- TODO.feat: change to json
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call create_journal('hs_office_contact');
|
||||
--//
|
@ -0,0 +1,45 @@
|
||||
### rbac contact
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph contact["`**contact**`"]
|
||||
direction TB
|
||||
style contact fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph contact:roles[ ]
|
||||
style contact:roles fill:#dd4901,stroke:white
|
||||
|
||||
role:contact:OWNER[[contact:OWNER]]
|
||||
role:contact:ADMIN[[contact:ADMIN]]
|
||||
role:contact:REFERRER[[contact:REFERRER]]
|
||||
end
|
||||
|
||||
subgraph contact:permissions[ ]
|
||||
style contact:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:contact:DELETE{{contact:DELETE}}
|
||||
perm:contact:UPDATE{{contact:UPDATE}}
|
||||
perm:contact:SELECT{{contact:SELECT}}
|
||||
perm:contact:INSERT{{contact:INSERT}}
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to users
|
||||
user:creator ==> role:contact:OWNER
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:ADMIN ==> role:contact:OWNER
|
||||
role:contact:OWNER ==> role:contact:ADMIN
|
||||
role:contact:ADMIN ==> role:contact:REFERRER
|
||||
|
||||
%% granting permissions to roles
|
||||
role:contact:OWNER ==> perm:contact:DELETE
|
||||
role:contact:ADMIN ==> perm:contact:UPDATE
|
||||
role:contact:REFERRER ==> perm:contact:SELECT
|
||||
role:global:GUEST ==> perm:contact:INSERT
|
||||
|
||||
```
|
@ -0,0 +1,146 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-rbac-OBJECT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('hs_office_contact');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('hsOfficeContact', 'hs_office_contact');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficeContact(
|
||||
NEW hs_office_contact
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeContactOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalADMIN()],
|
||||
userUuids => array[currentUserUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeContactADMIN(NEW),
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[hsOfficeContactOWNER(NEW)]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeContactREFERRER(NEW),
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[hsOfficeContactADMIN(NEW)]
|
||||
);
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_contact row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficeContact_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficeContact(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForHsOfficeContact_tg
|
||||
after insert on hs_office_contact
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficeContact_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_contact permissions for the related global rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_contact permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_contact'),
|
||||
globalGUEST());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_contact INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function hs_office_contact_global_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_contact'),
|
||||
globalGUEST());
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_hs_office_contact_global_insert_tg
|
||||
after insert on global
|
||||
for each row
|
||||
execute procedure hs_office_contact_global_insert_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityViewFromProjection('hs_office_contact',
|
||||
$idName$
|
||||
label
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_contact',
|
||||
$orderBy$
|
||||
label
|
||||
$orderBy$,
|
||||
$updates$
|
||||
label = new.label,
|
||||
postalAddress = new.postalAddress,
|
||||
emailAddresses = new.emailAddresses,
|
||||
phoneNumbers = new.phoneNumbers
|
||||
$updates$);
|
||||
--//
|
||||
|
@ -0,0 +1,96 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- TODO: These changesets are just for the external remote views to simulate the legacy tables.
|
||||
-- Once we don't need the external remote views anymore, create revert changesets.
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-MIGRATION-mapping:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE hs_office_contact_legacy_id
|
||||
(
|
||||
uuid uuid NOT NULL REFERENCES hs_office_contact(uuid),
|
||||
contact_id integer NOT NULL
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-MIGRATION-sequence:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE SEQUENCE IF NOT EXISTS hs_office_contact_legacy_id_seq
|
||||
AS integer
|
||||
START 1000000000
|
||||
OWNED BY hs_office_contact_legacy_id.contact_id;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-MIGRATION-default:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
ALTER TABLE hs_office_contact_legacy_id
|
||||
ALTER COLUMN contact_id
|
||||
SET DEFAULT nextVal('hs_office_contact_legacy_id_seq');
|
||||
|
||||
--/
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-MIGRATION-insert:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CALL defineContext('schema-migration');
|
||||
INSERT INTO hs_office_contact_legacy_id(uuid, contact_id)
|
||||
SELECT uuid, nextVal('hs_office_contact_legacy_id_seq') FROM hs_office_contact;
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-MIGRATION-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
create or replace function insertContactLegacyIdMapping()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
if TG_OP <> 'INSERT' then
|
||||
raise exception 'invalid usage of trigger';
|
||||
end if;
|
||||
|
||||
INSERT INTO hs_office_contact_legacy_id VALUES
|
||||
(NEW.uuid, nextVal('hs_office_contact_legacy_id_seq'));
|
||||
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger createContactLegacyIdMapping
|
||||
after insert on hs_office_contact
|
||||
for each row
|
||||
execute procedure insertContactLegacyIdMapping();
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-MIGRATION-delete-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
create or replace function deleteContactLegacyIdMapping()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
if TG_OP <> 'DELETE' then
|
||||
raise exception 'invalid usage of trigger';
|
||||
end if;
|
||||
|
||||
DELETE FROM hs_office_contact_legacy_id
|
||||
WHERE uuid = OLD.uuid;
|
||||
|
||||
return OLD;
|
||||
end; $$;
|
||||
|
||||
create trigger removeContactLegacyIdMapping
|
||||
before delete on hs_office_contact
|
||||
for each row
|
||||
execute procedure deleteContactLegacyIdMapping();
|
||||
--/
|
@ -0,0 +1,75 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates a single contact test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficeContactTestData(contLabel varchar)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentTask varchar;
|
||||
emailAddr varchar;
|
||||
begin
|
||||
currentTask = 'creating contact test-data ' || contLabel;
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
emailAddr = 'contact-admin@' || cleanIdentifier(contLabel) || '.example.com';
|
||||
call defineContext(currentTask);
|
||||
perform createRbacUser(emailAddr);
|
||||
call defineContext(currentTask, null, emailAddr);
|
||||
|
||||
raise notice 'creating test contact: %', contLabel;
|
||||
insert
|
||||
into hs_office_contact (label, postaladdress, emailaddresses, phonenumbers)
|
||||
values (contLabel, $address$
|
||||
Vorname Nachname
|
||||
Straße Hnr
|
||||
PLZ Stadt
|
||||
$address$, emailAddr, '+49 123 1234567');
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
/*
|
||||
Creates a range of test contact for mass data generation.
|
||||
*/
|
||||
create or replace procedure createHsOfficeContactTestData(
|
||||
startCount integer, -- count of auto generated rows before the run
|
||||
endCount integer -- count of auto generated rows after the run
|
||||
)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
for t in startCount..endCount
|
||||
loop
|
||||
call createHsOfficeContactTestData(intToVarChar(t, 4) || '#' || t);
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-contact-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
-- TODO: use better names
|
||||
call createHsOfficeContactTestData('first contact');
|
||||
call createHsOfficeContactTestData('second contact');
|
||||
call createHsOfficeContactTestData('third contact');
|
||||
call createHsOfficeContactTestData('fourth contact');
|
||||
call createHsOfficeContactTestData('fifth contact');
|
||||
call createHsOfficeContactTestData('sixth contact');
|
||||
call createHsOfficeContactTestData('seventh contact');
|
||||
call createHsOfficeContactTestData('eighth contact');
|
||||
call createHsOfficeContactTestData('ninth contact');
|
||||
call createHsOfficeContactTestData('tenth contact');
|
||||
call createHsOfficeContactTestData('eleventh contact');
|
||||
call createHsOfficeContactTestData('twelfth contact');
|
||||
end;
|
||||
$$;
|
||||
--//
|
@ -0,0 +1,32 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-MAIN-TABLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE TYPE HsOfficePersonType AS ENUM (
|
||||
'??', -- unknown
|
||||
'NP', -- natural person
|
||||
'LP', -- legal person
|
||||
'IF', -- incorporated firm
|
||||
'UF', -- unincorporated firm
|
||||
'PI'); -- public institution
|
||||
|
||||
CREATE CAST (character varying as HsOfficePersonType) WITH INOUT AS IMPLICIT;
|
||||
|
||||
create table if not exists hs_office_person
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||
personType HsOfficePersonType not null,
|
||||
tradeName varchar(96),
|
||||
givenName varchar(48),
|
||||
familyName varchar(48)
|
||||
);
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call create_journal('hs_office_person');
|
||||
--//
|
@ -0,0 +1,45 @@
|
||||
### rbac person
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||
|
||||
```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
|
||||
|
||||
```
|
@ -0,0 +1,146 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-OBJECT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('hs_office_person');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('hsOfficePerson', 'hs_office_person');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficePerson(
|
||||
NEW hs_office_person
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficePersonOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalADMIN()],
|
||||
userUuids => array[currentUserUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficePersonADMIN(NEW),
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[hsOfficePersonOWNER(NEW)]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficePersonREFERRER(NEW),
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[hsOfficePersonADMIN(NEW)]
|
||||
);
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_person row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficePerson_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficePerson(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
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:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_person permissions for the related global rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_person permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_person'),
|
||||
globalGUEST());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_person INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function hs_office_person_global_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_person'),
|
||||
globalGUEST());
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_hs_office_person_global_insert_tg
|
||||
after insert on global
|
||||
for each row
|
||||
execute procedure hs_office_person_global_insert_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
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',
|
||||
$orderBy$
|
||||
concat(tradeName, familyName, givenName)
|
||||
$orderBy$,
|
||||
$updates$
|
||||
personType = new.personType,
|
||||
tradeName = new.tradeName,
|
||||
givenName = new.givenName,
|
||||
familyName = new.familyName
|
||||
$updates$);
|
||||
--//
|
||||
|
@ -0,0 +1,77 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates a single person test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficePersonTestData(
|
||||
newPersonType HsOfficePersonType,
|
||||
newTradeName varchar,
|
||||
newFamilyName varchar = null,
|
||||
newGivenName varchar = null
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
fullName varchar;
|
||||
currentTask varchar;
|
||||
emailAddr varchar;
|
||||
begin
|
||||
fullName := concat_ws(', ', newTradeName, newFamilyName, newGivenName);
|
||||
currentTask = 'creating person test-data ' || fullName;
|
||||
emailAddr = 'person-' || left(cleanIdentifier(fullName), 32) || '@example.com';
|
||||
call defineContext(currentTask);
|
||||
perform createRbacUser(emailAddr);
|
||||
call defineContext(currentTask, null, emailAddr);
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
raise notice 'creating test person: % by %', fullName, emailAddr;
|
||||
insert
|
||||
into hs_office_person (persontype, tradename, givenname, familyname)
|
||||
values (newPersonType, newTradeName, newGivenName, newFamilyName);
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
/*
|
||||
Creates a range of test persons for mass data generation.
|
||||
*/
|
||||
create or replace procedure createTestPersonTestData(
|
||||
startCount integer, -- count of auto generated rows before the run
|
||||
endCount integer -- count of auto generated rows after the run
|
||||
)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
for t in startCount..endCount
|
||||
loop
|
||||
call createHsOfficePersonTestData('LP', intToVarChar(t, 4));
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-person-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call createHsOfficePersonTestData('LP', 'Hostsharing eG');
|
||||
call createHsOfficePersonTestData('LP', 'First GmbH');
|
||||
call createHsOfficePersonTestData('NP', null, 'Firby', 'Susan');
|
||||
call createHsOfficePersonTestData('NP', null, 'Smith', 'Peter');
|
||||
call createHsOfficePersonTestData('NP', null, 'Tucker', 'Jack');
|
||||
call createHsOfficePersonTestData('NP', null, 'Fouler', 'Ellie');
|
||||
call createHsOfficePersonTestData('LP', 'Second e.K.', 'Smith', 'Peter');
|
||||
call createHsOfficePersonTestData('IF', 'Third OHG');
|
||||
call createHsOfficePersonTestData('LP', 'Fourth eG');
|
||||
call createHsOfficePersonTestData('UF', 'Erben Bessler', 'Mel', 'Bessler');
|
||||
call createHsOfficePersonTestData('NP', null, 'Bessler', 'Anita');
|
||||
call createHsOfficePersonTestData('NP', null, 'Bessler', 'Bert');
|
||||
call createHsOfficePersonTestData('NP', null, 'Winkler', 'Paul');
|
||||
end;
|
||||
$$;
|
||||
--//
|
@ -0,0 +1,36 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relation-MAIN-TABLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE TYPE HsOfficeRelationType AS ENUM (
|
||||
'UNKNOWN',
|
||||
'PARTNER',
|
||||
'EX_PARTNER',
|
||||
'REPRESENTATIVE',
|
||||
'DEBITOR',
|
||||
'VIP_CONTACT',
|
||||
'OPERATIONS',
|
||||
'SUBSCRIBER');
|
||||
|
||||
CREATE CAST (character varying as HsOfficeRelationType) WITH INOUT AS IMPLICIT;
|
||||
|
||||
create table if not exists hs_office_relation
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred, -- on delete cascade
|
||||
anchorUuid uuid not null references hs_office_person(uuid),
|
||||
holderUuid uuid not null references hs_office_person(uuid),
|
||||
contactUuid uuid references hs_office_contact(uuid),
|
||||
type HsOfficeRelationType not null,
|
||||
mark varchar(24)
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relation-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call create_journal('hs_office_relation');
|
||||
--//
|
@ -0,0 +1,102 @@
|
||||
### rbac relation
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph holderPerson["`**holderPerson**`"]
|
||||
direction TB
|
||||
style holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph holderPerson:roles[ ]
|
||||
style holderPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:holderPerson:OWNER[[holderPerson:OWNER]]
|
||||
role:holderPerson:ADMIN[[holderPerson:ADMIN]]
|
||||
role:holderPerson:REFERRER[[holderPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph anchorPerson["`**anchorPerson**`"]
|
||||
direction TB
|
||||
style anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph anchorPerson:roles[ ]
|
||||
style anchorPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:anchorPerson:OWNER[[anchorPerson:OWNER]]
|
||||
role:anchorPerson:ADMIN[[anchorPerson:ADMIN]]
|
||||
role:anchorPerson:REFERRER[[anchorPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph contact["`**contact**`"]
|
||||
direction TB
|
||||
style contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph contact:roles[ ]
|
||||
style contact:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:contact:OWNER[[contact:OWNER]]
|
||||
role:contact:ADMIN[[contact:ADMIN]]
|
||||
role:contact:REFERRER[[contact:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph relation["`**relation**`"]
|
||||
direction TB
|
||||
style relation fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph relation:roles[ ]
|
||||
style relation:roles fill:#dd4901,stroke:white
|
||||
|
||||
role:relation:OWNER[[relation:OWNER]]
|
||||
role:relation:ADMIN[[relation:ADMIN]]
|
||||
role:relation:AGENT[[relation:AGENT]]
|
||||
role:relation:TENANT[[relation:TENANT]]
|
||||
end
|
||||
|
||||
subgraph relation:permissions[ ]
|
||||
style relation:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:relation:DELETE{{relation:DELETE}}
|
||||
perm:relation:UPDATE{{relation:UPDATE}}
|
||||
perm:relation:SELECT{{relation:SELECT}}
|
||||
perm:relation:INSERT{{relation:INSERT}}
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to users
|
||||
user:creator ==> role:relation:OWNER
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:ADMIN -.-> role:anchorPerson:OWNER
|
||||
role:anchorPerson:OWNER -.-> role:anchorPerson:ADMIN
|
||||
role:anchorPerson:ADMIN -.-> role:anchorPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:holderPerson:OWNER
|
||||
role:holderPerson:OWNER -.-> role:holderPerson:ADMIN
|
||||
role:holderPerson:ADMIN -.-> role:holderPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:contact:OWNER
|
||||
role:contact:OWNER -.-> role:contact:ADMIN
|
||||
role:contact:ADMIN -.-> role:contact:REFERRER
|
||||
role:global:ADMIN ==> role:relation:OWNER
|
||||
role:relation:OWNER ==> role:relation:ADMIN
|
||||
role:anchorPerson:ADMIN ==> role:relation:ADMIN
|
||||
role:relation:ADMIN ==> role:relation:AGENT
|
||||
role:holderPerson:ADMIN ==> role:relation:AGENT
|
||||
role:relation:AGENT ==> role:relation:TENANT
|
||||
role:holderPerson:ADMIN ==> role:relation:TENANT
|
||||
role:contact:ADMIN ==> role:relation:TENANT
|
||||
role:relation:TENANT ==> role:anchorPerson:REFERRER
|
||||
role:relation:TENANT ==> role:holderPerson:REFERRER
|
||||
role:relation:TENANT ==> role:contact:REFERRER
|
||||
|
||||
%% granting permissions to roles
|
||||
role:relation:OWNER ==> perm:relation:DELETE
|
||||
role:relation:ADMIN ==> perm:relation:UPDATE
|
||||
role:relation:TENANT ==> perm:relation:SELECT
|
||||
role:anchorPerson:ADMIN ==> perm:relation:INSERT
|
||||
|
||||
```
|
@ -0,0 +1,271 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relation-rbac-OBJECT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('hs_office_relation');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relation-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('hsOfficeRelation', 'hs_office_relation');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relation-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficeRelation(
|
||||
NEW hs_office_relation
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
newHolderPerson hs_office_person;
|
||||
newAnchorPerson hs_office_person;
|
||||
newContact hs_office_contact;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM hs_office_person WHERE uuid = NEW.holderUuid INTO newHolderPerson;
|
||||
assert newHolderPerson.uuid is not null, format('newHolderPerson must not be null for NEW.holderUuid = %s', NEW.holderUuid);
|
||||
|
||||
SELECT * FROM hs_office_person WHERE uuid = NEW.anchorUuid INTO newAnchorPerson;
|
||||
assert newAnchorPerson.uuid is not null, format('newAnchorPerson must not be null for NEW.anchorUuid = %s', NEW.anchorUuid);
|
||||
|
||||
SELECT * FROM hs_office_contact WHERE uuid = NEW.contactUuid INTO newContact;
|
||||
assert newContact.uuid is not null, format('newContact must not be null for NEW.contactUuid = %s', NEW.contactUuid);
|
||||
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeRelationOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalADMIN()],
|
||||
userUuids => array[currentUserUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeRelationADMIN(NEW),
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[
|
||||
hsOfficePersonADMIN(newAnchorPerson),
|
||||
hsOfficeRelationOWNER(NEW)]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeRelationAGENT(NEW),
|
||||
incomingSuperRoles => array[
|
||||
hsOfficePersonADMIN(newHolderPerson),
|
||||
hsOfficeRelationADMIN(NEW)]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeRelationTENANT(NEW),
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[
|
||||
hsOfficeContactADMIN(newContact),
|
||||
hsOfficePersonADMIN(newHolderPerson),
|
||||
hsOfficeRelationAGENT(NEW)],
|
||||
outgoingSubRoles => array[
|
||||
hsOfficeContactREFERRER(newContact),
|
||||
hsOfficePersonREFERRER(newAnchorPerson),
|
||||
hsOfficePersonREFERRER(newHolderPerson)]
|
||||
);
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_relation row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficeRelation_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficeRelation(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForHsOfficeRelation_tg
|
||||
after insert on hs_office_relation
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficeRelation_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relation-rbac-update-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
|
||||
*/
|
||||
|
||||
create or replace procedure updateRbacRulesForHsOfficeRelation(
|
||||
OLD hs_office_relation,
|
||||
NEW hs_office_relation
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
oldHolderPerson hs_office_person;
|
||||
newHolderPerson hs_office_person;
|
||||
oldAnchorPerson hs_office_person;
|
||||
newAnchorPerson hs_office_person;
|
||||
oldContact hs_office_contact;
|
||||
newContact hs_office_contact;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM hs_office_person WHERE uuid = OLD.holderUuid INTO oldHolderPerson;
|
||||
assert oldHolderPerson.uuid is not null, format('oldHolderPerson must not be null for OLD.holderUuid = %s', OLD.holderUuid);
|
||||
|
||||
SELECT * FROM hs_office_person WHERE uuid = NEW.holderUuid INTO newHolderPerson;
|
||||
assert newHolderPerson.uuid is not null, format('newHolderPerson must not be null for NEW.holderUuid = %s', NEW.holderUuid);
|
||||
|
||||
SELECT * FROM hs_office_person WHERE uuid = OLD.anchorUuid INTO oldAnchorPerson;
|
||||
assert oldAnchorPerson.uuid is not null, format('oldAnchorPerson must not be null for OLD.anchorUuid = %s', OLD.anchorUuid);
|
||||
|
||||
SELECT * FROM hs_office_person WHERE uuid = NEW.anchorUuid INTO newAnchorPerson;
|
||||
assert newAnchorPerson.uuid is not null, format('newAnchorPerson must not be null for NEW.anchorUuid = %s', NEW.anchorUuid);
|
||||
|
||||
SELECT * FROM hs_office_contact WHERE uuid = OLD.contactUuid INTO oldContact;
|
||||
assert oldContact.uuid is not null, format('oldContact must not be null for OLD.contactUuid = %s', OLD.contactUuid);
|
||||
|
||||
SELECT * FROM hs_office_contact WHERE uuid = NEW.contactUuid INTO newContact;
|
||||
assert newContact.uuid is not null, format('newContact must not be null for NEW.contactUuid = %s', NEW.contactUuid);
|
||||
|
||||
|
||||
if NEW.contactUuid <> OLD.contactUuid then
|
||||
|
||||
call revokeRoleFromRole(hsOfficeRelationTENANT(OLD), hsOfficeContactADMIN(oldContact));
|
||||
call grantRoleToRole(hsOfficeRelationTENANT(NEW), hsOfficeContactADMIN(newContact));
|
||||
|
||||
call revokeRoleFromRole(hsOfficeContactREFERRER(oldContact), hsOfficeRelationTENANT(OLD));
|
||||
call grantRoleToRole(hsOfficeContactREFERRER(newContact), hsOfficeRelationTENANT(NEW));
|
||||
|
||||
end if;
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new hs_office_relation row.
|
||||
*/
|
||||
|
||||
create or replace function updateTriggerForHsOfficeRelation_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call updateRbacRulesForHsOfficeRelation(OLD, NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger updateTriggerForHsOfficeRelation_tg
|
||||
after update on hs_office_relation
|
||||
for each row
|
||||
execute procedure updateTriggerForHsOfficeRelation_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relation-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_relation permissions for the related hs_office_person rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row hs_office_person;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_relation permissions for the related hs_office_person rows');
|
||||
|
||||
FOR row IN SELECT * FROM hs_office_person
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_relation'),
|
||||
hsOfficePersonADMIN(row));
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_relation INSERT permission to specified role of new hs_office_person rows.
|
||||
*/
|
||||
create or replace function hs_office_relation_hs_office_person_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_relation'),
|
||||
hsOfficePersonADMIN(NEW));
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_hs_office_relation_hs_office_person_insert_tg
|
||||
after insert on hs_office_person
|
||||
for each row
|
||||
execute procedure hs_office_relation_hs_office_person_insert_tf();
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_relation,
|
||||
where the check is performed by a direct role.
|
||||
|
||||
A direct role is a role depending on a foreign key directly available in the NEW row.
|
||||
*/
|
||||
create or replace function hs_office_relation_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into hs_office_relation not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_relation_insert_permission_check_tg
|
||||
before insert on hs_office_relation
|
||||
for each row
|
||||
when ( not hasInsertPermission(NEW.anchorUuid, 'INSERT', 'hs_office_relation') )
|
||||
execute procedure hs_office_relation_insert_permission_missing_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relation-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityViewFromProjection('hs_office_relation',
|
||||
$idName$
|
||||
(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)
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relation-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_relation',
|
||||
$orderBy$
|
||||
(select idName from hs_office_person_iv p where p.uuid = target.holderUuid)
|
||||
$orderBy$,
|
||||
$updates$
|
||||
contactUuid = new.contactUuid
|
||||
$updates$);
|
||||
--//
|
||||
|
@ -0,0 +1,113 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relation-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates a single relation test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficeRelationTestData(
|
||||
holderPersonName varchar,
|
||||
relationType HsOfficeRelationType,
|
||||
anchorPersonName varchar,
|
||||
contactLabel varchar,
|
||||
mark varchar default null)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentTask varchar;
|
||||
idName varchar;
|
||||
anchorPerson hs_office_person;
|
||||
holderPerson hs_office_person;
|
||||
contact hs_office_contact;
|
||||
|
||||
begin
|
||||
idName := cleanIdentifier( anchorPersonName || '-' || holderPersonName);
|
||||
currentTask := 'creating relation test-data ' || idName;
|
||||
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
select p.*
|
||||
into anchorPerson
|
||||
from hs_office_person p
|
||||
where p.tradeName = anchorPersonName or p.familyName = anchorPersonName;
|
||||
if anchorPerson is null then
|
||||
raise exception 'anchorPerson "%" not found', anchorPersonName;
|
||||
end if;
|
||||
|
||||
select p.*
|
||||
into holderPerson
|
||||
from hs_office_person p
|
||||
where p.tradeName = holderPersonName or p.familyName = holderPersonName;
|
||||
if holderPerson is null then
|
||||
raise exception 'holderPerson "%" not found', holderPersonName;
|
||||
end if;
|
||||
|
||||
select c.* into contact from hs_office_contact c where c.label = contactLabel;
|
||||
if contact is null then
|
||||
raise exception 'contact "%" not found', contactLabel;
|
||||
end if;
|
||||
|
||||
raise notice 'creating test relation: %', idName;
|
||||
raise notice '- using anchor person (%): %', anchorPerson.uuid, anchorPerson;
|
||||
raise notice '- using holder person (%): %', holderPerson.uuid, holderPerson;
|
||||
raise notice '- using contact (%): %', contact.uuid, contact;
|
||||
insert
|
||||
into hs_office_relation (uuid, anchoruuid, holderuuid, type, mark, contactUuid)
|
||||
values (uuid_generate_v4(), anchorPerson.uuid, holderPerson.uuid, relationType, mark, contact.uuid);
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
/*
|
||||
Creates a range of test relation for mass data generation.
|
||||
*/
|
||||
create or replace procedure createHsOfficeRelationTestData(
|
||||
startCount integer, -- count of auto generated rows before the run
|
||||
endCount integer -- count of auto generated rows after the run
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
person hs_office_person;
|
||||
contact hs_office_contact;
|
||||
begin
|
||||
for t in startCount..endCount
|
||||
loop
|
||||
select p.* from hs_office_person p where tradeName = intToVarChar(t, 4) into person;
|
||||
select c.* from hs_office_contact c where c.label = intToVarChar(t, 4) || '#' || t into contact;
|
||||
|
||||
call createHsOfficeRelationTestData(person.uuid, contact.uuid, 'REPRESENTATIVE');
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-relation-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call createHsOfficeRelationTestData('First GmbH', 'PARTNER', 'Hostsharing eG', 'first contact');
|
||||
call createHsOfficeRelationTestData('Firby', 'REPRESENTATIVE', 'First GmbH', 'first contact');
|
||||
call createHsOfficeRelationTestData('First GmbH', 'DEBITOR', 'First GmbH', 'first contact');
|
||||
|
||||
call createHsOfficeRelationTestData('Second e.K.', 'PARTNER', 'Hostsharing eG', 'second contact');
|
||||
call createHsOfficeRelationTestData('Smith', 'REPRESENTATIVE', 'Second e.K.', 'second contact');
|
||||
call createHsOfficeRelationTestData('Second e.K.', 'DEBITOR', 'Second e.K.', 'second contact');
|
||||
|
||||
call createHsOfficeRelationTestData('Third OHG', 'PARTNER', 'Hostsharing eG', 'third contact');
|
||||
call createHsOfficeRelationTestData('Tucker', 'REPRESENTATIVE', 'Third OHG', 'third contact');
|
||||
call createHsOfficeRelationTestData('Third OHG', 'DEBITOR', 'Third OHG', 'third contact');
|
||||
|
||||
call createHsOfficeRelationTestData('Fourth eG', 'PARTNER', 'Hostsharing eG', 'fourth contact');
|
||||
call createHsOfficeRelationTestData('Fouler', 'REPRESENTATIVE', 'Third OHG', 'third contact');
|
||||
call createHsOfficeRelationTestData('Third OHG', 'DEBITOR', 'Third OHG', 'third contact');
|
||||
|
||||
call createHsOfficeRelationTestData('Smith', 'PARTNER', 'Hostsharing eG', 'sixth contact');
|
||||
call createHsOfficeRelationTestData('Smith', 'DEBITOR', 'Smith', 'third contact');
|
||||
call createHsOfficeRelationTestData('Smith', 'SUBSCRIBER', 'Third OHG', 'third contact', 'members-announce');
|
||||
end;
|
||||
$$;
|
||||
--//
|
@ -0,0 +1,85 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-DETAILS-TABLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create table hs_office_partner_details
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||
registrationOffice varchar(96),
|
||||
registrationNumber varchar(96),
|
||||
birthPlace varchar(96),
|
||||
birthName varchar(96),
|
||||
birthday date,
|
||||
dateOfDeath date
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-DETAILS-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call create_journal('hs_office_partner_details');
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-MAIN-TABLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create table hs_office_partner
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||
partnerNumber numeric(5) unique not null,
|
||||
partnerRelUuid uuid not null references hs_office_relation(uuid), -- deleted in after delete trigger
|
||||
detailsUuid uuid not null references hs_office_partner_details(uuid) -- deleted in after delete trigger
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-DELETE-DEPENDENTS-TRIGGER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Trigger function to delete related details of a partner to delete.
|
||||
*/
|
||||
create or replace function deleteHsOfficeDependentsOnPartnerDelete()
|
||||
returns trigger
|
||||
language PLPGSQL
|
||||
as $$
|
||||
declare
|
||||
counter integer;
|
||||
begin
|
||||
DELETE FROM hs_office_partner_details d WHERE d.uuid = OLD.detailsUuid;
|
||||
GET DIAGNOSTICS counter = ROW_COUNT;
|
||||
if counter = 0 then
|
||||
raise exception 'partner details % could not be deleted', OLD.detailsUuid;
|
||||
end if;
|
||||
|
||||
DELETE FROM hs_office_relation r WHERE r.uuid = OLD.partnerRelUuid;
|
||||
GET DIAGNOSTICS counter = ROW_COUNT;
|
||||
if counter = 0 then
|
||||
raise exception 'partner relation % could not be deleted', OLD.partnerRelUuid;
|
||||
end if;
|
||||
|
||||
RETURN OLD;
|
||||
end; $$;
|
||||
|
||||
/**
|
||||
Triggers deletion of related rows of a partner to delete.
|
||||
*/
|
||||
create trigger hs_office_partner_delete_dependents_trigger
|
||||
after delete
|
||||
on hs_office_partner
|
||||
for each row
|
||||
execute procedure deleteHsOfficeDependentsOnPartnerDelete();
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call create_journal('hs_office_partner');
|
||||
--//
|
@ -0,0 +1,120 @@
|
||||
### rbac partner
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph partnerRel.contact["`**partnerRel.contact**`"]
|
||||
direction TB
|
||||
style partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel.contact:roles[ ]
|
||||
style partnerRel.contact:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel.contact:OWNER[[partnerRel.contact:OWNER]]
|
||||
role:partnerRel.contact:ADMIN[[partnerRel.contact:ADMIN]]
|
||||
role:partnerRel.contact:REFERRER[[partnerRel.contact:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph partner["`**partner**`"]
|
||||
direction TB
|
||||
style partner fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partner:permissions[ ]
|
||||
style partner:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:partner:INSERT{{partner:INSERT}}
|
||||
perm:partner:DELETE{{partner:DELETE}}
|
||||
perm:partner:UPDATE{{partner:UPDATE}}
|
||||
perm:partner:SELECT{{partner:SELECT}}
|
||||
end
|
||||
|
||||
subgraph partnerRel["`**partnerRel**`"]
|
||||
direction TB
|
||||
style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel:roles[ ]
|
||||
style partnerRel:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel:OWNER[[partnerRel:OWNER]]
|
||||
role:partnerRel:ADMIN[[partnerRel:ADMIN]]
|
||||
role:partnerRel:AGENT[[partnerRel:AGENT]]
|
||||
role:partnerRel:TENANT[[partnerRel:TENANT]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
subgraph partnerDetails["`**partnerDetails**`"]
|
||||
direction TB
|
||||
style partnerDetails fill:#feb28c,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerDetails:permissions[ ]
|
||||
style partnerDetails:permissions fill:#feb28c,stroke:white
|
||||
|
||||
perm:partnerDetails:DELETE{{partnerDetails:DELETE}}
|
||||
perm:partnerDetails:UPDATE{{partnerDetails:UPDATE}}
|
||||
perm:partnerDetails:SELECT{{partnerDetails:SELECT}}
|
||||
end
|
||||
end
|
||||
|
||||
subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
||||
direction TB
|
||||
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel.anchorPerson:roles[ ]
|
||||
style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel.anchorPerson:OWNER[[partnerRel.anchorPerson:OWNER]]
|
||||
role:partnerRel.anchorPerson:ADMIN[[partnerRel.anchorPerson:ADMIN]]
|
||||
role:partnerRel.anchorPerson:REFERRER[[partnerRel.anchorPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
|
||||
direction TB
|
||||
style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel.holderPerson:roles[ ]
|
||||
style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel.holderPerson:OWNER[[partnerRel.holderPerson:OWNER]]
|
||||
role:partnerRel.holderPerson:ADMIN[[partnerRel.holderPerson:ADMIN]]
|
||||
role:partnerRel.holderPerson:REFERRER[[partnerRel.holderPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:ADMIN -.-> role:partnerRel.anchorPerson:OWNER
|
||||
role:partnerRel.anchorPerson:OWNER -.-> role:partnerRel.anchorPerson:ADMIN
|
||||
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel.anchorPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:partnerRel.holderPerson:OWNER
|
||||
role:partnerRel.holderPerson:OWNER -.-> role:partnerRel.holderPerson:ADMIN
|
||||
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel.holderPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:partnerRel.contact:OWNER
|
||||
role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN
|
||||
role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER
|
||||
role:global:ADMIN -.-> role:partnerRel:OWNER
|
||||
role:partnerRel:OWNER -.-> role:partnerRel:ADMIN
|
||||
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:ADMIN
|
||||
role:partnerRel:ADMIN -.-> role:partnerRel:AGENT
|
||||
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
|
||||
role:partnerRel:AGENT -.-> role:partnerRel:TENANT
|
||||
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:TENANT
|
||||
role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT
|
||||
role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER
|
||||
role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER
|
||||
role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER
|
||||
|
||||
%% granting permissions to roles
|
||||
role:global:ADMIN ==> perm:partner:INSERT
|
||||
role:partnerRel:ADMIN ==> perm:partner:DELETE
|
||||
role:partnerRel:AGENT ==> perm:partner:UPDATE
|
||||
role:partnerRel:TENANT ==> perm:partner:SELECT
|
||||
role:partnerRel:ADMIN ==> perm:partnerDetails:DELETE
|
||||
role:partnerRel:AGENT ==> perm:partnerDetails:UPDATE
|
||||
role:partnerRel:AGENT ==> perm:partnerDetails:SELECT
|
||||
|
||||
```
|
@ -0,0 +1,238 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-OBJECT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('hs_office_partner');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('hsOfficePartner', 'hs_office_partner');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
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_relation;
|
||||
newPartnerDetails hs_office_partner_details;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM hs_office_relation WHERE uuid = NEW.partnerRelUuid 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 WHERE 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'), hsOfficeRelationADMIN(newPartnerRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTENANT(newPartnerRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationADMIN(newPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAGENT(newPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(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-update-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
|
||||
*/
|
||||
|
||||
create or replace procedure updateRbacRulesForHsOfficePartner(
|
||||
OLD hs_office_partner,
|
||||
NEW hs_office_partner
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
oldPartnerRel hs_office_relation;
|
||||
newPartnerRel hs_office_relation;
|
||||
oldPartnerDetails hs_office_partner_details;
|
||||
newPartnerDetails hs_office_partner_details;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM hs_office_relation WHERE uuid = OLD.partnerRelUuid INTO oldPartnerRel;
|
||||
assert oldPartnerRel.uuid is not null, format('oldPartnerRel must not be null for OLD.partnerRelUuid = %s', OLD.partnerRelUuid);
|
||||
|
||||
SELECT * FROM hs_office_relation WHERE uuid = NEW.partnerRelUuid 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 WHERE uuid = OLD.detailsUuid INTO oldPartnerDetails;
|
||||
assert oldPartnerDetails.uuid is not null, format('oldPartnerDetails must not be null for OLD.detailsUuid = %s', OLD.detailsUuid);
|
||||
|
||||
SELECT * FROM hs_office_partner_details WHERE uuid = NEW.detailsUuid INTO newPartnerDetails;
|
||||
assert newPartnerDetails.uuid is not null, format('newPartnerDetails must not be null for NEW.detailsUuid = %s', NEW.detailsUuid);
|
||||
|
||||
|
||||
if NEW.partnerRelUuid <> OLD.partnerRelUuid then
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'DELETE'), hsOfficeRelationADMIN(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationADMIN(newPartnerRel));
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'UPDATE'), hsOfficeRelationAGENT(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'SELECT'), hsOfficeRelationTENANT(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTENANT(newPartnerRel));
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'DELETE'), hsOfficeRelationADMIN(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationADMIN(newPartnerRel));
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAGENT(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAGENT(newPartnerRel));
|
||||
|
||||
end if;
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new hs_office_partner row.
|
||||
*/
|
||||
|
||||
create or replace function updateTriggerForHsOfficePartner_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call updateRbacRulesForHsOfficePartner(OLD, NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger updateTriggerForHsOfficePartner_tg
|
||||
after update on hs_office_partner
|
||||
for each row
|
||||
execute procedure updateTriggerForHsOfficePartner_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;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_partner permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_partner'),
|
||||
globalADMIN());
|
||||
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(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_partner'),
|
||||
globalADMIN());
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_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,
|
||||
where only global-admin has that permission.
|
||||
*/
|
||||
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',
|
||||
$orderBy$
|
||||
'P-' || partnerNumber
|
||||
$orderBy$,
|
||||
$updates$
|
||||
partnerRelUuid = new.partnerRelUuid
|
||||
$updates$);
|
||||
--//
|
||||
|
@ -0,0 +1,23 @@
|
||||
### rbac partnerDetails
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||
|
||||
```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
|
||||
|
||||
```
|
@ -0,0 +1,150 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-details-rbac-OBJECT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('hs_office_partner_details');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-details-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
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;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_partner_details permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_partner_details'),
|
||||
globalADMIN());
|
||||
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(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_partner_details'),
|
||||
globalADMIN());
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_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,
|
||||
where only global-admin has that permission.
|
||||
*/
|
||||
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 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',
|
||||
$orderBy$
|
||||
uuid
|
||||
$orderBy$,
|
||||
$updates$
|
||||
registrationOffice = new.registrationOffice,
|
||||
registrationNumber = new.registrationNumber,
|
||||
birthPlace = new.birthPlace,
|
||||
birthName = new.birthName,
|
||||
birthday = new.birthday,
|
||||
dateOfDeath = new.dateOfDeath
|
||||
$updates$);
|
||||
--//
|
||||
|
@ -0,0 +1,95 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- TODO: These changesets are just for the external remote views to simulate the legacy tables.
|
||||
-- Once we don't need the external remote views anymore, create revert changesets.
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-MIGRATION-mapping:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE hs_office_partner_legacy_id
|
||||
(
|
||||
uuid uuid NOT NULL REFERENCES hs_office_partner(uuid),
|
||||
bp_id integer NOT NULL
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-MIGRATION-sequence:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE SEQUENCE IF NOT EXISTS hs_office_partner_legacy_id_seq
|
||||
AS integer
|
||||
START 1000000000
|
||||
OWNED BY hs_office_partner_legacy_id.bp_id;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-MIGRATION-default:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
ALTER TABLE hs_office_partner_legacy_id
|
||||
ALTER COLUMN bp_id
|
||||
SET DEFAULT nextVal('hs_office_partner_legacy_id_seq');
|
||||
--/
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-MIGRATION-insert:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CALL defineContext('schema-migration');
|
||||
INSERT INTO hs_office_partner_legacy_id(uuid, bp_id)
|
||||
SELECT uuid, nextVal('hs_office_partner_legacy_id_seq') FROM hs_office_partner;
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-MIGRATION-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
create or replace function insertPartnerLegacyIdMapping()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
if TG_OP <> 'INSERT' then
|
||||
raise exception 'invalid usage of trigger';
|
||||
end if;
|
||||
|
||||
INSERT INTO hs_office_partner_legacy_id VALUES
|
||||
(NEW.uuid, nextVal('hs_office_partner_legacy_id_seq'));
|
||||
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger createPartnerLegacyIdMapping
|
||||
after insert on hs_office_partner
|
||||
for each row
|
||||
execute procedure insertPartnerLegacyIdMapping();
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-MIGRATION-delete-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
create or replace function deletePartnerLegacyIdMapping()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
if TG_OP <> 'DELETE' then
|
||||
raise exception 'invalid usage of trigger';
|
||||
end if;
|
||||
|
||||
DELETE FROM hs_office_partner_legacy_id
|
||||
WHERE uuid = OLD.uuid;
|
||||
|
||||
return OLD;
|
||||
end; $$;
|
||||
|
||||
create trigger removePartnerLegacyIdMapping
|
||||
before delete on hs_office_partner
|
||||
for each row
|
||||
execute procedure deletePartnerLegacyIdMapping();
|
||||
--/
|
@ -0,0 +1,86 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates a single partner test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficePartnerTestData(
|
||||
mandantTradeName varchar,
|
||||
newPartnerNumber numeric(5),
|
||||
partnerPersonName varchar,
|
||||
contactLabel varchar )
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentTask varchar;
|
||||
idName varchar;
|
||||
mandantPerson hs_office_person;
|
||||
partnerRel hs_office_relation;
|
||||
relatedPerson hs_office_person;
|
||||
relatedDetailsUuid uuid;
|
||||
begin
|
||||
idName := cleanIdentifier( partnerPersonName|| '-' || contactLabel);
|
||||
currentTask := 'creating partner test-data ' || idName;
|
||||
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
select p.* from hs_office_person p
|
||||
where p.tradeName = mandantTradeName
|
||||
into mandantPerson;
|
||||
if mandantPerson is null then
|
||||
raise exception 'mandant "%" not found', mandantTradeName;
|
||||
end if;
|
||||
|
||||
select p.* from hs_office_person p
|
||||
where p.tradeName = partnerPersonName or p.familyName = partnerPersonName
|
||||
into relatedPerson;
|
||||
|
||||
select r.* from hs_office_relation r
|
||||
where r.type = 'PARTNER'
|
||||
and r.anchoruuid = mandantPerson.uuid and r.holderuuid = relatedPerson.uuid
|
||||
into partnerRel;
|
||||
if partnerRel is null then
|
||||
raise exception 'partnerRel "%"-"%" not found', mandantPerson.tradename, partnerPersonName;
|
||||
end if;
|
||||
|
||||
raise notice 'creating test partner: %', idName;
|
||||
raise notice '- using partnerRel (%): %', partnerRel.uuid, partnerRel;
|
||||
raise notice '- using person (%): %', relatedPerson.uuid, relatedPerson;
|
||||
|
||||
if relatedPerson.persontype = 'NP' then
|
||||
insert
|
||||
into hs_office_partner_details (uuid, birthName, birthday, birthPlace)
|
||||
values (uuid_generate_v4(), 'Meyer', '1987-10-31', 'Hamburg')
|
||||
returning uuid into relatedDetailsUuid;
|
||||
else
|
||||
insert
|
||||
into hs_office_partner_details (uuid, registrationOffice, registrationNumber)
|
||||
values (uuid_generate_v4(), 'Hamburg', 'RegNo123456789')
|
||||
returning uuid into relatedDetailsUuid;
|
||||
end if;
|
||||
|
||||
insert
|
||||
into hs_office_partner (uuid, partnerNumber, partnerRelUuid, detailsUuid)
|
||||
values (uuid_generate_v4(), newPartnerNumber, partnerRel.uuid, relatedDetailsUuid);
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-partner-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call createHsOfficePartnerTestData('Hostsharing eG', 10001, 'First GmbH', 'first contact');
|
||||
call createHsOfficePartnerTestData('Hostsharing eG', 10002, 'Second e.K.', 'second contact');
|
||||
call createHsOfficePartnerTestData('Hostsharing eG', 10003, 'Third OHG', 'third contact');
|
||||
call createHsOfficePartnerTestData('Hostsharing eG', 10004, 'Fourth eG', 'fourth contact');
|
||||
call createHsOfficePartnerTestData('Hostsharing eG', 10010, 'Smith', 'fifth contact');
|
||||
end;
|
||||
$$;
|
||||
--//
|
@ -0,0 +1,21 @@
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-bankaccount-MAIN-TABLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create table hs_office_bankaccount
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||
holder varchar(64) not null,
|
||||
iban varchar(34) not null,
|
||||
bic varchar(11) not null
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-bankaccount-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call create_journal('hs_office_bankaccount');
|
||||
--//
|
@ -0,0 +1,45 @@
|
||||
### rbac bankAccount
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph bankAccount["`**bankAccount**`"]
|
||||
direction TB
|
||||
style bankAccount fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph bankAccount:roles[ ]
|
||||
style bankAccount:roles fill:#dd4901,stroke:white
|
||||
|
||||
role:bankAccount:OWNER[[bankAccount:OWNER]]
|
||||
role:bankAccount:ADMIN[[bankAccount:ADMIN]]
|
||||
role:bankAccount:REFERRER[[bankAccount:REFERRER]]
|
||||
end
|
||||
|
||||
subgraph bankAccount:permissions[ ]
|
||||
style bankAccount:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:bankAccount:INSERT{{bankAccount:INSERT}}
|
||||
perm:bankAccount:DELETE{{bankAccount:DELETE}}
|
||||
perm:bankAccount:UPDATE{{bankAccount:UPDATE}}
|
||||
perm:bankAccount:SELECT{{bankAccount:SELECT}}
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to users
|
||||
user:creator ==> role:bankAccount:OWNER
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:ADMIN ==> role:bankAccount:OWNER
|
||||
role:bankAccount:OWNER ==> role:bankAccount:ADMIN
|
||||
role:bankAccount:ADMIN ==> role:bankAccount:REFERRER
|
||||
|
||||
%% granting permissions to roles
|
||||
role:global:GUEST ==> perm:bankAccount:INSERT
|
||||
role:bankAccount:OWNER ==> perm:bankAccount:DELETE
|
||||
role:bankAccount:ADMIN ==> perm:bankAccount:UPDATE
|
||||
role:bankAccount:REFERRER ==> perm:bankAccount:SELECT
|
||||
|
||||
```
|
@ -0,0 +1,145 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-bankaccount-rbac-OBJECT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('hs_office_bankaccount');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-bankaccount-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('hsOfficeBankAccount', 'hs_office_bankaccount');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-bankaccount-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficeBankAccount(
|
||||
NEW hs_office_bankaccount
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeBankAccountOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalADMIN()],
|
||||
userUuids => array[currentUserUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeBankAccountADMIN(NEW),
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[hsOfficeBankAccountOWNER(NEW)]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeBankAccountREFERRER(NEW),
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[hsOfficeBankAccountADMIN(NEW)]
|
||||
);
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_bankaccount row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficeBankAccount_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficeBankAccount(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForHsOfficeBankAccount_tg
|
||||
after insert on hs_office_bankaccount
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficeBankAccount_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-bankaccount-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_bankaccount permissions for the related global rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_bankaccount permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_bankaccount'),
|
||||
globalGUEST());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_bankaccount INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function hs_office_bankaccount_global_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_bankaccount'),
|
||||
globalGUEST());
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_hs_office_bankaccount_global_insert_tg
|
||||
after insert on global
|
||||
for each row
|
||||
execute procedure hs_office_bankaccount_global_insert_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-bankaccount-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityViewFromProjection('hs_office_bankaccount',
|
||||
$idName$
|
||||
iban
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-bankaccount-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_bankaccount',
|
||||
$orderBy$
|
||||
iban
|
||||
$orderBy$,
|
||||
$updates$
|
||||
holder = new.holder,
|
||||
iban = new.iban,
|
||||
bic = new.bic
|
||||
$updates$);
|
||||
--//
|
||||
|
@ -0,0 +1,49 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-bankaccount-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates a single bankaccount test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficeBankAccountTestData(givenHolder varchar, givenIBAN varchar, givenBIC varchar)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentTask varchar;
|
||||
emailAddr varchar;
|
||||
begin
|
||||
currentTask = 'creating bankaccount test-data ' || givenHolder;
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
emailAddr = 'bankaccount-admin@' || cleanIdentifier(givenHolder) || '.example.com';
|
||||
call defineContext(currentTask);
|
||||
perform createRbacUser(emailAddr);
|
||||
call defineContext(currentTask, null, emailAddr);
|
||||
|
||||
raise notice 'creating test bankaccount: %', givenHolder;
|
||||
insert
|
||||
into hs_office_bankaccount(uuid, holder, iban, bic)
|
||||
values (uuid_generate_v4(), givenHolder, givenIBAN, givenBIC);
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-bankaccount-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
-- IBANs+BICs taken from https://ibanvalidieren.de/beispiele.html
|
||||
call createHsOfficeBankAccountTestData('First GmbH', 'DE02120300000000202051', 'BYLADEM1001');
|
||||
call createHsOfficeBankAccountTestData('Peter Smith', 'DE02500105170137075030', 'INGDDEFF');
|
||||
call createHsOfficeBankAccountTestData('Second e.K.', 'DE02100500000054540402', 'BELADEBE');
|
||||
call createHsOfficeBankAccountTestData('Third OHG', 'DE02300209000106531065', 'CMCIDEDD');
|
||||
call createHsOfficeBankAccountTestData('Fourth eG', 'DE02200505501015871393', 'HASPDEHH');
|
||||
call createHsOfficeBankAccountTestData('Mel Bessler', 'DE02100100100006820101', 'PBNKDEFF');
|
||||
call createHsOfficeBankAccountTestData('Anita Bessler', 'DE02300606010002474689', 'DAAEDEDD');
|
||||
call createHsOfficeBankAccountTestData('Paul Winkler', 'DE02600501010002034304', 'SOLADEST600');
|
||||
end;
|
||||
$$;
|
@ -0,0 +1,64 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-MAIN-TABLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create table hs_office_debitor
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||
debitorNumberSuffix numeric(2) not null,
|
||||
debitorRelUuid uuid not null references hs_office_relation(uuid),
|
||||
billable boolean not null default true,
|
||||
vatId varchar(24), -- TODO.spec: here or in person?
|
||||
vatCountryCode varchar(2),
|
||||
vatBusiness boolean not null,
|
||||
vatReverseCharge boolean not null,
|
||||
refundBankAccountUuid uuid references hs_office_bankaccount(uuid),
|
||||
defaultPrefix char(3) not null unique
|
||||
constraint check_default_prefix check (
|
||||
defaultPrefix::text ~ '^([a-z]{3}|al0|bh1|c4s|f3k|k8i|l3d|mh1|o13|p2m|s80|t4w)$'
|
||||
)
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-DELETE-DEPENDENTS-TRIGGER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
Trigger function to delete related rows of a debitor to delete.
|
||||
*/
|
||||
create or replace function deleteHsOfficeDependentsOnDebitorDelete()
|
||||
returns trigger
|
||||
language PLPGSQL
|
||||
as $$
|
||||
declare
|
||||
counter integer;
|
||||
begin
|
||||
DELETE FROM hs_office_relation r WHERE r.uuid = OLD.debitorRelUuid;
|
||||
GET DIAGNOSTICS counter = ROW_COUNT;
|
||||
if counter = 0 then
|
||||
raise exception 'debitor relation % could not be deleted', OLD.debitorRelUuid;
|
||||
end if;
|
||||
|
||||
RETURN OLD;
|
||||
end; $$;
|
||||
|
||||
/**
|
||||
Triggers deletion of related details of a debitor to delete.
|
||||
*/
|
||||
create trigger hs_office_debitor_delete_dependents_trigger
|
||||
after delete
|
||||
on hs_office_debitor
|
||||
for each row
|
||||
execute procedure deleteHsOfficeDependentsOnDebitorDelete();
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call create_journal('hs_office_debitor');
|
||||
--//
|
@ -0,0 +1,198 @@
|
||||
### rbac debitor
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"]
|
||||
direction TB
|
||||
style debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph debitorRel.anchorPerson:roles[ ]
|
||||
style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:debitorRel.anchorPerson:OWNER[[debitorRel.anchorPerson:OWNER]]
|
||||
role:debitorRel.anchorPerson:ADMIN[[debitorRel.anchorPerson:ADMIN]]
|
||||
role:debitorRel.anchorPerson:REFERRER[[debitorRel.anchorPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"]
|
||||
direction TB
|
||||
style debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph debitorRel.holderPerson:roles[ ]
|
||||
style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:debitorRel.holderPerson:OWNER[[debitorRel.holderPerson:OWNER]]
|
||||
role:debitorRel.holderPerson:ADMIN[[debitorRel.holderPerson:ADMIN]]
|
||||
role:debitorRel.holderPerson:REFERRER[[debitorRel.holderPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
|
||||
direction TB
|
||||
style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel.holderPerson:roles[ ]
|
||||
style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel.holderPerson:OWNER[[partnerRel.holderPerson:OWNER]]
|
||||
role:partnerRel.holderPerson:ADMIN[[partnerRel.holderPerson:ADMIN]]
|
||||
role:partnerRel.holderPerson:REFERRER[[partnerRel.holderPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph debitor["`**debitor**`"]
|
||||
direction TB
|
||||
style debitor fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph debitor:permissions[ ]
|
||||
style debitor:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:debitor:INSERT{{debitor:INSERT}}
|
||||
perm:debitor:DELETE{{debitor:DELETE}}
|
||||
perm:debitor:UPDATE{{debitor:UPDATE}}
|
||||
perm:debitor:SELECT{{debitor:SELECT}}
|
||||
end
|
||||
|
||||
subgraph debitorRel["`**debitorRel**`"]
|
||||
direction TB
|
||||
style debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph debitorRel:roles[ ]
|
||||
style debitorRel:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:debitorRel:OWNER[[debitorRel:OWNER]]
|
||||
role:debitorRel:ADMIN[[debitorRel:ADMIN]]
|
||||
role:debitorRel:AGENT[[debitorRel:AGENT]]
|
||||
role:debitorRel:TENANT[[debitorRel:TENANT]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
subgraph partnerRel["`**partnerRel**`"]
|
||||
direction TB
|
||||
style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel:roles[ ]
|
||||
style partnerRel:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel:OWNER[[partnerRel:OWNER]]
|
||||
role:partnerRel:ADMIN[[partnerRel:ADMIN]]
|
||||
role:partnerRel:AGENT[[partnerRel:AGENT]]
|
||||
role:partnerRel:TENANT[[partnerRel:TENANT]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph partnerRel.contact["`**partnerRel.contact**`"]
|
||||
direction TB
|
||||
style partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel.contact:roles[ ]
|
||||
style partnerRel.contact:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel.contact:OWNER[[partnerRel.contact:OWNER]]
|
||||
role:partnerRel.contact:ADMIN[[partnerRel.contact:ADMIN]]
|
||||
role:partnerRel.contact:REFERRER[[partnerRel.contact:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph debitorRel.contact["`**debitorRel.contact**`"]
|
||||
direction TB
|
||||
style debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph debitorRel.contact:roles[ ]
|
||||
style debitorRel.contact:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:debitorRel.contact:OWNER[[debitorRel.contact:OWNER]]
|
||||
role:debitorRel.contact:ADMIN[[debitorRel.contact:ADMIN]]
|
||||
role:debitorRel.contact:REFERRER[[debitorRel.contact:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
||||
direction TB
|
||||
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel.anchorPerson:roles[ ]
|
||||
style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel.anchorPerson:OWNER[[partnerRel.anchorPerson:OWNER]]
|
||||
role:partnerRel.anchorPerson:ADMIN[[partnerRel.anchorPerson:ADMIN]]
|
||||
role:partnerRel.anchorPerson:REFERRER[[partnerRel.anchorPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph refundBankAccount["`**refundBankAccount**`"]
|
||||
direction TB
|
||||
style refundBankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph refundBankAccount:roles[ ]
|
||||
style refundBankAccount:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:refundBankAccount:OWNER[[refundBankAccount:OWNER]]
|
||||
role:refundBankAccount:ADMIN[[refundBankAccount:ADMIN]]
|
||||
role:refundBankAccount:REFERRER[[refundBankAccount:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:ADMIN -.-> role:debitorRel.anchorPerson:OWNER
|
||||
role:debitorRel.anchorPerson:OWNER -.-> role:debitorRel.anchorPerson:ADMIN
|
||||
role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel.anchorPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:debitorRel.holderPerson:OWNER
|
||||
role:debitorRel.holderPerson:OWNER -.-> role:debitorRel.holderPerson:ADMIN
|
||||
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel.holderPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:debitorRel.contact:OWNER
|
||||
role:debitorRel.contact:OWNER -.-> role:debitorRel.contact:ADMIN
|
||||
role:debitorRel.contact:ADMIN -.-> role:debitorRel.contact:REFERRER
|
||||
role:global:ADMIN -.-> role:debitorRel:OWNER
|
||||
role:debitorRel:OWNER -.-> role:debitorRel:ADMIN
|
||||
role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:ADMIN
|
||||
role:debitorRel:ADMIN -.-> role:debitorRel:AGENT
|
||||
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT
|
||||
role:debitorRel:AGENT -.-> role:debitorRel:TENANT
|
||||
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:TENANT
|
||||
role:debitorRel.contact:ADMIN -.-> role:debitorRel:TENANT
|
||||
role:debitorRel:TENANT -.-> role:debitorRel.anchorPerson:REFERRER
|
||||
role:debitorRel:TENANT -.-> role:debitorRel.holderPerson:REFERRER
|
||||
role:debitorRel:TENANT -.-> role:debitorRel.contact:REFERRER
|
||||
role:global:ADMIN -.-> role:refundBankAccount:OWNER
|
||||
role:refundBankAccount:OWNER -.-> role:refundBankAccount:ADMIN
|
||||
role:refundBankAccount:ADMIN -.-> role:refundBankAccount:REFERRER
|
||||
role:refundBankAccount:ADMIN ==> role:debitorRel:AGENT
|
||||
role:debitorRel:AGENT ==> role:refundBankAccount:REFERRER
|
||||
role:global:ADMIN -.-> role:partnerRel.anchorPerson:OWNER
|
||||
role:partnerRel.anchorPerson:OWNER -.-> role:partnerRel.anchorPerson:ADMIN
|
||||
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel.anchorPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:partnerRel.holderPerson:OWNER
|
||||
role:partnerRel.holderPerson:OWNER -.-> role:partnerRel.holderPerson:ADMIN
|
||||
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel.holderPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:partnerRel.contact:OWNER
|
||||
role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN
|
||||
role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER
|
||||
role:global:ADMIN -.-> role:partnerRel:OWNER
|
||||
role:partnerRel:OWNER -.-> role:partnerRel:ADMIN
|
||||
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:ADMIN
|
||||
role:partnerRel:ADMIN -.-> role:partnerRel:AGENT
|
||||
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
|
||||
role:partnerRel:AGENT -.-> role:partnerRel:TENANT
|
||||
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:TENANT
|
||||
role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT
|
||||
role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER
|
||||
role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER
|
||||
role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER
|
||||
role:partnerRel:ADMIN ==> role:debitorRel:ADMIN
|
||||
role:partnerRel:AGENT ==> role:debitorRel:AGENT
|
||||
role:debitorRel:AGENT ==> role:partnerRel:TENANT
|
||||
|
||||
%% granting permissions to roles
|
||||
role:global:ADMIN ==> perm:debitor:INSERT
|
||||
role:debitorRel:OWNER ==> perm:debitor:DELETE
|
||||
role:debitorRel:ADMIN ==> perm:debitor:UPDATE
|
||||
role:debitorRel:TENANT ==> perm:debitor:SELECT
|
||||
|
||||
```
|
@ -0,0 +1,227 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-rbac-OBJECT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('hs_office_debitor');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('hsOfficeDebitor', 'hs_office_debitor');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficeDebitor(
|
||||
NEW hs_office_debitor
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
newPartnerRel hs_office_relation;
|
||||
newDebitorRel hs_office_relation;
|
||||
newRefundBankAccount hs_office_bankaccount;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT partnerRel.*
|
||||
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 NEW.debitorRelUuid = debitorRel.uuid
|
||||
INTO newPartnerRel;
|
||||
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
|
||||
|
||||
SELECT * FROM hs_office_relation WHERE uuid = NEW.debitorRelUuid INTO newDebitorRel;
|
||||
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorRelUuid = %s', NEW.debitorRelUuid);
|
||||
|
||||
SELECT * FROM hs_office_bankaccount WHERE uuid = NEW.refundBankAccountUuid INTO newRefundBankAccount;
|
||||
|
||||
call grantRoleToRole(hsOfficeBankAccountREFERRER(newRefundBankAccount), hsOfficeRelationAGENT(newDebitorRel));
|
||||
call grantRoleToRole(hsOfficeRelationADMIN(newDebitorRel), hsOfficeRelationADMIN(newPartnerRel));
|
||||
call grantRoleToRole(hsOfficeRelationAGENT(newDebitorRel), hsOfficeBankAccountADMIN(newRefundBankAccount));
|
||||
call grantRoleToRole(hsOfficeRelationAGENT(newDebitorRel), hsOfficeRelationAGENT(newPartnerRel));
|
||||
call grantRoleToRole(hsOfficeRelationTENANT(newPartnerRel), hsOfficeRelationAGENT(newDebitorRel));
|
||||
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationOWNER(newDebitorRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTENANT(newDebitorRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationADMIN(newDebitorRel));
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_debitor row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficeDebitor_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficeDebitor(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForHsOfficeDebitor_tg
|
||||
after insert on hs_office_debitor
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficeDebitor_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-rbac-update-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
|
||||
*/
|
||||
|
||||
create or replace procedure updateRbacRulesForHsOfficeDebitor(
|
||||
OLD hs_office_debitor,
|
||||
NEW hs_office_debitor
|
||||
)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
|
||||
if NEW.debitorRelUuid is distinct from OLD.debitorRelUuid
|
||||
or NEW.refundBankAccountUuid is distinct from OLD.refundBankAccountUuid then
|
||||
delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid;
|
||||
call buildRbacSystemForHsOfficeDebitor(NEW);
|
||||
end if;
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new hs_office_debitor row.
|
||||
*/
|
||||
|
||||
create or replace function updateTriggerForHsOfficeDebitor_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call updateRbacRulesForHsOfficeDebitor(OLD, NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger updateTriggerForHsOfficeDebitor_tg
|
||||
after update on hs_office_debitor
|
||||
for each row
|
||||
execute procedure updateTriggerForHsOfficeDebitor_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_debitor permissions for the related global rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_debitor permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_debitor'),
|
||||
globalADMIN());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_debitor INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function hs_office_debitor_global_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_debitor'),
|
||||
globalADMIN());
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_hs_office_debitor_global_insert_tg
|
||||
after insert on global
|
||||
for each row
|
||||
execute procedure hs_office_debitor_global_insert_tf();
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_debitor,
|
||||
where only global-admin has that permission.
|
||||
*/
|
||||
create or replace function hs_office_debitor_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into hs_office_debitor not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_debitor_insert_permission_check_tg
|
||||
before insert on hs_office_debitor
|
||||
for each row
|
||||
when ( not isGlobalAdmin() )
|
||||
execute procedure hs_office_debitor_insert_permission_missing_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityViewFromQuery('hs_office_debitor',
|
||||
$idName$
|
||||
SELECT debitor.uuid AS uuid,
|
||||
'D-' || (SELECT partner.partnerNumber
|
||||
FROM hs_office_partner partner
|
||||
JOIN hs_office_relation partnerRel
|
||||
ON partnerRel.uuid = partner.partnerRelUUid AND partnerRel.type = 'PARTNER'
|
||||
JOIN hs_office_relation debitorRel
|
||||
ON debitorRel.anchorUuid = partnerRel.holderUuid AND debitorRel.type = 'DEBITOR'
|
||||
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|
||||
|| to_char(debitorNumberSuffix, 'fm00') as idName
|
||||
FROM hs_office_debitor AS debitor
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_debitor',
|
||||
$orderBy$
|
||||
defaultPrefix
|
||||
$orderBy$,
|
||||
$updates$
|
||||
debitorRelUuid = new.debitorRelUuid,
|
||||
billable = new.billable,
|
||||
refundBankAccountUuid = new.refundBankAccountUuid,
|
||||
vatId = new.vatId,
|
||||
vatCountryCode = new.vatCountryCode,
|
||||
vatBusiness = new.vatBusiness,
|
||||
vatReverseCharge = new.vatReverseCharge,
|
||||
defaultPrefix = new.defaultPrefix
|
||||
$updates$);
|
||||
--//
|
||||
|
@ -0,0 +1,62 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates a single debitor test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficeDebitorTestData(
|
||||
withDebitorNumberSuffix numeric(5),
|
||||
forPartnerPersonName varchar,
|
||||
forBillingContactLabel varchar,
|
||||
withDefaultPrefix varchar
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentTask varchar;
|
||||
idName varchar;
|
||||
relatedDebitorRelUuid uuid;
|
||||
relatedBankAccountUuid uuid;
|
||||
begin
|
||||
idName := cleanIdentifier( forPartnerPersonName|| '-' || forBillingContactLabel);
|
||||
currentTask := 'creating debitor test-data ' || idName;
|
||||
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
select debitorRel.uuid
|
||||
into relatedDebitorRelUuid
|
||||
from hs_office_relation debitorRel
|
||||
join hs_office_person person on person.uuid = debitorRel.holderUuid
|
||||
and (person.tradeName = forPartnerPersonName or person.familyName = forPartnerPersonName)
|
||||
where debitorRel.type = 'DEBITOR';
|
||||
|
||||
select b.uuid
|
||||
into relatedBankAccountUuid
|
||||
from hs_office_bankaccount b
|
||||
where b.holder = forPartnerPersonName;
|
||||
|
||||
raise notice 'creating test debitor: % (#%)', idName, withDebitorNumberSuffix;
|
||||
-- raise exception 'creating test debitor: (uuid=%, debitorRelUuid=%, debitornumbersuffix=%, billable=%, vatbusiness=%, vatreversecharge=%, refundbankaccountuuid=%, defaultprefix=%)',
|
||||
-- uuid_generate_v4(), relatedDebitorRelUuid, withDebitorNumberSuffix, true, true, false, relatedBankAccountUuid, withDefaultPrefix;
|
||||
insert
|
||||
into hs_office_debitor (uuid, debitorRelUuid, debitornumbersuffix, billable, vatbusiness, vatreversecharge, refundbankaccountuuid, defaultprefix)
|
||||
values (uuid_generate_v4(), relatedDebitorRelUuid, withDebitorNumberSuffix, true, true, false, relatedBankAccountUuid, withDefaultPrefix);
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-debitor-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call createHsOfficeDebitorTestData(11, 'First GmbH', 'first contact', 'fir');
|
||||
call createHsOfficeDebitorTestData(12, 'Second e.K.', 'second contact', 'sec');
|
||||
call createHsOfficeDebitorTestData(13, 'Third OHG', 'third contact', 'thi');
|
||||
end;
|
||||
$$;
|
||||
--//
|
@ -0,0 +1,24 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-MAIN-TABLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create table if not exists hs_office_sepamandate
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||
debitorUuid uuid not null references hs_office_debitor(uuid),
|
||||
bankAccountUuid uuid not null references hs_office_bankaccount(uuid),
|
||||
reference varchar(96) not null,
|
||||
agreement date not null,
|
||||
validity daterange not null
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call create_journal('hs_office_sepamandate');
|
||||
--//
|
@ -0,0 +1,141 @@
|
||||
### rbac sepaMandate
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph bankAccount["`**bankAccount**`"]
|
||||
direction TB
|
||||
style bankAccount fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph bankAccount:roles[ ]
|
||||
style bankAccount:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:bankAccount:OWNER[[bankAccount:OWNER]]
|
||||
role:bankAccount:ADMIN[[bankAccount:ADMIN]]
|
||||
role:bankAccount:REFERRER[[bankAccount:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph debitorRel.contact["`**debitorRel.contact**`"]
|
||||
direction TB
|
||||
style debitorRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph debitorRel.contact:roles[ ]
|
||||
style debitorRel.contact:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:debitorRel.contact:OWNER[[debitorRel.contact:OWNER]]
|
||||
role:debitorRel.contact:ADMIN[[debitorRel.contact:ADMIN]]
|
||||
role:debitorRel.contact:REFERRER[[debitorRel.contact:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph debitorRel.anchorPerson["`**debitorRel.anchorPerson**`"]
|
||||
direction TB
|
||||
style debitorRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph debitorRel.anchorPerson:roles[ ]
|
||||
style debitorRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:debitorRel.anchorPerson:OWNER[[debitorRel.anchorPerson:OWNER]]
|
||||
role:debitorRel.anchorPerson:ADMIN[[debitorRel.anchorPerson:ADMIN]]
|
||||
role:debitorRel.anchorPerson:REFERRER[[debitorRel.anchorPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph debitorRel.holderPerson["`**debitorRel.holderPerson**`"]
|
||||
direction TB
|
||||
style debitorRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph debitorRel.holderPerson:roles[ ]
|
||||
style debitorRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:debitorRel.holderPerson:OWNER[[debitorRel.holderPerson:OWNER]]
|
||||
role:debitorRel.holderPerson:ADMIN[[debitorRel.holderPerson:ADMIN]]
|
||||
role:debitorRel.holderPerson:REFERRER[[debitorRel.holderPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph sepaMandate["`**sepaMandate**`"]
|
||||
direction TB
|
||||
style sepaMandate fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph sepaMandate:roles[ ]
|
||||
style sepaMandate:roles fill:#dd4901,stroke:white
|
||||
|
||||
role:sepaMandate:OWNER[[sepaMandate:OWNER]]
|
||||
role:sepaMandate:ADMIN[[sepaMandate:ADMIN]]
|
||||
role:sepaMandate:AGENT[[sepaMandate:AGENT]]
|
||||
role:sepaMandate:REFERRER[[sepaMandate:REFERRER]]
|
||||
end
|
||||
|
||||
subgraph sepaMandate:permissions[ ]
|
||||
style sepaMandate:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:sepaMandate:DELETE{{sepaMandate:DELETE}}
|
||||
perm:sepaMandate:UPDATE{{sepaMandate:UPDATE}}
|
||||
perm:sepaMandate:SELECT{{sepaMandate:SELECT}}
|
||||
perm:sepaMandate:INSERT{{sepaMandate:INSERT}}
|
||||
end
|
||||
end
|
||||
|
||||
subgraph debitorRel["`**debitorRel**`"]
|
||||
direction TB
|
||||
style debitorRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph debitorRel:roles[ ]
|
||||
style debitorRel:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:debitorRel:OWNER[[debitorRel:OWNER]]
|
||||
role:debitorRel:ADMIN[[debitorRel:ADMIN]]
|
||||
role:debitorRel:AGENT[[debitorRel:AGENT]]
|
||||
role:debitorRel:TENANT[[debitorRel:TENANT]]
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to users
|
||||
user:creator ==> role:sepaMandate:OWNER
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:ADMIN -.-> role:debitorRel.anchorPerson:OWNER
|
||||
role:debitorRel.anchorPerson:OWNER -.-> role:debitorRel.anchorPerson:ADMIN
|
||||
role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel.anchorPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:debitorRel.holderPerson:OWNER
|
||||
role:debitorRel.holderPerson:OWNER -.-> role:debitorRel.holderPerson:ADMIN
|
||||
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel.holderPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:debitorRel.contact:OWNER
|
||||
role:debitorRel.contact:OWNER -.-> role:debitorRel.contact:ADMIN
|
||||
role:debitorRel.contact:ADMIN -.-> role:debitorRel.contact:REFERRER
|
||||
role:global:ADMIN -.-> role:debitorRel:OWNER
|
||||
role:debitorRel:OWNER -.-> role:debitorRel:ADMIN
|
||||
role:debitorRel.anchorPerson:ADMIN -.-> role:debitorRel:ADMIN
|
||||
role:debitorRel:ADMIN -.-> role:debitorRel:AGENT
|
||||
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:AGENT
|
||||
role:debitorRel:AGENT -.-> role:debitorRel:TENANT
|
||||
role:debitorRel.holderPerson:ADMIN -.-> role:debitorRel:TENANT
|
||||
role:debitorRel.contact:ADMIN -.-> role:debitorRel:TENANT
|
||||
role:debitorRel:TENANT -.-> role:debitorRel.anchorPerson:REFERRER
|
||||
role:debitorRel:TENANT -.-> role:debitorRel.holderPerson:REFERRER
|
||||
role:debitorRel:TENANT -.-> role:debitorRel.contact:REFERRER
|
||||
role:global:ADMIN -.-> role:bankAccount:OWNER
|
||||
role:bankAccount:OWNER -.-> role:bankAccount:ADMIN
|
||||
role:bankAccount:ADMIN -.-> role:bankAccount:REFERRER
|
||||
role:global:ADMIN ==> role:sepaMandate:OWNER
|
||||
role:sepaMandate:OWNER ==> role:sepaMandate:ADMIN
|
||||
role:sepaMandate:ADMIN ==> role:sepaMandate:AGENT
|
||||
role:sepaMandate:AGENT ==> role:bankAccount:REFERRER
|
||||
role:sepaMandate:AGENT ==> role:debitorRel:AGENT
|
||||
role:sepaMandate:AGENT ==> role:sepaMandate:REFERRER
|
||||
role:bankAccount:ADMIN ==> role:sepaMandate:REFERRER
|
||||
role:debitorRel:AGENT ==> role:sepaMandate:REFERRER
|
||||
role:sepaMandate:REFERRER ==> role:debitorRel:TENANT
|
||||
|
||||
%% granting permissions to roles
|
||||
role:sepaMandate:OWNER ==> perm:sepaMandate:DELETE
|
||||
role:sepaMandate:ADMIN ==> perm:sepaMandate:UPDATE
|
||||
role:sepaMandate:REFERRER ==> perm:sepaMandate:SELECT
|
||||
role:debitorRel:ADMIN ==> perm:sepaMandate:INSERT
|
||||
|
||||
```
|
@ -0,0 +1,207 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-rbac-OBJECT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('hs_office_sepamandate');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('hsOfficeSepaMandate', 'hs_office_sepamandate');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficeSepaMandate(
|
||||
NEW hs_office_sepamandate
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
newBankAccount hs_office_bankaccount;
|
||||
newDebitorRel hs_office_relation;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM hs_office_bankaccount WHERE uuid = NEW.bankAccountUuid INTO newBankAccount;
|
||||
assert newBankAccount.uuid is not null, format('newBankAccount must not be null for NEW.bankAccountUuid = %s', NEW.bankAccountUuid);
|
||||
|
||||
SELECT debitorRel.*
|
||||
FROM hs_office_relation debitorRel
|
||||
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||
WHERE debitor.uuid = NEW.debitorUuid
|
||||
INTO newDebitorRel;
|
||||
assert newDebitorRel.uuid is not null, format('newDebitorRel must not be null for NEW.debitorUuid = %s', NEW.debitorUuid);
|
||||
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeSepaMandateOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalADMIN()],
|
||||
userUuids => array[currentUserUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeSepaMandateADMIN(NEW),
|
||||
permissions => array['UPDATE'],
|
||||
incomingSuperRoles => array[hsOfficeSepaMandateOWNER(NEW)]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeSepaMandateAGENT(NEW),
|
||||
incomingSuperRoles => array[hsOfficeSepaMandateADMIN(NEW)],
|
||||
outgoingSubRoles => array[
|
||||
hsOfficeBankAccountREFERRER(newBankAccount),
|
||||
hsOfficeRelationAGENT(newDebitorRel)]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeSepaMandateREFERRER(NEW),
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[
|
||||
hsOfficeBankAccountADMIN(newBankAccount),
|
||||
hsOfficeRelationAGENT(newDebitorRel),
|
||||
hsOfficeSepaMandateAGENT(NEW)],
|
||||
outgoingSubRoles => array[hsOfficeRelationTENANT(newDebitorRel)]
|
||||
);
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_sepamandate row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficeSepaMandate_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficeSepaMandate(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForHsOfficeSepaMandate_tg
|
||||
after insert on hs_office_sepamandate
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficeSepaMandate_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_sepamandate permissions for the related hs_office_relation rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row hs_office_relation;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_sepamandate permissions for the related hs_office_relation rows');
|
||||
|
||||
FOR row IN SELECT * FROM hs_office_relation
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_sepamandate'),
|
||||
hsOfficeRelationADMIN(row));
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_sepamandate INSERT permission to specified role of new hs_office_relation rows.
|
||||
*/
|
||||
create or replace function hs_office_sepamandate_hs_office_relation_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_sepamandate'),
|
||||
hsOfficeRelationADMIN(NEW));
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_hs_office_sepamandate_hs_office_relation_insert_tg
|
||||
after insert on hs_office_relation
|
||||
for each row
|
||||
execute procedure hs_office_sepamandate_hs_office_relation_insert_tf();
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_sepamandate,
|
||||
where the check is performed by an indirect role.
|
||||
|
||||
An indirect role is a role which depends on an object uuid which is not a direct foreign key
|
||||
of the source entity, but needs to be fetched via joined tables.
|
||||
*/
|
||||
create or replace function hs_office_sepamandate_insert_permission_check_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
superRoleObjectUuid uuid;
|
||||
|
||||
begin
|
||||
superRoleObjectUuid := (SELECT debitorRel.uuid
|
||||
FROM hs_office_relation debitorRel
|
||||
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
|
||||
WHERE debitor.uuid = NEW.debitorUuid
|
||||
);
|
||||
assert superRoleObjectUuid is not null, 'superRoleObjectUuid must not be null';
|
||||
|
||||
if ( not hasInsertPermission(superRoleObjectUuid, 'INSERT', 'hs_office_sepamandate') ) then
|
||||
raise exception
|
||||
'[403] insert into hs_office_sepamandate not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end if;
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_sepamandate_insert_permission_check_tg
|
||||
before insert on hs_office_sepamandate
|
||||
for each row
|
||||
execute procedure hs_office_sepamandate_insert_permission_check_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityViewFromQuery('hs_office_sepamandate',
|
||||
$idName$
|
||||
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
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_sepamandate',
|
||||
$orderBy$
|
||||
validity
|
||||
$orderBy$,
|
||||
$updates$
|
||||
reference = new.reference,
|
||||
agreement = new.agreement,
|
||||
validity = new.validity
|
||||
$updates$);
|
||||
--//
|
||||
|
@ -0,0 +1,97 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- TODO: These changesets are just for the external remote views to simulate the legacy tables.
|
||||
-- Once we don't need the external remote views anymore, create revert changesets.
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-MIGRATION-mapping:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE hs_office_sepamandate_legacy_id
|
||||
(
|
||||
uuid uuid NOT NULL REFERENCES hs_office_sepamandate(uuid),
|
||||
sepa_mandate_id integer NOT NULL
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-MIGRATION-sequence:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE SEQUENCE IF NOT EXISTS hs_office_sepamandate_legacy_id_seq
|
||||
AS integer
|
||||
START 1000000000
|
||||
OWNED BY hs_office_sepamandate_legacy_id.sepa_mandate_id;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-MIGRATION-default:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
ALTER TABLE hs_office_sepamandate_legacy_id
|
||||
ALTER COLUMN sepa_mandate_id
|
||||
SET DEFAULT nextVal('hs_office_sepamandate_legacy_id_seq');
|
||||
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-MIGRATION-insert:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CALL defineContext('schema-migration');
|
||||
INSERT INTO hs_office_sepamandate_legacy_id(uuid, sepa_mandate_id)
|
||||
SELECT uuid, nextVal('hs_office_sepamandate_legacy_id_seq') FROM hs_office_sepamandate;
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-MIGRATION-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
create or replace function insertSepaMandateLegacyIdMapping()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
if TG_OP <> 'INSERT' then
|
||||
raise exception 'invalid usage of trigger';
|
||||
end if;
|
||||
|
||||
INSERT INTO hs_office_sepamandate_legacy_id VALUES
|
||||
(NEW.uuid, nextVal('hs_office_sepamandate_legacy_id_seq'));
|
||||
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger createSepaMandateLegacyIdMapping
|
||||
after insert on hs_office_sepamandate
|
||||
for each row
|
||||
execute procedure insertSepaMandateLegacyIdMapping();
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepamandate-MIGRATION-delete-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
create or replace function deleteSepaMandateLegacyIdMapping()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
if TG_OP <> 'DELETE' then
|
||||
raise exception 'invalid usage of trigger';
|
||||
end if;
|
||||
|
||||
DELETE FROM hs_office_sepamandate_legacy_id
|
||||
WHERE uuid = OLD.uuid;
|
||||
|
||||
return OLD;
|
||||
end; $$;
|
||||
|
||||
create trigger removeSepaMandateLegacyIdMapping
|
||||
before delete on hs_office_sepamandate
|
||||
for each row
|
||||
execute procedure deleteSepaMandateLegacyIdMapping();
|
||||
--/
|
@ -0,0 +1,56 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepaMandate-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates a single sepaMandate test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficeSepaMandateTestData(
|
||||
forPartnerNumber numeric(5),
|
||||
forDebitorSuffix numeric(2),
|
||||
forIban varchar,
|
||||
withReference varchar)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentTask varchar;
|
||||
relatedDebitor hs_office_debitor;
|
||||
relatedBankAccount hs_office_bankAccount;
|
||||
begin
|
||||
currentTask := 'creating SEPA-mandate test-data ' || forPartnerNumber::text || forDebitorSuffix::text;
|
||||
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
select debitor.* into relatedDebitor
|
||||
from hs_office_debitor debitor
|
||||
join hs_office_relation debitorRel on debitorRel.uuid = debitor.debitorRelUuid
|
||||
join hs_office_relation partnerRel on partnerRel.holderUuid = debitorRel.anchorUuid
|
||||
join hs_office_partner partner on partner.partnerRelUuid = partnerRel.uuid
|
||||
where partner.partnerNumber = forPartnerNumber and debitor.debitorNumberSuffix = forDebitorSuffix;
|
||||
select b.* into relatedBankAccount
|
||||
from hs_office_bankAccount b where b.iban = forIban;
|
||||
|
||||
raise notice 'creating test SEPA-mandate: %', forPartnerNumber::text || forDebitorSuffix::text;
|
||||
raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;
|
||||
raise notice '- using bankAccount (%): %', relatedBankAccount.uuid, relatedBankAccount;
|
||||
insert
|
||||
into hs_office_sepamandate (uuid, debitoruuid, bankAccountuuid, reference, agreement, validity)
|
||||
values (uuid_generate_v4(), relatedDebitor.uuid, relatedBankAccount.uuid, withReference, '20220930', daterange('20221001' , '20261231', '[]'));
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-sepaMandate-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call createHsOfficeSepaMandateTestData(10001, 11, 'DE02120300000000202051', 'ref-10001-11');
|
||||
call createHsOfficeSepaMandateTestData(10002, 12, 'DE02100500000054540402', 'ref-10002-12');
|
||||
call createHsOfficeSepaMandateTestData(10003, 13, 'DE02300209000106531065', 'ref-10003-13');
|
||||
end;
|
||||
$$;
|
||||
--//
|
@ -0,0 +1,31 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-membership-MAIN-TABLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE TYPE HsOfficeReasonForTermination AS ENUM ('NONE', 'CANCELLATION', 'TRANSFER', 'DEATH', 'LIQUIDATION', 'EXPULSION', 'UNKNOWN');
|
||||
|
||||
CREATE CAST (character varying as HsOfficeReasonForTermination) WITH INOUT AS IMPLICIT;
|
||||
|
||||
create table if not exists hs_office_membership
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||
partnerUuid uuid not null references hs_office_partner(uuid),
|
||||
memberNumberSuffix char(2) not null check (
|
||||
memberNumberSuffix::text ~ '^[0-9][0-9]$'),
|
||||
validity daterange not null,
|
||||
reasonForTermination HsOfficeReasonForTermination not null default 'NONE',
|
||||
membershipFeeBillable boolean not null default true,
|
||||
|
||||
UNIQUE(partnerUuid, memberNumberSuffix)
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-membership-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call create_journal('hs_office_membership');
|
||||
--//
|
@ -0,0 +1,120 @@
|
||||
### rbac membership
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph partnerRel["`**partnerRel**`"]
|
||||
direction TB
|
||||
style partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel:roles[ ]
|
||||
style partnerRel:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel:OWNER[[partnerRel:OWNER]]
|
||||
role:partnerRel:ADMIN[[partnerRel:ADMIN]]
|
||||
role:partnerRel:AGENT[[partnerRel:AGENT]]
|
||||
role:partnerRel:TENANT[[partnerRel:TENANT]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph partnerRel.contact["`**partnerRel.contact**`"]
|
||||
direction TB
|
||||
style partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel.contact:roles[ ]
|
||||
style partnerRel.contact:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel.contact:OWNER[[partnerRel.contact:OWNER]]
|
||||
role:partnerRel.contact:ADMIN[[partnerRel.contact:ADMIN]]
|
||||
role:partnerRel.contact:REFERRER[[partnerRel.contact:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph membership["`**membership**`"]
|
||||
direction TB
|
||||
style membership fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph membership:roles[ ]
|
||||
style membership:roles fill:#dd4901,stroke:white
|
||||
|
||||
role:membership:OWNER[[membership:OWNER]]
|
||||
role:membership:ADMIN[[membership:ADMIN]]
|
||||
role:membership:AGENT[[membership:AGENT]]
|
||||
end
|
||||
|
||||
subgraph membership:permissions[ ]
|
||||
style membership:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:membership:INSERT{{membership:INSERT}}
|
||||
perm:membership:DELETE{{membership:DELETE}}
|
||||
perm:membership:UPDATE{{membership:UPDATE}}
|
||||
perm:membership:SELECT{{membership:SELECT}}
|
||||
end
|
||||
end
|
||||
|
||||
subgraph partnerRel.anchorPerson["`**partnerRel.anchorPerson**`"]
|
||||
direction TB
|
||||
style partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel.anchorPerson:roles[ ]
|
||||
style partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel.anchorPerson:OWNER[[partnerRel.anchorPerson:OWNER]]
|
||||
role:partnerRel.anchorPerson:ADMIN[[partnerRel.anchorPerson:ADMIN]]
|
||||
role:partnerRel.anchorPerson:REFERRER[[partnerRel.anchorPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph partnerRel.holderPerson["`**partnerRel.holderPerson**`"]
|
||||
direction TB
|
||||
style partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph partnerRel.holderPerson:roles[ ]
|
||||
style partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:partnerRel.holderPerson:OWNER[[partnerRel.holderPerson:OWNER]]
|
||||
role:partnerRel.holderPerson:ADMIN[[partnerRel.holderPerson:ADMIN]]
|
||||
role:partnerRel.holderPerson:REFERRER[[partnerRel.holderPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to users
|
||||
user:creator ==> role:membership:OWNER
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:ADMIN -.-> role:partnerRel.anchorPerson:OWNER
|
||||
role:partnerRel.anchorPerson:OWNER -.-> role:partnerRel.anchorPerson:ADMIN
|
||||
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel.anchorPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:partnerRel.holderPerson:OWNER
|
||||
role:partnerRel.holderPerson:OWNER -.-> role:partnerRel.holderPerson:ADMIN
|
||||
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel.holderPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:partnerRel.contact:OWNER
|
||||
role:partnerRel.contact:OWNER -.-> role:partnerRel.contact:ADMIN
|
||||
role:partnerRel.contact:ADMIN -.-> role:partnerRel.contact:REFERRER
|
||||
role:global:ADMIN -.-> role:partnerRel:OWNER
|
||||
role:partnerRel:OWNER -.-> role:partnerRel:ADMIN
|
||||
role:partnerRel.anchorPerson:ADMIN -.-> role:partnerRel:ADMIN
|
||||
role:partnerRel:ADMIN -.-> role:partnerRel:AGENT
|
||||
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:AGENT
|
||||
role:partnerRel:AGENT -.-> role:partnerRel:TENANT
|
||||
role:partnerRel.holderPerson:ADMIN -.-> role:partnerRel:TENANT
|
||||
role:partnerRel.contact:ADMIN -.-> role:partnerRel:TENANT
|
||||
role:partnerRel:TENANT -.-> role:partnerRel.anchorPerson:REFERRER
|
||||
role:partnerRel:TENANT -.-> role:partnerRel.holderPerson:REFERRER
|
||||
role:partnerRel:TENANT -.-> role:partnerRel.contact:REFERRER
|
||||
role:membership:OWNER ==> role:membership:ADMIN
|
||||
role:partnerRel:ADMIN ==> role:membership:ADMIN
|
||||
role:membership:ADMIN ==> role:membership:AGENT
|
||||
role:partnerRel:AGENT ==> role:membership:AGENT
|
||||
role:membership:AGENT ==> role:partnerRel:TENANT
|
||||
|
||||
%% granting permissions to roles
|
||||
role:global:ADMIN ==> perm:membership:INSERT
|
||||
role:membership:ADMIN ==> perm:membership:DELETE
|
||||
role:membership:ADMIN ==> perm:membership:UPDATE
|
||||
role:membership:AGENT ==> perm:membership:SELECT
|
||||
|
||||
```
|
@ -0,0 +1,178 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-membership-rbac-OBJECT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('hs_office_membership');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-membership-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('hsOfficeMembership', 'hs_office_membership');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-membership-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficeMembership(
|
||||
NEW hs_office_membership
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
newPartnerRel hs_office_relation;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT partnerRel.*
|
||||
FROM hs_office_partner AS partner
|
||||
JOIN hs_office_relation AS partnerRel ON partnerRel.uuid = partner.partnerRelUuid
|
||||
WHERE partner.uuid = NEW.partnerUuid
|
||||
INTO newPartnerRel;
|
||||
assert newPartnerRel.uuid is not null, format('newPartnerRel must not be null for NEW.partnerUuid = %s', NEW.partnerUuid);
|
||||
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeMembershipOWNER(NEW),
|
||||
userUuids => array[currentUserUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeMembershipADMIN(NEW),
|
||||
permissions => array['DELETE', 'UPDATE'],
|
||||
incomingSuperRoles => array[
|
||||
hsOfficeMembershipOWNER(NEW),
|
||||
hsOfficeRelationADMIN(newPartnerRel)]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeMembershipAGENT(NEW),
|
||||
permissions => array['SELECT'],
|
||||
incomingSuperRoles => array[
|
||||
hsOfficeMembershipADMIN(NEW),
|
||||
hsOfficeRelationAGENT(newPartnerRel)],
|
||||
outgoingSubRoles => array[hsOfficeRelationTENANT(newPartnerRel)]
|
||||
);
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_membership row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficeMembership_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficeMembership(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForHsOfficeMembership_tg
|
||||
after insert on hs_office_membership
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficeMembership_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-membership-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_membership permissions for the related global rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_membership permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_membership'),
|
||||
globalADMIN());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_membership INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function hs_office_membership_global_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_membership'),
|
||||
globalADMIN());
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_hs_office_membership_global_insert_tg
|
||||
after insert on global
|
||||
for each row
|
||||
execute procedure hs_office_membership_global_insert_tf();
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_membership,
|
||||
where only global-admin has that permission.
|
||||
*/
|
||||
create or replace function hs_office_membership_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into hs_office_membership not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_membership_insert_permission_check_tg
|
||||
before insert on hs_office_membership
|
||||
for each row
|
||||
when ( not isGlobalAdmin() )
|
||||
execute procedure hs_office_membership_insert_permission_missing_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-membership-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityViewFromQuery('hs_office_membership',
|
||||
$idName$
|
||||
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
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-membership-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_membership',
|
||||
$orderBy$
|
||||
validity
|
||||
$orderBy$,
|
||||
$updates$
|
||||
validity = new.validity,
|
||||
membershipFeeBillable = new.membershipFeeBillable,
|
||||
reasonForTermination = new.reasonForTermination
|
||||
$updates$);
|
||||
--//
|
||||
|
@ -0,0 +1,48 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-membership-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates a single membership test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficeMembershipTestData(
|
||||
forPartnerNumber numeric(5),
|
||||
newMemberNumberSuffix char(2) )
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentTask varchar;
|
||||
relatedPartner hs_office_partner;
|
||||
begin
|
||||
currentTask := 'creating Membership test-data ' ||
|
||||
'P-' || forPartnerNumber::text ||
|
||||
'M-...' || newMemberNumberSuffix;
|
||||
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
select partner.* from hs_office_partner partner
|
||||
where partner.partnerNumber = forPartnerNumber into relatedPartner;
|
||||
|
||||
raise notice 'creating test Membership: M-% %', forPartnerNumber, newMemberNumberSuffix;
|
||||
raise notice '- using partner (%): %', relatedPartner.uuid, relatedPartner;
|
||||
insert
|
||||
into hs_office_membership (uuid, partneruuid, memberNumberSuffix, validity, reasonfortermination)
|
||||
values (uuid_generate_v4(), relatedPartner.uuid, newMemberNumberSuffix, daterange('20221001' , null, '[]'), 'NONE');
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-membership-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call createHsOfficeMembershipTestData(10001, '01');
|
||||
call createHsOfficeMembershipTestData(10002, '02');
|
||||
call createHsOfficeMembershipTestData(10003, '03');
|
||||
end;
|
||||
$$;
|
||||
--//
|
@ -0,0 +1,56 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopshares-MAIN-TABLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE TYPE HsOfficeCoopSharesTransactionType AS ENUM ('ADJUSTMENT', 'SUBSCRIPTION', 'CANCELLATION');
|
||||
|
||||
CREATE CAST (character varying as HsOfficeCoopSharesTransactionType) WITH INOUT AS IMPLICIT;
|
||||
|
||||
create table if not exists hs_office_coopsharestransaction
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||
membershipUuid uuid not null references hs_office_membership(uuid),
|
||||
transactionType HsOfficeCoopSharesTransactionType not null,
|
||||
valueDate date not null,
|
||||
shareCount integer,
|
||||
reference varchar(48),
|
||||
comment varchar(512)
|
||||
);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopshares-SHARE-COUNT-CONSTRAINT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create or replace function checkSharesByMembershipUuid(forMembershipUuid UUID, newShareCount integer)
|
||||
returns boolean
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentShareCount integer;
|
||||
totalShareCount integer;
|
||||
begin
|
||||
select sum(cst.shareCount)
|
||||
from hs_office_coopsharestransaction cst
|
||||
where cst.membershipUuid = forMembershipUuid
|
||||
into currentShareCount;
|
||||
totalShareCount := currentShareCount + newShareCount;
|
||||
if totalShareCount < 0 then
|
||||
raise exception '[400] coop shares transaction would result in a negative number of shares';
|
||||
end if;
|
||||
return true;
|
||||
end; $$;
|
||||
|
||||
alter table hs_office_coopsharestransaction
|
||||
add constraint hs_office_coopshares_positive
|
||||
check ( checkSharesByMembershipUuid(membershipUuid, shareCount) );
|
||||
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopshares-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call create_journal('hs_office_coopsharestransaction');
|
||||
--//
|
@ -0,0 +1,120 @@
|
||||
### rbac coopSharesTransaction
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph membership.partnerRel.holderPerson["`**membership.partnerRel.holderPerson**`"]
|
||||
direction TB
|
||||
style membership.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph membership.partnerRel.holderPerson:roles[ ]
|
||||
style membership.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:membership.partnerRel.holderPerson:OWNER[[membership.partnerRel.holderPerson:OWNER]]
|
||||
role:membership.partnerRel.holderPerson:ADMIN[[membership.partnerRel.holderPerson:ADMIN]]
|
||||
role:membership.partnerRel.holderPerson:REFERRER[[membership.partnerRel.holderPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph membership.partnerRel.anchorPerson["`**membership.partnerRel.anchorPerson**`"]
|
||||
direction TB
|
||||
style membership.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph membership.partnerRel.anchorPerson:roles[ ]
|
||||
style membership.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:membership.partnerRel.anchorPerson:OWNER[[membership.partnerRel.anchorPerson:OWNER]]
|
||||
role:membership.partnerRel.anchorPerson:ADMIN[[membership.partnerRel.anchorPerson:ADMIN]]
|
||||
role:membership.partnerRel.anchorPerson:REFERRER[[membership.partnerRel.anchorPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph coopSharesTransaction["`**coopSharesTransaction**`"]
|
||||
direction TB
|
||||
style coopSharesTransaction fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph coopSharesTransaction:permissions[ ]
|
||||
style coopSharesTransaction:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:coopSharesTransaction:INSERT{{coopSharesTransaction:INSERT}}
|
||||
perm:coopSharesTransaction:UPDATE{{coopSharesTransaction:UPDATE}}
|
||||
perm:coopSharesTransaction:SELECT{{coopSharesTransaction:SELECT}}
|
||||
end
|
||||
end
|
||||
|
||||
subgraph membership["`**membership**`"]
|
||||
direction TB
|
||||
style membership fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph membership:roles[ ]
|
||||
style membership:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:membership:OWNER[[membership:OWNER]]
|
||||
role:membership:ADMIN[[membership:ADMIN]]
|
||||
role:membership:AGENT[[membership:AGENT]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph membership.partnerRel["`**membership.partnerRel**`"]
|
||||
direction TB
|
||||
style membership.partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph membership.partnerRel:roles[ ]
|
||||
style membership.partnerRel:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:membership.partnerRel:OWNER[[membership.partnerRel:OWNER]]
|
||||
role:membership.partnerRel:ADMIN[[membership.partnerRel:ADMIN]]
|
||||
role:membership.partnerRel:AGENT[[membership.partnerRel:AGENT]]
|
||||
role:membership.partnerRel:TENANT[[membership.partnerRel:TENANT]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph membership.partnerRel.contact["`**membership.partnerRel.contact**`"]
|
||||
direction TB
|
||||
style membership.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph membership.partnerRel.contact:roles[ ]
|
||||
style membership.partnerRel.contact:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:membership.partnerRel.contact:OWNER[[membership.partnerRel.contact:OWNER]]
|
||||
role:membership.partnerRel.contact:ADMIN[[membership.partnerRel.contact:ADMIN]]
|
||||
role:membership.partnerRel.contact:REFERRER[[membership.partnerRel.contact:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:ADMIN -.-> role:membership.partnerRel.anchorPerson:OWNER
|
||||
role:membership.partnerRel.anchorPerson:OWNER -.-> role:membership.partnerRel.anchorPerson:ADMIN
|
||||
role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel.anchorPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:membership.partnerRel.holderPerson:OWNER
|
||||
role:membership.partnerRel.holderPerson:OWNER -.-> role:membership.partnerRel.holderPerson:ADMIN
|
||||
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel.holderPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:membership.partnerRel.contact:OWNER
|
||||
role:membership.partnerRel.contact:OWNER -.-> role:membership.partnerRel.contact:ADMIN
|
||||
role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel.contact:REFERRER
|
||||
role:global:ADMIN -.-> role:membership.partnerRel:OWNER
|
||||
role:membership.partnerRel:OWNER -.-> role:membership.partnerRel:ADMIN
|
||||
role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel:ADMIN
|
||||
role:membership.partnerRel:ADMIN -.-> role:membership.partnerRel:AGENT
|
||||
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:AGENT
|
||||
role:membership.partnerRel:AGENT -.-> role:membership.partnerRel:TENANT
|
||||
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:TENANT
|
||||
role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel:TENANT
|
||||
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.anchorPerson:REFERRER
|
||||
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.holderPerson:REFERRER
|
||||
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.contact:REFERRER
|
||||
role:membership:OWNER -.-> role:membership:ADMIN
|
||||
role:membership.partnerRel:ADMIN -.-> role:membership:ADMIN
|
||||
role:membership:ADMIN -.-> role:membership:AGENT
|
||||
role:membership.partnerRel:AGENT -.-> role:membership:AGENT
|
||||
role:membership:AGENT -.-> role:membership.partnerRel:TENANT
|
||||
|
||||
%% granting permissions to roles
|
||||
role:membership:ADMIN ==> perm:coopSharesTransaction:INSERT
|
||||
role:membership:ADMIN ==> perm:coopSharesTransaction:UPDATE
|
||||
role:membership:AGENT ==> perm:coopSharesTransaction:SELECT
|
||||
|
||||
```
|
@ -0,0 +1,151 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopsharestransaction-rbac-OBJECT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('hs_office_coopsharestransaction');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopsharestransaction-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('hsOfficeCoopSharesTransaction', 'hs_office_coopsharestransaction');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopsharestransaction-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficeCoopSharesTransaction(
|
||||
NEW hs_office_coopsharestransaction
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
newMembership hs_office_membership;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM hs_office_membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
||||
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s', NEW.membershipUuid);
|
||||
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeMembershipAGENT(newMembership));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeMembershipADMIN(newMembership));
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_coopsharestransaction row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficeCoopSharesTransaction_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficeCoopSharesTransaction(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForHsOfficeCoopSharesTransaction_tg
|
||||
after insert on hs_office_coopsharestransaction
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficeCoopSharesTransaction_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopsharestransaction-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_coopsharestransaction permissions for the related hs_office_membership rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row hs_office_membership;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_coopsharestransaction permissions for the related hs_office_membership rows');
|
||||
|
||||
FOR row IN SELECT * FROM hs_office_membership
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_coopsharestransaction'),
|
||||
hsOfficeMembershipADMIN(row));
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_coopsharestransaction INSERT permission to specified role of new hs_office_membership rows.
|
||||
*/
|
||||
create or replace function hs_office_coopsharestransaction_hs_office_membership_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_coopsharestransaction'),
|
||||
hsOfficeMembershipADMIN(NEW));
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_hs_office_coopsharestransaction_hs_office_membership_insert_tg
|
||||
after insert on hs_office_membership
|
||||
for each row
|
||||
execute procedure hs_office_coopsharestransaction_hs_office_membership_insert_tf();
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_coopsharestransaction,
|
||||
where the check is performed by a direct role.
|
||||
|
||||
A direct role is a role depending on a foreign key directly available in the NEW row.
|
||||
*/
|
||||
create or replace function hs_office_coopsharestransaction_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into hs_office_coopsharestransaction not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_coopsharestransaction_insert_permission_check_tg
|
||||
before insert on hs_office_coopsharestransaction
|
||||
for each row
|
||||
when ( not hasInsertPermission(NEW.membershipUuid, 'INSERT', 'hs_office_coopsharestransaction') )
|
||||
execute procedure hs_office_coopsharestransaction_insert_permission_missing_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopsharestransaction-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityViewFromProjection('hs_office_coopsharestransaction',
|
||||
$idName$
|
||||
reference
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopsharestransaction-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_coopsharestransaction',
|
||||
$orderBy$
|
||||
reference
|
||||
$orderBy$,
|
||||
$updates$
|
||||
comment = new.comment
|
||||
$updates$);
|
||||
--//
|
||||
|
@ -0,0 +1,96 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- TODO: These changesets are just for the external remote views to simulate the legacy tables.
|
||||
-- Once we don't need the external remote views anymore, create revert changesets.
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopshares-MIGRATION-mapping:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE hs_office_coopsharestransaction_legacy_id
|
||||
(
|
||||
uuid uuid NOT NULL REFERENCES hs_office_coopsharestransaction(uuid),
|
||||
member_share_id integer NOT NULL
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopshares-MIGRATION-sequence:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE SEQUENCE IF NOT EXISTS hs_office_coopsharestransaction_legacy_id_seq
|
||||
AS integer
|
||||
START 1000000000
|
||||
OWNED BY hs_office_coopsharestransaction_legacy_id.member_share_id;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopshares-MIGRATION-default:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
ALTER TABLE hs_office_coopsharestransaction_legacy_id
|
||||
ALTER COLUMN member_share_id
|
||||
SET DEFAULT nextVal('hs_office_coopsharestransaction_legacy_id_seq');
|
||||
|
||||
--/
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopshares-MIGRATION-insert:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CALL defineContext('schema-migration');
|
||||
INSERT INTO hs_office_coopsharestransaction_legacy_id(uuid, member_share_id)
|
||||
SELECT uuid, nextVal('hs_office_coopsharestransaction_legacy_id_seq') FROM hs_office_coopsharestransaction;
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopShares-MIGRATION-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
create or replace function insertCoopSharesLegacyIdMapping()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
if TG_OP <> 'INSERT' then
|
||||
raise exception 'invalid usage of trigger';
|
||||
end if;
|
||||
|
||||
INSERT INTO hs_office_coopsharestransaction_legacy_id VALUES
|
||||
(NEW.uuid, nextVal('hs_office_coopsharestransaction_legacy_id_seq'));
|
||||
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger createCoopSharesLegacyIdMapping
|
||||
after insert on hs_office_coopsharestransaction
|
||||
for each row
|
||||
execute procedure insertCoopSharesLegacyIdMapping();
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopShares-MIGRATION-delete-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
create or replace function deleteCoopSharesLegacyIdMapping()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
if TG_OP <> 'DELETE' then
|
||||
raise exception 'invalid usage of trigger';
|
||||
end if;
|
||||
|
||||
DELETE FROM hs_office_coopsharestransaction_legacy_id
|
||||
WHERE uuid = OLD.uuid;
|
||||
|
||||
return OLD;
|
||||
end; $$;
|
||||
|
||||
create trigger removeCoopSharesLegacyIdMapping
|
||||
before delete on hs_office_coopsharestransaction
|
||||
for each row
|
||||
execute procedure deleteCoopSharesLegacyIdMapping();
|
||||
--/
|
@ -0,0 +1,52 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopSharesTransaction-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates a single coopSharesTransaction test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficeCoopSharesTransactionTestData(
|
||||
givenPartnerNumber numeric,
|
||||
givenMemberNumberSuffix char(2)
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentTask varchar;
|
||||
membership hs_office_membership;
|
||||
begin
|
||||
currentTask = 'creating coopSharesTransaction test-data ' || givenPartnerNumber::text || givenMemberNumberSuffix;
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
call defineContext(currentTask);
|
||||
select m.uuid
|
||||
from hs_office_membership m
|
||||
join hs_office_partner p on p.uuid = m.partneruuid
|
||||
where p.partnerNumber = givenPartnerNumber
|
||||
and m.memberNumberSuffix = givenMemberNumberSuffix
|
||||
into membership;
|
||||
|
||||
raise notice 'creating test coopSharesTransaction: %', givenPartnerNumber::text || givenMemberNumberSuffix;
|
||||
insert
|
||||
into hs_office_coopsharestransaction(uuid, membershipuuid, transactiontype, valuedate, sharecount, reference, comment)
|
||||
values
|
||||
(uuid_generate_v4(), membership.uuid, 'SUBSCRIPTION', '2010-03-15', 4, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-1', 'initial subscription'),
|
||||
(uuid_generate_v4(), membership.uuid, 'CANCELLATION', '2021-09-01', -2, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-2', 'cancelling some'),
|
||||
(uuid_generate_v4(), membership.uuid, 'ADJUSTMENT', '2022-10-20', 2, 'ref '||givenPartnerNumber::text || givenMemberNumberSuffix||'-3', 'some adjustment');
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopSharesTransaction-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call createHsOfficeCoopSharesTransactionTestData(10001, '01');
|
||||
call createHsOfficeCoopSharesTransactionTestData(10002, '02');
|
||||
call createHsOfficeCoopSharesTransactionTestData(10003, '03');
|
||||
end;
|
||||
$$;
|
@ -0,0 +1,63 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassets-MAIN-TABLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE TYPE HsOfficeCoopAssetsTransactionType AS ENUM ('ADJUSTMENT',
|
||||
'DEPOSIT',
|
||||
'DISBURSAL',
|
||||
'TRANSFER',
|
||||
'ADOPTION',
|
||||
'CLEARING',
|
||||
'LOSS',
|
||||
'LIMITATION');
|
||||
|
||||
CREATE CAST (character varying as HsOfficeCoopAssetsTransactionType) WITH INOUT AS IMPLICIT;
|
||||
|
||||
create table if not exists hs_office_coopassetstransaction
|
||||
(
|
||||
uuid uuid unique references RbacObject (uuid) initially deferred,
|
||||
membershipUuid uuid not null references hs_office_membership(uuid),
|
||||
transactionType HsOfficeCoopAssetsTransactionType not null,
|
||||
valueDate date not null,
|
||||
assetValue money,
|
||||
reference varchar(48),
|
||||
comment varchar(512)
|
||||
);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassets-ASSET-VALUE-CONSTRAINT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create or replace function checkAssetsByMembershipUuid(forMembershipUuid UUID, newAssetValue money)
|
||||
returns boolean
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentAssetValue money;
|
||||
totalAssetValue money;
|
||||
begin
|
||||
select sum(cat.assetValue)
|
||||
from hs_office_coopassetstransaction cat
|
||||
where cat.membershipUuid = forMembershipUuid
|
||||
into currentAssetValue;
|
||||
totalAssetValue := currentAssetValue + newAssetValue;
|
||||
if totalAssetValue::numeric < 0 then
|
||||
raise exception '[400] coop assets transaction would result in a negative balance of assets';
|
||||
end if;
|
||||
return true;
|
||||
end; $$;
|
||||
|
||||
alter table hs_office_coopassetstransaction
|
||||
add constraint hs_office_coopassets_positive
|
||||
check ( checkAssetsByMembershipUuid(membershipUuid, assetValue) );
|
||||
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassets-MAIN-TABLE-JOURNAL:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call create_journal('hs_office_coopassetstransaction');
|
||||
--//
|
@ -0,0 +1,120 @@
|
||||
### rbac coopAssetsTransaction
|
||||
|
||||
This code generated was by RbacViewMermaidFlowchartGenerator, do not amend manually.
|
||||
|
||||
```mermaid
|
||||
%%{init:{'flowchart':{'htmlLabels':false}}}%%
|
||||
flowchart TB
|
||||
|
||||
subgraph membership.partnerRel.holderPerson["`**membership.partnerRel.holderPerson**`"]
|
||||
direction TB
|
||||
style membership.partnerRel.holderPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph membership.partnerRel.holderPerson:roles[ ]
|
||||
style membership.partnerRel.holderPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:membership.partnerRel.holderPerson:OWNER[[membership.partnerRel.holderPerson:OWNER]]
|
||||
role:membership.partnerRel.holderPerson:ADMIN[[membership.partnerRel.holderPerson:ADMIN]]
|
||||
role:membership.partnerRel.holderPerson:REFERRER[[membership.partnerRel.holderPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph membership.partnerRel.anchorPerson["`**membership.partnerRel.anchorPerson**`"]
|
||||
direction TB
|
||||
style membership.partnerRel.anchorPerson fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph membership.partnerRel.anchorPerson:roles[ ]
|
||||
style membership.partnerRel.anchorPerson:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:membership.partnerRel.anchorPerson:OWNER[[membership.partnerRel.anchorPerson:OWNER]]
|
||||
role:membership.partnerRel.anchorPerson:ADMIN[[membership.partnerRel.anchorPerson:ADMIN]]
|
||||
role:membership.partnerRel.anchorPerson:REFERRER[[membership.partnerRel.anchorPerson:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph coopAssetsTransaction["`**coopAssetsTransaction**`"]
|
||||
direction TB
|
||||
style coopAssetsTransaction fill:#dd4901,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph coopAssetsTransaction:permissions[ ]
|
||||
style coopAssetsTransaction:permissions fill:#dd4901,stroke:white
|
||||
|
||||
perm:coopAssetsTransaction:INSERT{{coopAssetsTransaction:INSERT}}
|
||||
perm:coopAssetsTransaction:UPDATE{{coopAssetsTransaction:UPDATE}}
|
||||
perm:coopAssetsTransaction:SELECT{{coopAssetsTransaction:SELECT}}
|
||||
end
|
||||
end
|
||||
|
||||
subgraph membership["`**membership**`"]
|
||||
direction TB
|
||||
style membership fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph membership:roles[ ]
|
||||
style membership:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:membership:OWNER[[membership:OWNER]]
|
||||
role:membership:ADMIN[[membership:ADMIN]]
|
||||
role:membership:AGENT[[membership:AGENT]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph membership.partnerRel["`**membership.partnerRel**`"]
|
||||
direction TB
|
||||
style membership.partnerRel fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph membership.partnerRel:roles[ ]
|
||||
style membership.partnerRel:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:membership.partnerRel:OWNER[[membership.partnerRel:OWNER]]
|
||||
role:membership.partnerRel:ADMIN[[membership.partnerRel:ADMIN]]
|
||||
role:membership.partnerRel:AGENT[[membership.partnerRel:AGENT]]
|
||||
role:membership.partnerRel:TENANT[[membership.partnerRel:TENANT]]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph membership.partnerRel.contact["`**membership.partnerRel.contact**`"]
|
||||
direction TB
|
||||
style membership.partnerRel.contact fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||
|
||||
subgraph membership.partnerRel.contact:roles[ ]
|
||||
style membership.partnerRel.contact:roles fill:#99bcdb,stroke:white
|
||||
|
||||
role:membership.partnerRel.contact:OWNER[[membership.partnerRel.contact:OWNER]]
|
||||
role:membership.partnerRel.contact:ADMIN[[membership.partnerRel.contact:ADMIN]]
|
||||
role:membership.partnerRel.contact:REFERRER[[membership.partnerRel.contact:REFERRER]]
|
||||
end
|
||||
end
|
||||
|
||||
%% granting roles to roles
|
||||
role:global:ADMIN -.-> role:membership.partnerRel.anchorPerson:OWNER
|
||||
role:membership.partnerRel.anchorPerson:OWNER -.-> role:membership.partnerRel.anchorPerson:ADMIN
|
||||
role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel.anchorPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:membership.partnerRel.holderPerson:OWNER
|
||||
role:membership.partnerRel.holderPerson:OWNER -.-> role:membership.partnerRel.holderPerson:ADMIN
|
||||
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel.holderPerson:REFERRER
|
||||
role:global:ADMIN -.-> role:membership.partnerRel.contact:OWNER
|
||||
role:membership.partnerRel.contact:OWNER -.-> role:membership.partnerRel.contact:ADMIN
|
||||
role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel.contact:REFERRER
|
||||
role:global:ADMIN -.-> role:membership.partnerRel:OWNER
|
||||
role:membership.partnerRel:OWNER -.-> role:membership.partnerRel:ADMIN
|
||||
role:membership.partnerRel.anchorPerson:ADMIN -.-> role:membership.partnerRel:ADMIN
|
||||
role:membership.partnerRel:ADMIN -.-> role:membership.partnerRel:AGENT
|
||||
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:AGENT
|
||||
role:membership.partnerRel:AGENT -.-> role:membership.partnerRel:TENANT
|
||||
role:membership.partnerRel.holderPerson:ADMIN -.-> role:membership.partnerRel:TENANT
|
||||
role:membership.partnerRel.contact:ADMIN -.-> role:membership.partnerRel:TENANT
|
||||
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.anchorPerson:REFERRER
|
||||
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.holderPerson:REFERRER
|
||||
role:membership.partnerRel:TENANT -.-> role:membership.partnerRel.contact:REFERRER
|
||||
role:membership:OWNER -.-> role:membership:ADMIN
|
||||
role:membership.partnerRel:ADMIN -.-> role:membership:ADMIN
|
||||
role:membership:ADMIN -.-> role:membership:AGENT
|
||||
role:membership.partnerRel:AGENT -.-> role:membership:AGENT
|
||||
role:membership:AGENT -.-> role:membership.partnerRel:TENANT
|
||||
|
||||
%% granting permissions to roles
|
||||
role:membership:ADMIN ==> perm:coopAssetsTransaction:INSERT
|
||||
role:membership:ADMIN ==> perm:coopAssetsTransaction:UPDATE
|
||||
role:membership:AGENT ==> perm:coopAssetsTransaction:SELECT
|
||||
|
||||
```
|
@ -0,0 +1,151 @@
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by RbacViewPostgresGenerator, do not amend manually.
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassetstransaction-rbac-OBJECT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('hs_office_coopassetstransaction');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassetstransaction-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('hsOfficeCoopAssetsTransaction', 'hs_office_coopassetstransaction');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassetstransaction-rbac-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficeCoopAssetsTransaction(
|
||||
NEW hs_office_coopassetstransaction
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
newMembership hs_office_membership;
|
||||
|
||||
begin
|
||||
call enterTriggerForObjectUuid(NEW.uuid);
|
||||
|
||||
SELECT * FROM hs_office_membership WHERE uuid = NEW.membershipUuid INTO newMembership;
|
||||
assert newMembership.uuid is not null, format('newMembership must not be null for NEW.membershipUuid = %s', NEW.membershipUuid);
|
||||
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeMembershipAGENT(newMembership));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeMembershipADMIN(newMembership));
|
||||
|
||||
call leaveTriggerForObjectUuid(NEW.uuid);
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_coopassetstransaction row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficeCoopAssetsTransaction_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficeCoopAssetsTransaction(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForHsOfficeCoopAssetsTransaction_tg
|
||||
after insert on hs_office_coopassetstransaction
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficeCoopAssetsTransaction_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassetstransaction-rbac-INSERT:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_coopassetstransaction permissions for the related hs_office_membership rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row hs_office_membership;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_coopassetstransaction permissions for the related hs_office_membership rows');
|
||||
|
||||
FOR row IN SELECT * FROM hs_office_membership
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_coopassetstransaction'),
|
||||
hsOfficeMembershipADMIN(row));
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_coopassetstransaction INSERT permission to specified role of new hs_office_membership rows.
|
||||
*/
|
||||
create or replace function hs_office_coopassetstransaction_hs_office_membership_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call grantPermissionToRole(
|
||||
createPermission(NEW.uuid, 'INSERT', 'hs_office_coopassetstransaction'),
|
||||
hsOfficeMembershipADMIN(NEW));
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_hs_office_coopassetstransaction_hs_office_membership_insert_tg
|
||||
after insert on hs_office_membership
|
||||
for each row
|
||||
execute procedure hs_office_coopassetstransaction_hs_office_membership_insert_tf();
|
||||
|
||||
/**
|
||||
Checks if the user or assumed roles are allowed to insert a row to hs_office_coopassetstransaction,
|
||||
where the check is performed by a direct role.
|
||||
|
||||
A direct role is a role depending on a foreign key directly available in the NEW row.
|
||||
*/
|
||||
create or replace function hs_office_coopassetstransaction_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise exception '[403] insert into hs_office_coopassetstransaction not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_coopassetstransaction_insert_permission_check_tg
|
||||
before insert on hs_office_coopassetstransaction
|
||||
for each row
|
||||
when ( not hasInsertPermission(NEW.membershipUuid, 'INSERT', 'hs_office_coopassetstransaction') )
|
||||
execute procedure hs_office_coopassetstransaction_insert_permission_missing_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassetstransaction-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call generateRbacIdentityViewFromProjection('hs_office_coopassetstransaction',
|
||||
$idName$
|
||||
reference
|
||||
$idName$);
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassetstransaction-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('hs_office_coopassetstransaction',
|
||||
$orderBy$
|
||||
reference
|
||||
$orderBy$,
|
||||
$updates$
|
||||
comment = new.comment
|
||||
$updates$);
|
||||
--//
|
||||
|
@ -0,0 +1,96 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
-- TODO: These changesets are just for the external remote views to simulate the legacy tables.
|
||||
-- Once we don't need the external remote views anymore, create revert changesets.
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassets-MIGRATION-mapping:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE hs_office_coopassetstransaction_legacy_id
|
||||
(
|
||||
uuid uuid NOT NULL REFERENCES hs_office_coopassetstransaction(uuid),
|
||||
member_asset_id integer NOT NULL
|
||||
);
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassets-MIGRATION-sequence:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CREATE SEQUENCE IF NOT EXISTS hs_office_coopassetstransaction_legacy_id_seq
|
||||
AS integer
|
||||
START 1000000000
|
||||
OWNED BY hs_office_coopassetstransaction_legacy_id.member_asset_id;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassets-MIGRATION-default:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
ALTER TABLE hs_office_coopassetstransaction_legacy_id
|
||||
ALTER COLUMN member_asset_id
|
||||
SET DEFAULT nextVal('hs_office_coopassetstransaction_legacy_id_seq');
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopassets-MIGRATION-insert:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
CALL defineContext('schema-migration');
|
||||
INSERT INTO hs_office_coopassetstransaction_legacy_id(uuid, member_asset_id)
|
||||
SELECT uuid, nextVal('hs_office_coopassetstransaction_legacy_id_seq') FROM hs_office_coopassetstransaction;
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopAssets-MIGRATION-insert-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
create or replace function insertCoopAssetsLegacyIdMapping()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
if TG_OP <> 'INSERT' then
|
||||
raise exception 'invalid usage of trigger';
|
||||
end if;
|
||||
|
||||
INSERT INTO hs_office_coopassetstransaction_legacy_id VALUES
|
||||
(NEW.uuid, nextVal('hs_office_coopassetstransaction_legacy_id_seq'));
|
||||
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger createCoopAssetsLegacyIdMapping
|
||||
after insert on hs_office_coopassetstransaction
|
||||
for each row
|
||||
execute procedure insertCoopAssetsLegacyIdMapping();
|
||||
--/
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopAssets-MIGRATION-delete-trigger:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
create or replace function deleteCoopAssetsLegacyIdMapping()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
if TG_OP <> 'DELETE' then
|
||||
raise exception 'invalid usage of trigger';
|
||||
end if;
|
||||
|
||||
DELETE FROM hs_office_coopassetstransaction_legacy_id
|
||||
WHERE uuid = OLD.uuid;
|
||||
|
||||
return OLD;
|
||||
end; $$;
|
||||
|
||||
create trigger removeCoopAssetsLegacyIdMapping
|
||||
before delete on hs_office_coopassetstransaction
|
||||
for each row
|
||||
execute procedure deleteCoopAssetsLegacyIdMapping();
|
||||
--/
|
@ -0,0 +1,52 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopAssetsTransaction-TEST-DATA-GENERATOR:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates a single coopAssetsTransaction test record.
|
||||
*/
|
||||
create or replace procedure createHsOfficeCoopAssetsTransactionTestData(
|
||||
givenPartnerNumber numeric,
|
||||
givenMemberNumberSuffix char(2)
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentTask varchar;
|
||||
membership hs_office_membership;
|
||||
begin
|
||||
currentTask = 'creating coopAssetsTransaction test-data ' || givenPartnerNumber || givenMemberNumberSuffix;
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
call defineContext(currentTask);
|
||||
select m.uuid
|
||||
from hs_office_membership m
|
||||
join hs_office_partner p on p.uuid = m.partneruuid
|
||||
where p.partnerNumber = givenPartnerNumber
|
||||
and m.memberNumberSuffix = givenMemberNumberSuffix
|
||||
into membership;
|
||||
|
||||
raise notice 'creating test coopAssetsTransaction: %', givenPartnerNumber || givenMemberNumberSuffix;
|
||||
insert
|
||||
into hs_office_coopassetstransaction(uuid, membershipuuid, transactiontype, valuedate, assetvalue, reference, comment)
|
||||
values
|
||||
(uuid_generate_v4(), membership.uuid, 'DEPOSIT', '2010-03-15', 320.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-1', 'initial deposit'),
|
||||
(uuid_generate_v4(), membership.uuid, 'DISBURSAL', '2021-09-01', -128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-2', 'partial disbursal'),
|
||||
(uuid_generate_v4(), membership.uuid, 'ADJUSTMENT', '2022-10-20', 128.00, 'ref '||givenPartnerNumber || givenMemberNumberSuffix||'-3', 'some adjustment');
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset hs-office-coopAssetsTransaction-TEST-DATA-GENERATION:1 –context=dev,tc endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
do language plpgsql $$
|
||||
begin
|
||||
call createHsOfficeCoopAssetsTransactionTestData(10001, '01');
|
||||
call createHsOfficeCoopAssetsTransactionTestData(10002, '02');
|
||||
call createHsOfficeCoopAssetsTransactionTestData(10003, '03');
|
||||
end;
|
||||
$$;
|
Reference in New Issue
Block a user