1
0

add HsOfficeBankAccount*

This commit is contained in:
Michael Hoennig
2022-10-04 19:09:37 +02:00
parent c3195662dd
commit a93143ff00
19 changed files with 1301 additions and 4 deletions

View File

@ -20,5 +20,7 @@ map:
null: org.openapitools.jackson.nullable.JsonNullable
/api/hs/office/relationships/{relationshipUUID}:
null: org.openapitools.jackson.nullable.JsonNullable
/api/hs/office/bankaccounts/{bankAccountUUID}:
null: org.openapitools.jackson.nullable.JsonNullable
/api/hs/office/debitors/{debitorUUID}:
null: org.openapitools.jackson.nullable.JsonNullable

View File

@ -0,0 +1,31 @@
components:
schemas:
HsOfficeBankAccount:
type: object
properties:
uuid:
type: string
format: uuid
holder:
type: string
iban:
type: string
bic:
type: string
HsOfficeBankAccountInsert:
type: object
properties:
holder:
type: string
iban:
type: string
bic:
type: string
required:
- holder
- iban
- bic

View File

@ -0,0 +1,51 @@
get:
tags:
- hs-office-bank-accounts
description: 'Fetch a single bank account by its uuid, if visible for the current subject.'
operationId: getBankAccountByUuid
parameters:
- $ref: './auth.yaml#/components/parameters/currentUser'
- $ref: './auth.yaml#/components/parameters/assumedRoles'
- name: bankAccountUUID
in: path
required: true
schema:
type: string
format: uuid
description: UUID of the bankaccount to fetch.
responses:
"200":
description: OK
content:
'application/json':
schema:
$ref: './hs-office-bankaccount-schemas.yaml#/components/schemas/HsOfficeBankAccount'
"401":
$ref: './error-responses.yaml#/components/responses/Unauthorized'
"403":
$ref: './error-responses.yaml#/components/responses/Forbidden'
delete:
tags:
- hs-office-bank-accounts
description: 'Delete a single bank account by its uuid, if permitted for the current subject.'
operationId: deleteBankAccountByUuid
parameters:
- $ref: './auth.yaml#/components/parameters/currentUser'
- $ref: './auth.yaml#/components/parameters/assumedRoles'
- name: bankAccountUUID
in: path
required: true
schema:
type: string
format: uuid
description: UUID of the bank account to delete.
responses:
"204":
description: No Content
"401":
$ref: './error-responses.yaml#/components/responses/Unauthorized'
"403":
$ref: './error-responses.yaml#/components/responses/Forbidden'
"404":
$ref: './error-responses.yaml#/components/responses/NotFound'

View File

@ -0,0 +1,56 @@
get:
summary: Returns a list of (optionally filtered) bankaccounts.
description: Returns the list of (optionally filtered) bankaccounts which are visible to the current user or any of it's assumed roles.
tags:
- hs-office-bank-accounts
operationId: listBankAccounts
parameters:
- $ref: './auth.yaml#/components/parameters/currentUser'
- $ref: './auth.yaml#/components/parameters/assumedRoles'
- name: holder
in: query
required: false
schema:
type: string
description: Prefix of holder to filter the results.
responses:
"200":
description: OK
content:
'application/json':
schema:
type: array
items:
$ref: './hs-office-bankaccount-schemas.yaml#/components/schemas/HsOfficeBankAccount'
"401":
$ref: './error-responses.yaml#/components/responses/Unauthorized'
"403":
$ref: './error-responses.yaml#/components/responses/Forbidden'
post:
summary: Adds a new bank account.
tags:
- hs-office-bank-accounts
operationId: addBankAccount
parameters:
- $ref: './auth.yaml#/components/parameters/currentUser'
- $ref: './auth.yaml#/components/parameters/assumedRoles'
requestBody:
content:
'application/json':
schema:
$ref: './hs-office-bankaccount-schemas.yaml#/components/schemas/HsOfficeBankAccountInsert'
required: true
responses:
"201":
description: Created
content:
'application/json':
schema:
$ref: './hs-office-bankaccount-schemas.yaml#/components/schemas/HsOfficeBankAccount'
"401":
$ref: './error-responses.yaml#/components/responses/Unauthorized'
"403":
$ref: './error-responses.yaml#/components/responses/Forbidden'
"409":
$ref: './error-responses.yaml#/components/responses/Conflict'

View File

@ -44,6 +44,15 @@ paths:
$ref: "./hs-office-relationships-with-uuid.yaml"
# BankAccounts
/api/hs/office/bankaccounts:
$ref: "./hs-office-bankaccounts.yaml"
/api/hs/office/bankaccounts/{bankAccountUUID}:
$ref: "./hs-office-bankaccounts-with-uuid.yaml"
# Debitors
/api/hs/office/debitors:

View File

@ -0,0 +1,13 @@
-- ============================================================================
--changeset hs-office-bankaccount-MAIN-TABLE:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
create table hs_office_bankaccount
(
uuid uuid unique references RbacObject (uuid) initially deferred,
holder varchar(27) not null,
iban varchar(34) not null,
bic varchar(11) not null
);
--//

View File

