fix insert grants + assertions and improve generated formatting
This commit is contained in:
parent
3872f5dc19
commit
1f59462f1b
@ -138,7 +138,7 @@ public class HsOfficeMembershipEntity implements HasUuid, Stringifyable {
|
||||
WHERE partner.uuid = ${REF}.partnerUuid
|
||||
"""),
|
||||
NOT_NULL)
|
||||
.toRole("partnerRel", ADMIN).grantPermission(INSERT)
|
||||
.toRole("global", ADMIN).grantPermission(INSERT)
|
||||
|
||||
.createRole(OWNER, (with) -> {
|
||||
with.owningUser(CREATOR);
|
||||
|
@ -47,16 +47,14 @@ public class InsertTriggerGenerator {
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row ${rawSuperTableName};
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO ${rawSubTableName} permissions for the related ${rawSuperTableName} rows');
|
||||
|
||||
FOR row IN SELECT * FROM ${rawSuperTableName}
|
||||
LOOP
|
||||
roleUuid := findRoleId(${rawSuperRoleDescriptor});
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', '${rawSubTableName}');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', '${rawSubTableName}'),
|
||||
${rawSuperRoleDescriptor});
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -63,6 +63,7 @@ create or replace view rbacgrants_ev as
|
||||
x.grantedByRoleUuid,
|
||||
x.ascendantUuid as ascendantUuid,
|
||||
x.descendantUuid as descendantUuid,
|
||||
x.op as permOp, x.optablename as permOpTableName,
|
||||
x.assumed
|
||||
from (
|
||||
select g.uuid as grantUuid,
|
||||
@ -74,12 +75,16 @@ create or replace view rbacgrants_ev as
|
||||
'role ' || aro.objectTable || '#' || findIdNameByObjectUuid(aro.objectTable, aro.uuid) || '.' || ar.roletype
|
||||
) as ascendingIdName,
|
||||
aro.objectTable, aro.uuid,
|
||||
|
||||
coalesce(
|
||||
'role ' || dro.objectTable || '#' || findIdNameByObjectUuid(dro.objectTable, dro.uuid) || '.' || dr.roletype,
|
||||
'perm ' || dp.op || ' on ' || dpo.objecttable || '#' || findIdNameByObjectUuid(dpo.objectTable, dpo.uuid)
|
||||
( case
|
||||
when dro is not null
|
||||
then ('role ' || dro.objectTable || '#' || findIdNameByObjectUuid(dro.objectTable, dro.uuid) || '.' || dr.roletype)
|
||||
when dp.op = 'INSERT'
|
||||
then 'perm ' || dp.op || ' into ' || dp.opTableName || ' with ' || dpo.objecttable || '#' || findIdNameByObjectUuid(dpo.objectTable, dpo.uuid)
|
||||
else 'perm ' || dp.op || ' on ' || dpo.objecttable || '#' || findIdNameByObjectUuid(dpo.objectTable, dpo.uuid)
|
||||
end
|
||||
) as descendingIdName,
|
||||
dro.objectTable, dro.uuid
|
||||
dro.objectTable, dro.uuid,
|
||||
dp.op, dp.optablename
|
||||
from rbacgrants as g
|
||||
|
||||
left outer join rbacrole as ar on ar.uuid = g.ascendantUuid
|
||||
|
@ -86,16 +86,14 @@ execute procedure insertTriggerForTestCustomer_tf();
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO test_customer permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
roleUuid := findRoleId(globalAdmin());
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'test_customer');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'test_customer'),
|
||||
globalAdmin());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -151,16 +151,14 @@ execute procedure updateTriggerForTestPackage_tf();
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row test_customer;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO test_package permissions for the related test_customer rows');
|
||||
|
||||
FOR row IN SELECT * FROM test_customer
|
||||
LOOP
|
||||
roleUuid := findRoleId(testCustomerAdmin(row));
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'test_package');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'test_package'),
|
||||
testCustomerAdmin(row));
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -150,16 +150,14 @@ execute procedure updateTriggerForTestDomain_tf();
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row test_package;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO test_domain permissions for the related test_package rows');
|
||||
|
||||
FOR row IN SELECT * FROM test_package
|
||||
LOOP
|
||||
roleUuid := findRoleId(testPackageAdmin(row));
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'test_domain');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'test_domain'),
|
||||
testPackageAdmin(row));
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -86,16 +86,14 @@ execute procedure insertTriggerForHsOfficeContact_tf();
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_contact permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
roleUuid := findRoleId(globalGuest());
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_contact');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_contact'),
|
||||
globalGuest());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -86,16 +86,14 @@ execute procedure insertTriggerForHsOfficePerson_tf();
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_person permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
roleUuid := findRoleId(globalGuest());
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_person');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_person'),
|
||||
globalGuest());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -192,16 +192,14 @@ execute procedure updateTriggerForHsOfficeRelation_tf();
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row hs_office_person;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
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
|
||||
roleUuid := findRoleId(hsOfficePersonAdmin(row));
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_relation');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_relation'),
|
||||
hsOfficePersonAdmin(row));
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -163,16 +163,14 @@ execute procedure updateTriggerForHsOfficePartner_tf();
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_partner permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
roleUuid := findRoleId(globalAdmin());
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_partner');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_partner'),
|
||||
globalAdmin());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -67,16 +67,14 @@ execute procedure insertTriggerForHsOfficePartnerDetails_tf();
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_partner_details permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
roleUuid := findRoleId(globalAdmin());
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_partner_details');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_partner_details'),
|
||||
globalAdmin());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -86,16 +86,14 @@ execute procedure insertTriggerForHsOfficeBankAccount_tf();
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_bankaccount permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
roleUuid := findRoleId(globalGuest());
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_bankaccount');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_bankaccount'),
|
||||
globalGuest());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -111,16 +111,14 @@ execute procedure insertTriggerForHsOfficeSepaMandate_tf();
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row hs_office_relation;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
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
|
||||
roleUuid := findRoleId(hsOfficeRelationAdmin(row));
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_sepamandate');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_sepamandate'),
|
||||
hsOfficeRelationAdmin(row));
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -136,16 +136,14 @@ execute procedure updateTriggerForHsOfficeDebitor_tf();
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row global;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_debitor permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
roleUuid := findRoleId(globalAdmin());
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_debitor');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_debitor'),
|
||||
globalAdmin());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
@ -151,7 +151,7 @@ role:membership:admin ==> role:membership:referrer
|
||||
role:membership:referrer ==> role:partnerRel:tenant
|
||||
|
||||
%% granting permissions to roles
|
||||
role:partnerRel:admin ==> perm:membership:INSERT
|
||||
role:global:admin ==> perm:membership:INSERT
|
||||
role:membership:owner ==> perm:membership:DELETE
|
||||
role:membership:admin ==> perm:membership:UPDATE
|
||||
role:membership:referrer ==> perm:membership:SELECT
|
||||
|
@ -93,79 +93,60 @@ execute procedure insertTriggerForHsOfficeMembership_tf();
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates INSERT INTO hs_office_membership permissions for the related hs_office_relation rows.
|
||||
Creates INSERT INTO hs_office_membership permissions for the related global rows.
|
||||
*/
|
||||
do language plpgsql $$
|
||||
declare
|
||||
row hs_office_relation;
|
||||
permissionUuid uuid;
|
||||
roleUuid uuid;
|
||||
row global;
|
||||
begin
|
||||
call defineContext('create INSERT INTO hs_office_membership permissions for the related hs_office_relation rows');
|
||||
call defineContext('create INSERT INTO hs_office_membership permissions for the related global rows');
|
||||
|
||||
FOR row IN SELECT * FROM hs_office_relation
|
||||
FOR row IN SELECT * FROM global
|
||||
LOOP
|
||||
roleUuid := findRoleId(hsOfficeRelationAdmin(row));
|
||||
permissionUuid := createPermission(row.uuid, 'INSERT', 'hs_office_membership');
|
||||
call grantPermissionToRole(permissionUuid, roleUuid);
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', 'hs_office_membership'),
|
||||
globalAdmin());
|
||||
END LOOP;
|
||||
END;
|
||||
$$;
|
||||
|
||||
/**
|
||||
Adds hs_office_membership INSERT permission to specified role of new hs_office_relation rows.
|
||||
Adds hs_office_membership INSERT permission to specified role of new global rows.
|
||||
*/
|
||||
create or replace function hs_office_membership_hs_office_relation_insert_tf()
|
||||
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'),
|
||||
hsOfficeRelationAdmin(NEW));
|
||||
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_hs_office_relation_insert_tg
|
||||
after insert on hs_office_relation
|
||||
create trigger z_hs_office_membership_global_insert_tg
|
||||
after insert on global
|
||||
for each row
|
||||
execute procedure hs_office_membership_hs_office_relation_insert_tf();
|
||||
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 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.
|
||||
where only global-admin has that permission.
|
||||
*/
|
||||
create or replace function hs_office_membership_insert_permission_check_tf()
|
||||
create or replace function hs_office_membership_insert_permission_missing_tf()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
|
||||
declare
|
||||
superRoleObjectUuid uuid;
|
||||
|
||||
begin
|
||||
superRoleObjectUuid := (SELECT partnerRel.uuid
|
||||
FROM hs_office_partner AS partner
|
||||
JOIN hs_office_relation AS partnerRel ON partnerRel.uuid = partner.partnerRelUuid
|
||||
WHERE partner.uuid = NEW.partnerUuid
|
||||
);
|
||||
assert superRoleObjectUuid is not null, 'superRoleObjectUuid must not be null';
|
||||
|
||||
if ( not hasInsertPermission(superRoleObjectUuid, 'INSERT', 'hs_office_membership') ) then
|
||||
raise exception
|
||||
'[403] insert into hs_office_membership not allowed for current subjects % (%)',
|
||||
raise exception '[403] insert into hs_office_membership not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
end if;
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_membership_insert_permission_check_tg
|
||||
before insert on hs_office_membership
|
||||
for each row
|
||||
execute procedure hs_office_membership_insert_permission_check_tf();
|
||||
when ( not isGlobalAdmin() )
|
||||
execute procedure hs_office_membership_insert_permission_missing_tf();
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
|
@ -179,8 +179,7 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
.map(s -> s.replace("hs_office_", ""))
|
||||
.containsExactlyInAnyOrder(Array.fromFormatted(
|
||||
initialGrantNames,
|
||||
// FIXME: the next line is completely wrong, the format as well that it exists
|
||||
"{ grant perm INSERT on relation#FirstGmbH-with-DEBITOR-FourtheG to role relation#FirstGmbH-with-DEBITOR-FourtheG.admin by system and assume }",
|
||||
"{ grant perm INSERT into sepamandate with relation#FirstGmbH-with-DEBITOR-FourtheG to role relation#FirstGmbH-with-DEBITOR-FourtheG.admin by system and assume }",
|
||||
|
||||
// owner
|
||||
"{ grant perm DELETE on debitor#D-1000122 to role relation#FirstGmbH-with-DEBITOR-FourtheG.owner by system and assume }",
|
||||
|
@ -142,8 +142,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
.map(s -> s.replace("hs_office_", ""))
|
||||
.containsExactlyInAnyOrder(distinct(fromFormatted(
|
||||
initialGrantNames,
|
||||
// FIXME: this entry is wrong in existance and format
|
||||
"{ grant perm INSERT on relation#HostsharingeG-with-PARTNER-EBess to role relation#HostsharingeG-with-PARTNER-EBess.admin by system and assume }",
|
||||
"{ grant perm INSERT into sepamandate with relation#HostsharingeG-with-PARTNER-EBess to role relation#HostsharingeG-with-PARTNER-EBess.admin by system and assume }",
|
||||
|
||||
// permissions on partner
|
||||
"{ grant perm DELETE on partner#P-20032 to role relation#HostsharingeG-with-PARTNER-EBess.admin by system and assume }",
|
||||
|
@ -94,9 +94,9 @@ class HsOfficePersonRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
||||
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll());
|
||||
|
||||
// when
|
||||
attempt(em, () -> toCleanup(personRepo.save(
|
||||
hsOfficePerson("another new person")))
|
||||
).assumeSuccessful();
|
||||
attempt(em, () -> toCleanup(
|
||||
personRepo.save(hsOfficePerson("another new person"))
|
||||
)).assumeSuccessful();
|
||||
|
||||
// then
|
||||
assertThat(distinctRoleNamesOf(rawRoleRepo.findAll())).containsExactlyInAnyOrder(
|
||||
@ -109,8 +109,7 @@ class HsOfficePersonRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
||||
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(
|
||||
Array.from(
|
||||
initialGrantNames,
|
||||
// FIXME: the INSERT grant is wrong in format and existence
|
||||
"{ grant perm INSERT on hs_office_person#anothernewperson to role hs_office_person#anothernewperson.admin by system and assume }",
|
||||
"{ grant perm INSERT into hs_office_relation with hs_office_person#anothernewperson to role hs_office_person#anothernewperson.admin by system and assume }",
|
||||
|
||||
"{ grant role hs_office_person#anothernewperson.owner to user selfregistered-user-drew@hostsharing.org by hs_office_person#anothernewperson.owner and assume }",
|
||||
"{ grant role hs_office_person#anothernewperson.owner to role global#global.admin by system and assume }",
|
||||
|
@ -131,7 +131,8 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
||||
"hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.tenant"));
|
||||
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll())).containsExactlyInAnyOrder(Array.fromFormatted(
|
||||
initialGrantNames,
|
||||
"{ grant perm INSERT on hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin by system and assume }",
|
||||
// TODO: this grant should only be created for DEBITOR-Relationships, thus the RBAC DSL needs to support conditional grants
|
||||
"{ grant perm INSERT into hs_office_sepamandate with hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.admin by system and assume }",
|
||||
|
||||
"{ grant perm DELETE on hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert to role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner by system and assume }",
|
||||
"{ grant role hs_office_relation#ErbenBesslerMelBessler-with-REPRESENTATIVE-BesslerBert.owner to role global#global.admin by system and assume }",
|
||||
|
Loading…
Reference in New Issue
Block a user