@ -0,0 +1,138 @@
--liquibase formatted sql
-- ============================================================================
--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-ROLES-CREATION:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Creates the roles and their assignments for a new bankaccount for the AFTER INSERT TRIGGER.
*/
create or replace function createRbacRolesForHsOfficeBankAccount()
returns trigger
language plpgsql
strict as $$
declare
ownerRole uuid;
begin
if TG_OP <> 'INSERT' then
raise exception 'invalid usage of TRIGGER AFTER INSERT';
end if;
-- the owner role with full access for the creator assigned to the current user
ownerRole := createRole(
hsOfficeBankAccountOwner(NEW),
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['delete']),
beneathRole(globalAdmin()),
withoutSubRoles(),
withUser(currentUser()), -- TODO.spec: Who is owner of a new bankaccount?
grantedByRole(globalAdmin())
);
-- TODO.spec: assumption can not be updated
-- Where bankaccounts can be created, assigned, re-assigned and deleted, they cannot be updated.
-- Thus SQL UPDATE and 'edit' permission are being implemented.
-- the tenant role for those related users who can view the data
perform createRole(
hsOfficeBankAccountTenant(NEW),
grantingPermissions(forObjectUuid => NEW.uuid, permitOps => array ['view']),
beneathRole(ownerRole)
);
return NEW;
end; $$;
/*
An AFTER INSERT TRIGGER which creates the role structure for a new customer.
*/
create trigger createRbacRolesForHsOfficeBankAccount_Trigger
after insert
on hs_office_bankaccount
for each row
execute procedure createRbacRolesForHsOfficeBankAccount();
--//
-- ============================================================================
--changeset hs-office-bankaccount-rbac-IDENTITY-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call generateRbacIdentityView('hs_office_bankaccount', $idName$
target.holder
$idName$);
--//
-- ============================================================================
--changeset hs-office-bankaccount-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
call generateRbacRestrictedView('hs_office_bankaccount', 'target.holder',
$updates$
holder = new.holder,
iban = new.iban,
bic = new.bic
$updates$);
--/
-- ============================================================================
--changeset hs-office-bankaccount-rbac-NEW-BANKACCOUNT:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Creates a global permission for new-bankaccount and assigns it to the hostsharing admins role.
*/
do language plpgsql $$
declare
addCustomerPermissions uuid[];
globalObjectUuid uuid;
globalAdminRoleUuid uuid ;
begin
call defineContext('granting global new-bankaccount permission to global admin role', null, null, null);
globalAdminRoleUuid := findRoleId(globalAdmin());
globalObjectUuid := (select uuid from global);
addCustomerPermissions := createPermissions(globalObjectUuid, array ['new-bankaccount']);
call grantPermissionsToRole(globalAdminRoleUuid, addCustomerPermissions);
end;
$$;
/**
Used by the trigger to prevent the add-customer to current user respectively assumed roles.
*/
create or replace function addHsOfficeBankAccountNotAllowedForCurrentSubjects()
returns trigger
language PLPGSQL
as $$
begin
raise exception '[403] new-bankaccount not permitted for %',
array_to_string(currentSubjects(), ';', 'null');
end; $$;
/**
Checks if the user or assumed roles are allowed to create a new customer.
*/
create trigger hs_office_bankaccount_insert_trigger
before insert
on hs_office_bankaccount
for each row
-- TODO.spec: who is allowed to create new bankaccounts
when ( not hasAssumedRole() )
execute procedure addHsOfficeBankAccountNotAllowedForCurrentSubjects();
--//

View File

@ -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 RBAC test bankaccount ' || 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 e.G.', 'DE02200505501015871393', 'HASPDEHH');
call createHsOfficeBankAccountTestData('Mel Bessler', 'DE02100100100006820101', 'PBNKDEFF');
call createHsOfficeBankAccountTestData('Anita Bessler', 'DE02300606010002474689', 'DAAEDEDD');
call createHsOfficeBankAccountTestData('Paul Winkler', 'DE02600501010002034304', 'SOLADEST600');
end;
$$;

View File

@ -12,7 +12,8 @@ create table hs_office_debitor
billingContactUuid uuid not null references hs_office_contact(uuid),
vatId varchar(24), -- TODO.spec: here or in person?
vatCountryCode varchar(2),
vatBusiness boolean not null -- TODO.spec: more of such?
-- TODO.impl: SEPA-mandate + bank account
vatBusiness boolean not null, -- TODO.spec: more of such?
bankAccountUuid uuid references hs_office_bankaccount(uuid)
-- TODO.impl: SEPA-mandate
);
--//

View File

@ -1,10 +1,28 @@
### hs_office_debitor RBAC Roles
```mermaid
graph TD;
flowchart TB;
subgraph bankaccount;
direction TB;
%% oversimplified version for now
%%
%% Beware: role:debitor.tenant should NOT be granted role:bankaccount.tenent
%% because otherwise, later in the development,
%% e.g. package admins could see the debitors bank account,
%% except if we do NOT use the debitor in the hosting super module.
%% role:bankaccount.owner
role:bankaccount.owner --> perm:bankaccount.*;
end;
subgraph debitor[" "];
direction TB;
%% role:debitor.owner
role:debitor.owner --> perm:debitor.*;
role:global.admin --> role:debitor.owner;
role:debitor.owner --> role:bankaccount.owner;
%% role:debitor.admin
role:debitor.admin --> perm:debitor.edit;
@ -21,4 +39,12 @@ graph TD;
role:debitor.tenant --> role:partner.tenant;
role:debitor.tenant --> role:person.tenant;
role:debitor.tenant --> role:contact.tenant;
end;
subgraph global;
direction TB;
role:global.admin --> role:debitor.owner;
end;
```

View File

@ -71,6 +71,12 @@ databaseChangeLog:
file: db/changelog/233-hs-office-relationship-rbac.sql
- include:
file: db/changelog/238-hs-office-relationship-test-data.sql
- include:
file: db/changelog/240-hs-office-bankaccount.sql
- include:
file: db/changelog/243-hs-office-bankaccount-rbac.sql
- include:
file: db/changelog/248-hs-office-bankaccount-test-data.sql
- include:
file: db/changelog/270-hs-office-debitor.sql
- include: