introduce separate database-schemas base+rbac #103

Merged
hsh-michaelhoennig merged 54 commits from introduce-separate-database-schemas-base-and-rbac into master 2024-09-16 15:36:38 +02:00
155 changed files with 827 additions and 816 deletions
Showing only changes of commit 1f9ee517e4 - Show all commits

View File

@ -77,17 +77,17 @@ If you have at least Docker and the Java JDK installed in appropriate versions a
# the following command should return a JSON array with just all customers: # the following command should return a JSON array with just all customers:
curl \ curl \
-H 'current-user: superuser-alex@hostsharing.net' \ -H 'current-subject: superuser-alex@hostsharing.net' \
http://localhost:8080/api/test/customers http://localhost:8080/api/test/customers
# the following command should return a JSON array with just all packages visible for the admin of the customer yyy: # the following command should return a JSON array with just all packages visible for the admin of the customer yyy:
curl \ curl \
-H 'current-user: superuser-alex@hostsharing.net' -H 'assumed-roles: test_customer#yyy:ADMIN' \ -H 'current-subject: superuser-alex@hostsharing.net' -H 'assumed-roles: test_customer#yyy:ADMIN' \
http://localhost:8080/api/test/packages http://localhost:8080/api/test/packages
# add a new customer # add a new customer
curl \ curl \
-H 'current-user: superuser-alex@hostsharing.net' -H "Content-Type: application/json" \ -H 'current-subject: superuser-alex@hostsharing.net' -H "Content-Type: application/json" \
-d '{ "prefix":"ttt", "reference":80001, "adminUserName":"admin@ttt.example.com" }' \ -d '{ "prefix":"ttt", "reference":80001, "adminUserName":"admin@ttt.example.com" }' \
-X POST http://localhost:8080/api/test/customers -X POST http://localhost:8080/api/test/customers

View File

@ -14,9 +14,9 @@ The core problem here is, that in our RBAC system, determining the permissions o
### Technical Background ### Technical Background
The session variable `hsadminng.currentUser` contains the accessing (domain-level) user, which is unrelated to the PostgreSQL user). The session variable `hsadminng.currentSubject` contains the accessing (domain-level) user, which is unrelated to the PostgreSQL user).
Given is a stored function `isPermissionGrantedToSubject` which detects if the accessing user has a given permission (e.g. 'view'). Given is a stored function `isPermissionGrantedToSubject` which detects if the accessing subject has a given permission (e.g. 'view').
Given is also a stored function `queryAllPermissionsOfSubjectId` which returns the flattened view to all permissions assigned to the given accessing user. Given is also a stored function `queryAllPermissionsOfSubjectId` which returns the flattened view to all permissions assigned to the given accessing user.
@ -38,7 +38,7 @@ In this solution, the database ignores row level visibility and returns all rows
Very flexible access, programmatic, rules could be implemented. Very flexible access, programmatic, rules could be implemented.
The role-hierarchy and permissions for currently logged-in users user could be cached in the backend. The role-hierarchy and permissions for currently logged-in sujects could be cached in the backend.
hsh-michaelhoennig marked this conversation as resolved Outdated

typo

typo
The access logic can be tested in pure Java unit tests. The access logic can be tested in pure Java unit tests.
@ -74,11 +74,11 @@ For restricted DB-users, which are used by the backend, access to rows is filter
FOR SELECT FOR SELECT
TO restricted TO restricted
USING ( USING (
isPermissionGrantedToSubject(findEffectivePermissionId('customer', id, 'view'), currentUserUuid()) isPermissionGrantedToSubject(findEffectivePermissionId('customer', id, 'view'), currentSubjectUuid())
); );
SET SESSION AUTHORIZATION restricted; SET SESSION AUTHORIZATION restricted;
SET hsadminng.currentUser TO 'alex@example.com'; SET hsadminng.currentSubject TO 'alex@example.com';
SELECT * from customer; -- will only return visible rows SELECT * from customer; -- will only return visible rows
#### Advantages #### Advantages
@ -101,10 +101,10 @@ We are bound to PostgreSQL, including integration tests and testing the RBAC sys
CREATE OR REPLACE RULE "_RETURN" AS CREATE OR REPLACE RULE "_RETURN" AS
ON SELECT TO cust_view ON SELECT TO cust_view
DO INSTEAD DO INSTEAD
SELECT * FROM customer WHERE isPermissionGrantedToSubject(findEffectivePermissionId('customer', id, 'view'), currentUserUuid()); SELECT * FROM customer WHERE isPermissionGrantedToSubject(findEffectivePermissionId('customer', id, 'view'), currentSubjectUuid());
SET SESSION AUTHORIZATION restricted; SET SESSION AUTHORIZATION restricted;
SET hsadminng.currentUser TO 'alex@example.com'; SET hsadminng.currentSubject TO 'alex@example.com';
SELECT * from customer; -- will only return visible rows SELECT * from customer; -- will only return visible rows
#### Advantages #### Advantages
@ -130,12 +130,12 @@ We do not access the tables directly from the backend, but via views which join
CREATE OR REPLACE VIEW cust_view AS CREATE OR REPLACE VIEW cust_view AS
SELECT c.id, c.reference, c.prefix SELECT c.id, c.reference, c.prefix
FROM customer AS c FROM customer AS c
JOIN queryAllPermissionsOfSubjectId(currentUserUuid()) AS p JOIN queryAllPermissionsOfSubjectId(currentSubjectUuid()) AS p
ON p.tableName='customer' AND p.rowId=c.id AND p.op='view'; ON p.tableName='customer' AND p.rowId=c.id AND p.op='view';
GRANT ALL PRIVILEGES ON cust_view TO restricted; GRANT ALL PRIVILEGES ON cust_view TO restricted;
SET SESSION SESSION AUTHORIZATION restricted; SET SESSION SESSION AUTHORIZATION restricted;
SET hsadminng.currentUser TO 'alex@example.com'; SET hsadminng.currentSubject TO 'alex@example.com';
SELECT * from cust_view; -- will only return visible rows SELECT * from cust_view; -- will only return visible rows
Alternatively the JOIN could also be applied in a "ON SELECT DO INSTEAD"-RULE, if there is any advantage for later features. Alternatively the JOIN could also be applied in a "ON SELECT DO INSTEAD"-RULE, if there is any advantage for later features.

View File

@ -392,9 +392,9 @@ We found some solution approaches:
3. Inverting the recursion of the CTE-query, combined with the type condition. 3. Inverting the recursion of the CTE-query, combined with the type condition.
Instead of starting the recursion with `currentsubjectsuuids()`, Instead of starting the recursion with `currentSubjectOrAssumedRolesUuids()`,
we could start it with the target table name and row-type, we could start it with the target table name and row-type,
then recurse down to the `currentsubjectsuuids()`. then recurse down to the `currentSubjectOrAssumedRolesUuids()`.
In the end, we need the object UUIDs, though. In the end, we need the object UUIDs, though.
But if we start with the join of `rbacObject` with `rbacPermission`, But if we start with the join of `rbacObject` with `rbacPermission`,

View File

@ -364,10 +364,10 @@ This way, each user can only select the data they have 'SELECT'-permission for,
### Current User ### Current User
The current use is taken from the session variable `hsadminng.currentUser` which contains the name of the user as stored in the The current use is taken from the session variable `hsadminng.currentSubject` which contains the name of the user as stored in the
*RbacUser*s table. Example: *RbacUser*s table. Example:
SET LOCAL hsadminng.currentUser = 'mike@hostsharing.net'; SET LOCAL hsadminng.currentSubject = 'mike@hostsharing.net';
That user is also used for historicization and audit log, but which is a different topic. That user is also used for historicization and audit log, but which is a different topic.
@ -388,7 +388,7 @@ A full example is shown here:
BEGIN TRANSACTION; BEGIN TRANSACTION;
SET SESSION SESSION AUTHORIZATION restricted; SET SESSION SESSION AUTHORIZATION restricted;
SET LOCAL hsadminng.currentUser = 'mike@hostsharing.net'; SET LOCAL hsadminng.currentSubject = 'mike@hostsharing.net';
SET LOCAL hsadminng.assumedRoles = 'customer#aab:admin;customer#aac:admin'; SET LOCAL hsadminng.assumedRoles = 'customer#aab:admin;customer#aac:admin';
SELECT c.prefix, p.name as "package", ema.localPart || '@' || dom.name as "email-address" SELECT c.prefix, p.name as "package", ema.localPart || '@' || dom.name as "email-address"
@ -624,7 +624,7 @@ Let's have a look at the two view queries:
WHERE target.uuid IN ( WHERE target.uuid IN (
SELECT uuid SELECT uuid
FROM queryAccessibleObjectUuidsOfSubjectIds( FROM queryAccessibleObjectUuidsOfSubjectIds(
'SELECT, 'customer', currentSubjectsUuids())); 'SELECT, 'customer', currentSubjectOrAssumedRolesUuids()));
This view should be automatically updatable. This view should be automatically updatable.
Where, for updates, we actually have to check for 'UPDATE' instead of 'SELECT' operation, which makes it a bit more complicated. Where, for updates, we actually have to check for 'UPDATE' instead of 'SELECT' operation, which makes it a bit more complicated.
@ -642,7 +642,7 @@ Looks like the query optimizer needed some statistics to find the best path.
SELECT DISTINCT target.* SELECT DISTINCT target.*
FROM customer AS target FROM customer AS target
JOIN queryAccessibleObjectUuidsOfSubjectIds( JOIN queryAccessibleObjectUuidsOfSubjectIds(
'SELECT, 'customer', currentSubjectsUuids()) AS allowedObjId 'SELECT, 'customer', currentSubjectOrAssumedRolesUuids()) AS allowedObjId
ON target.uuid = allowedObjId; ON target.uuid = allowedObjId;
This view cannot is not updatable automatically, This view cannot is not updatable automatically,

View File

@ -28,7 +28,7 @@ commit;
set hsadminng.tx_history_txid to ''; set hsadminng.tx_history_txid to '';
set hsadminng.tx_history_timestamp to '2024-08-29 12:42'; set hsadminng.tx_history_timestamp to '2024-08-29 12:42';
-- all versions -- all versions
select tx_history_txid(), txc.txtimestamp, txc.currentUser, txc.currentTask, haex.* select tx_history_txid(), txc.txtimestamp, txc.currentSubject, txc.currentTask, haex.*
from hs_hosting_asset_ex haex from hs_hosting_asset_ex haex
join basis.tx_context txc on haex.txid=txc.txid join basis.tx_context txc on haex.txid=txc.txid
where haex.identifier = 'test@thi.example.org'; where haex.identifier = 'test@thi.example.org';

View File

@ -20,11 +20,11 @@ CREATE POLICY customer_policy ON customer
TO restricted TO restricted
USING ( USING (
-- id=1000 -- id=1000
isPermissionGrantedToSubject(findEffectivePermissionId('test_customer', id, 'SELECT'), currentUserUuid()) isPermissionGrantedToSubject(findEffectivePermissionId('test_customer', id, 'SELECT'), rbac.currentSubjectUuid())
); );
SET SESSION AUTHORIZATION restricted; SET SESSION AUTHORIZATION restricted;
SET hsadminng.currentUser TO 'alex@example.com'; SET hsadminng.currentSubject TO 'alex@example.com';
SELECT * from customer; SELECT * from customer;
-- access control via view-rule and isPermissionGrantedToSubject - way too slow (35 s 580 ms for 1 million rows) -- access control via view-rule and isPermissionGrantedToSubject - way too slow (35 s 580 ms for 1 million rows)
@ -35,7 +35,7 @@ SELECT * FROM customer;
CREATE OR REPLACE RULE "_RETURN" AS CREATE OR REPLACE RULE "_RETURN" AS
ON SELECT TO cust_view ON SELECT TO cust_view
DO INSTEAD DO INSTEAD
SELECT * FROM customer WHERE isPermissionGrantedToSubject(findEffectivePermissionId('test_customer', id, 'SELECT'), currentUserUuid()); SELECT * FROM customer WHERE isPermissionGrantedToSubject(findEffectivePermissionId('test_customer', id, 'SELECT'), rbac.currentSubjectUuid());
SELECT * from cust_view LIMIT 10; SELECT * from cust_view LIMIT 10;
select queryAllPermissionsOfSubjectId(findRbacUser('superuser-alex@hostsharing.net')); select queryAllPermissionsOfSubjectId(findRbacUser('superuser-alex@hostsharing.net'));
@ -51,12 +51,12 @@ CREATE OR REPLACE RULE "_RETURN" AS
ON SELECT TO cust_view ON SELECT TO cust_view
DO INSTEAD DO INSTEAD
SELECT c.uuid, c.reference, c.prefix FROM customer AS c SELECT c.uuid, c.reference, c.prefix FROM customer AS c
JOIN queryAllPermissionsOfSubjectId(currentUserUuid()) AS p JOIN queryAllPermissionsOfSubjectId(rbac.currentSubjectUuid()) AS p
ON p.objectTable='test_customer' AND p.objectUuid=c.uuid; ON p.objectTable='test_customer' AND p.objectUuid=c.uuid;
GRANT ALL PRIVILEGES ON cust_view TO restricted; GRANT ALL PRIVILEGES ON cust_view TO restricted;
SET SESSION SESSION AUTHORIZATION restricted; SET SESSION SESSION AUTHORIZATION restricted;
SET hsadminng.currentUser TO 'alex@example.com'; SET hsadminng.currentSubject TO 'alex@example.com';
SELECT * from cust_view; SELECT * from cust_view;
@ -67,14 +67,14 @@ DROP VIEW IF EXISTS cust_view;
CREATE OR REPLACE VIEW cust_view AS CREATE OR REPLACE VIEW cust_view AS
SELECT c.uuid, c.reference, c.prefix SELECT c.uuid, c.reference, c.prefix
FROM customer AS c FROM customer AS c
JOIN queryAllPermissionsOfSubjectId(currentUserUuid()) AS p JOIN queryAllPermissionsOfSubjectId(rbac.currentSubjectUuid()) AS p
ON p.objectUuid=c.uuid; ON p.objectUuid=c.uuid;
GRANT ALL PRIVILEGES ON cust_view TO restricted; GRANT ALL PRIVILEGES ON cust_view TO restricted;
SET SESSION SESSION AUTHORIZATION restricted; SET SESSION SESSION AUTHORIZATION restricted;
-- SET hsadminng.currentUser TO 'alex@example.com'; -- SET hsadminng.currentSubject TO 'alex@example.com';
SET hsadminng.currentUser TO 'superuser-alex@hostsharing.net'; SET hsadminng.currentSubject TO 'superuser-alex@hostsharing.net';
-- SET hsadminng.currentUser TO 'aaaaouq@example.com'; -- SET hsadminng.currentSubject TO 'aaaaouq@example.com';
SELECT * from cust_view where reference=1144150; SELECT * from cust_view where reference=1144150;
select rr.uuid, rr.type from RbacGrants g select rr.uuid, rr.type from RbacGrants g

View File

@ -17,7 +17,7 @@ with recursive
1 as level, 1 as level,
true true
from rbacgrants from rbacgrants
where (rbacgrants.ascendantuuid = any (currentsubjectsuuids())) where (rbacgrants.ascendantuuid = any (rbac.currentSubjectOrAssumedRolesUuids()))
and rbacgrants.assumed and rbacgrants.assumed
union all union all
select distinct g.descendantuuid, select distinct g.descendantuuid,

View File

@ -38,53 +38,53 @@ public class Context {
private HttpServletRequest request; private HttpServletRequest request;
@Transactional(propagation = MANDATORY) @Transactional(propagation = MANDATORY)
public void define(final String currentUser) { public void define(final String currentSubject) {
define(currentUser, null); define(currentSubject, null);
} }
@Transactional(propagation = MANDATORY) @Transactional(propagation = MANDATORY)
public void define(final String currentUser, final String assumedRoles) { public void define(final String currentSubject, final String assumedRoles) {
define(toTask(request), toCurl(request), currentUser, assumedRoles); define(toTask(request), toCurl(request), currentSubject, assumedRoles);
} }
@Transactional(propagation = MANDATORY) @Transactional(propagation = MANDATORY)
public void define( public void define(
final String currentTask, final String currentTask,
final String currentRequest, final String currentRequest,
final String currentUser, final String currentSubject,
final String assumedRoles) { final String assumedRoles) {
final var query = em.createNativeQuery(""" final var query = em.createNativeQuery("""
call basis.defineContext( call basis.defineContext(
cast(:currentTask as varchar(127)), cast(:currentTask as varchar(127)),
cast(:currentRequest as text), cast(:currentRequest as text),
cast(:currentUser as varchar(63)), cast(:currentSubject as varchar(63)),
cast(:assumedRoles as varchar(1023))); cast(:assumedRoles as varchar(1023)));
"""); """);
query.setParameter("currentTask", shortenToMaxLength(currentTask, 127)); query.setParameter("currentTask", shortenToMaxLength(currentTask, 127));
query.setParameter("currentRequest", currentRequest); query.setParameter("currentRequest", currentRequest);
query.setParameter("currentUser", currentUser); query.setParameter("currentSubject", currentSubject);
query.setParameter("assumedRoles", assumedRoles != null ? assumedRoles : ""); query.setParameter("assumedRoles", assumedRoles != null ? assumedRoles : "");
query.executeUpdate(); query.executeUpdate();
} }
public String getCurrentTask() { public String fetchCurrentTask() {
return (String) em.createNativeQuery("select current_setting('hsadminng.currentTask');").getSingleResult(); return (String) em.createNativeQuery("select current_setting('hsadminng.currentTask');").getSingleResult();
} }
public String getCurrentUser() { public String fetchCurrentSubject() {
return String.valueOf(em.createNativeQuery("select currentUser()").getSingleResult()); return String.valueOf(em.createNativeQuery("select basis.currentSubject()").getSingleResult());
} }
public UUID getCurrentUserUUid() { public UUID fetchCurrentSubjectUuid() {
return (UUID) em.createNativeQuery("select currentUserUUid()", UUID.class).getSingleResult(); return (UUID) em.createNativeQuery("select rbac.currentSubjectUuid()", UUID.class).getSingleResult();
} }
public String[] getAssumedRoles() { public String[] fetchAssumedRoles() {
return (String[]) em.createNativeQuery("select assumedRoles() as roles", String[].class).getSingleResult(); return (String[]) em.createNativeQuery("select basis.assumedRoles() as roles", String[].class).getSingleResult();
} }
public UUID[] currentSubjectsUuids() { public UUID[] fetchCurrentSubjectOrAssumedRolesUuids() {
return (UUID[]) em.createNativeQuery("select currentSubjectsUuids() as uuids", UUID[].class).getSingleResult(); return (UUID[]) em.createNativeQuery("select rbac.currentSubjectOrAssumedRolesUuids() as uuids", UUID[].class).getSingleResult();
} }
public static String getCallerMethodNameFromStackFrame(final int skipFrames) { public static String getCallerMethodNameFromStackFrame(final int skipFrames) {

View File

@ -41,10 +41,10 @@ public class HsBookingItemController implements HsBookingItemsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsBookingItemResource>> listBookingItemsByProjectUuid( public ResponseEntity<List<HsBookingItemResource>> listBookingItemsByProjectUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID projectUuid) { final UUID projectUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = bookingItemRepo.findAllByProjectUuid(projectUuid); final var entities = bookingItemRepo.findAllByProjectUuid(projectUuid);
@ -55,11 +55,11 @@ public class HsBookingItemController implements HsBookingItemsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsBookingItemResource> addBookingItem( public ResponseEntity<HsBookingItemResource> addBookingItem(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsBookingItemInsertResource body) { final HsBookingItemInsertResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsBookingItemRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); final var entityToSave = mapper.map(body, HsBookingItemRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@ -77,11 +77,11 @@ public class HsBookingItemController implements HsBookingItemsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsBookingItemResource> getBookingItemByUuid( public ResponseEntity<HsBookingItemResource> getBookingItemByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID bookingItemUuid) { final UUID bookingItemUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = bookingItemRepo.findByUuid(bookingItemUuid); final var result = bookingItemRepo.findByUuid(bookingItemUuid);
result.ifPresent(entity -> em.detach(entity)); // prevent further LAZY-loading result.ifPresent(entity -> em.detach(entity)); // prevent further LAZY-loading
@ -94,10 +94,10 @@ public class HsBookingItemController implements HsBookingItemsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deleteBookingIemByUuid( public ResponseEntity<Void> deleteBookingIemByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID bookingItemUuid) { final UUID bookingItemUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = bookingItemRepo.deleteByUuid(bookingItemUuid); final var result = bookingItemRepo.deleteByUuid(bookingItemUuid);
return result == 0 return result == 0
@ -108,12 +108,12 @@ public class HsBookingItemController implements HsBookingItemsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsBookingItemResource> patchBookingItem( public ResponseEntity<HsBookingItemResource> patchBookingItem(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID bookingItemUuid, final UUID bookingItemUuid,
final HsBookingItemPatchResource body) { final HsBookingItemPatchResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var current = bookingItemRepo.findByUuid(bookingItemUuid).orElseThrow(); final var current = bookingItemRepo.findByUuid(bookingItemUuid).orElseThrow();

View File

@ -36,10 +36,10 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsBookingProjectResource>> listBookingProjectsByDebitorUuid( public ResponseEntity<List<HsBookingProjectResource>> listBookingProjectsByDebitorUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID debitorUuid) { final UUID debitorUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = bookingProjectRepo.findAllByDebitorUuid(debitorUuid); final var entities = bookingProjectRepo.findAllByDebitorUuid(debitorUuid);
@ -50,11 +50,11 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsBookingProjectResource> addBookingProject( public ResponseEntity<HsBookingProjectResource> addBookingProject(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsBookingProjectInsertResource body) { final HsBookingProjectInsertResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsBookingProjectRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); final var entityToSave = mapper.map(body, HsBookingProjectRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@ -72,11 +72,11 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsBookingProjectResource> getBookingProjectByUuid( public ResponseEntity<HsBookingProjectResource> getBookingProjectByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID bookingProjectUuid) { final UUID bookingProjectUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = bookingProjectRepo.findByUuid(bookingProjectUuid); final var result = bookingProjectRepo.findByUuid(bookingProjectUuid);
return result return result
@ -88,10 +88,10 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deleteBookingIemByUuid( public ResponseEntity<Void> deleteBookingIemByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID bookingProjectUuid) { final UUID bookingProjectUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = bookingProjectRepo.deleteByUuid(bookingProjectUuid); final var result = bookingProjectRepo.deleteByUuid(bookingProjectUuid);
return result == 0 return result == 0
@ -102,12 +102,12 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsBookingProjectResource> patchBookingProject( public ResponseEntity<HsBookingProjectResource> patchBookingProject(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID bookingProjectUuid, final UUID bookingProjectUuid,
final HsBookingProjectPatchResource body) { final HsBookingProjectPatchResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var current = bookingProjectRepo.findByUuid(bookingProjectUuid).orElseThrow(); final var current = bookingProjectRepo.findByUuid(bookingProjectUuid).orElseThrow();

View File

@ -49,12 +49,12 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsHostingAssetResource>> listAssets( public ResponseEntity<List<HsHostingAssetResource>> listAssets(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID debitorUuid, final UUID debitorUuid,
final UUID parentAssetUuid, final UUID parentAssetUuid,
final HsHostingAssetTypeResource type) { final HsHostingAssetTypeResource type) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = rbacAssetRepo.findAllByCriteria(debitorUuid, parentAssetUuid, HsHostingAssetType.of(type)); final var entities = rbacAssetRepo.findAllByCriteria(debitorUuid, parentAssetUuid, HsHostingAssetType.of(type));
@ -66,11 +66,11 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsHostingAssetResource> addAsset( public ResponseEntity<HsHostingAssetResource> addAsset(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsHostingAssetInsertResource body) { final HsHostingAssetInsertResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entity = mapper.map(body, HsHostingAssetRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); final var entity = mapper.map(body, HsHostingAssetRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@ -94,11 +94,11 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsHostingAssetResource> getAssetByUuid( public ResponseEntity<HsHostingAssetResource> getAssetByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID assetUuid) { final UUID assetUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = rbacAssetRepo.findByUuid(assetUuid); final var result = rbacAssetRepo.findByUuid(assetUuid);
return result return result
@ -110,10 +110,10 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deleteAssetUuid( public ResponseEntity<Void> deleteAssetUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID assetUuid) { final UUID assetUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = rbacAssetRepo.deleteByUuid(assetUuid); final var result = rbacAssetRepo.deleteByUuid(assetUuid);
return result == 0 return result == 0
@ -124,12 +124,12 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsHostingAssetResource> patchAsset( public ResponseEntity<HsHostingAssetResource> patchAsset(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID assetUuid, final UUID assetUuid,
final HsHostingAssetPatchResource body) { final HsHostingAssetPatchResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entity = rbacAssetRepo.findByUuid(assetUuid).orElseThrow(); final var entity = rbacAssetRepo.findByUuid(assetUuid).orElseThrow();

View File

@ -32,10 +32,10 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeBankAccountResource>> listBankAccounts( public ResponseEntity<List<HsOfficeBankAccountResource>> listBankAccounts(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final String holder) { final String holder) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = bankAccountRepo.findByOptionalHolderLike(holder); final var entities = bankAccountRepo.findByOptionalHolderLike(holder);
@ -46,11 +46,11 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeBankAccountResource> addBankAccount( public ResponseEntity<HsOfficeBankAccountResource> addBankAccount(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsOfficeBankAccountInsertResource body) { final HsOfficeBankAccountInsertResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
IbanUtil.validate(body.getIban()); IbanUtil.validate(body.getIban());
BicUtil.validate(body.getBic()); BicUtil.validate(body.getBic());
@ -72,11 +72,11 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsOfficeBankAccountResource> getBankAccountByUuid( public ResponseEntity<HsOfficeBankAccountResource> getBankAccountByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID bankAccountUuid) { final UUID bankAccountUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = bankAccountRepo.findByUuid(bankAccountUuid); final var result = bankAccountRepo.findByUuid(bankAccountUuid);
if (result.isEmpty()) { if (result.isEmpty()) {
@ -88,10 +88,10 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deleteBankAccountByUuid( public ResponseEntity<Void> deleteBankAccountByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID BankAccountUuid) { final UUID BankAccountUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = bankAccountRepo.deleteByUuid(BankAccountUuid); final var result = bankAccountRepo.deleteByUuid(BankAccountUuid);
if (result == 0) { if (result == 0) {

View File

@ -34,10 +34,10 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeContactResource>> listContacts( public ResponseEntity<List<HsOfficeContactResource>> listContacts(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final String caption) { final String caption) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = contactRepo.findContactByOptionalCaptionLike(caption); final var entities = contactRepo.findContactByOptionalCaptionLike(caption);
@ -48,11 +48,11 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeContactResource> addContact( public ResponseEntity<HsOfficeContactResource> addContact(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsOfficeContactInsertResource body) { final HsOfficeContactInsertResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsOfficeContactRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); final var entityToSave = mapper.map(body, HsOfficeContactRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@ -70,11 +70,11 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsOfficeContactResource> getContactByUuid( public ResponseEntity<HsOfficeContactResource> getContactByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID contactUuid) { final UUID contactUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = contactRepo.findByUuid(contactUuid); final var result = contactRepo.findByUuid(contactUuid);
if (result.isEmpty()) { if (result.isEmpty()) {
@ -86,10 +86,10 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deleteContactByUuid( public ResponseEntity<Void> deleteContactByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID contactUuid) { final UUID contactUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = contactRepo.deleteByUuid(contactUuid); final var result = contactRepo.deleteByUuid(contactUuid);
if (result == 0) { if (result == 0) {
@ -102,12 +102,12 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeContactResource> patchContact( public ResponseEntity<HsOfficeContactResource> patchContact(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID contactUuid, final UUID contactUuid,
final HsOfficeContactPatchResource body) { final HsOfficeContactPatchResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var current = contactRepo.findByUuid(contactUuid).orElseThrow(); final var current = contactRepo.findByUuid(contactUuid).orElseThrow();

View File

@ -37,12 +37,12 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeCoopAssetsTransactionResource>> listCoopAssets( public ResponseEntity<List<HsOfficeCoopAssetsTransactionResource>> listCoopAssets(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID membershipUuid, final UUID membershipUuid,
final @DateTimeFormat(iso = ISO.DATE) LocalDate fromValueDate, final @DateTimeFormat(iso = ISO.DATE) LocalDate fromValueDate,
final @DateTimeFormat(iso = ISO.DATE) LocalDate toValueDate) { final @DateTimeFormat(iso = ISO.DATE) LocalDate toValueDate) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange( final var entities = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
membershipUuid, membershipUuid,
@ -56,11 +56,11 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeCoopAssetsTransactionResource> addCoopAssetsTransaction( public ResponseEntity<HsOfficeCoopAssetsTransactionResource> addCoopAssetsTransaction(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsOfficeCoopAssetsTransactionInsertResource requestBody) { final HsOfficeCoopAssetsTransactionInsertResource requestBody) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
validate(requestBody); validate(requestBody);
final var entityToSave = mapper.map(requestBody, HsOfficeCoopAssetsTransactionEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); final var entityToSave = mapper.map(requestBody, HsOfficeCoopAssetsTransactionEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@ -79,9 +79,9 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsOfficeCoopAssetsTransactionResource> getCoopAssetTransactionByUuid( public ResponseEntity<HsOfficeCoopAssetsTransactionResource> getCoopAssetTransactionByUuid(
final String currentUser, final String assumedRoles, final UUID assetTransactionUuid) { final String currentSubject, final String assumedRoles, final UUID assetTransactionUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = coopAssetsTransactionRepo.findByUuid(assetTransactionUuid); final var result = coopAssetsTransactionRepo.findByUuid(assetTransactionUuid);
if (result.isEmpty()) { if (result.isEmpty()) {

View File

@ -39,12 +39,12 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeCoopSharesTransactionResource>> listCoopShares( public ResponseEntity<List<HsOfficeCoopSharesTransactionResource>> listCoopShares(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID membershipUuid, final UUID membershipUuid,
final @DateTimeFormat(iso = ISO.DATE) LocalDate fromValueDate, final @DateTimeFormat(iso = ISO.DATE) LocalDate fromValueDate,
final @DateTimeFormat(iso = ISO.DATE) LocalDate toValueDate) { final @DateTimeFormat(iso = ISO.DATE) LocalDate toValueDate) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange( final var entities = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
membershipUuid, membershipUuid,
@ -58,11 +58,11 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeCoopSharesTransactionResource> addCoopSharesTransaction( public ResponseEntity<HsOfficeCoopSharesTransactionResource> addCoopSharesTransaction(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsOfficeCoopSharesTransactionInsertResource requestBody) { final HsOfficeCoopSharesTransactionInsertResource requestBody) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
validate(requestBody); validate(requestBody);
final var entityToSave = mapper.map(requestBody, HsOfficeCoopSharesTransactionEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); final var entityToSave = mapper.map(requestBody, HsOfficeCoopSharesTransactionEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
@ -81,9 +81,9 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsOfficeCoopSharesTransactionResource> getCoopShareTransactionByUuid( public ResponseEntity<HsOfficeCoopSharesTransactionResource> getCoopShareTransactionByUuid(
final String currentUser, final String assumedRoles, final UUID shareTransactionUuid) { final String currentSubject, final String assumedRoles, final UUID shareTransactionUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = coopSharesTransactionRepo.findByUuid(shareTransactionUuid); final var result = coopSharesTransactionRepo.findByUuid(shareTransactionUuid);
if (result.isEmpty()) { if (result.isEmpty()) {

View File

@ -48,11 +48,11 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeDebitorResource>> listDebitors( public ResponseEntity<List<HsOfficeDebitorResource>> listDebitors(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final String name, final String name,
final Integer debitorNumber) { final Integer debitorNumber) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = debitorNumber != null final var entities = debitorNumber != null
? debitorRepo.findDebitorByDebitorNumber(debitorNumber) ? debitorRepo.findDebitorByDebitorNumber(debitorNumber)
@ -65,11 +65,11 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeDebitorResource> addDebitor( public ResponseEntity<HsOfficeDebitorResource> addDebitor(
String currentUser, String currentSubject,
String assumedRoles, String assumedRoles,
HsOfficeDebitorInsertResource body) { HsOfficeDebitorInsertResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRelUuid() == null, Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRelUuid() == null,
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found both"); "ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found both");
@ -112,11 +112,11 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsOfficeDebitorResource> getDebitorByUuid( public ResponseEntity<HsOfficeDebitorResource> getDebitorByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID debitorUuid) { final UUID debitorUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = debitorRepo.findByUuid(debitorUuid); final var result = debitorRepo.findByUuid(debitorUuid);
if (result.isEmpty()) { if (result.isEmpty()) {
@ -128,10 +128,10 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deleteDebitorByUuid( public ResponseEntity<Void> deleteDebitorByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID debitorUuid) { final UUID debitorUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = debitorRepo.deleteByUuid(debitorUuid); final var result = debitorRepo.deleteByUuid(debitorUuid);
if (result == 0) { if (result == 0) {
@ -144,12 +144,12 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeDebitorResource> patchDebitor( public ResponseEntity<HsOfficeDebitorResource> patchDebitor(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID debitorUuid, final UUID debitorUuid,
final HsOfficeDebitorPatchResource body) { final HsOfficeDebitorPatchResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow(); final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow();

View File

@ -32,11 +32,11 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeMembershipResource>> listMemberships( public ResponseEntity<List<HsOfficeMembershipResource>> listMemberships(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
UUID partnerUuid, UUID partnerUuid,
Integer memberNumber) { Integer memberNumber) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = ( memberNumber != null) final var entities = ( memberNumber != null)
? List.of(membershipRepo.findMembershipByMemberNumber(memberNumber)) ? List.of(membershipRepo.findMembershipByMemberNumber(memberNumber))
@ -50,11 +50,11 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeMembershipResource> addMembership( public ResponseEntity<HsOfficeMembershipResource> addMembership(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsOfficeMembershipInsertResource body) { final HsOfficeMembershipInsertResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class); final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class);
@ -73,11 +73,11 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsOfficeMembershipResource> getMembershipByUuid( public ResponseEntity<HsOfficeMembershipResource> getMembershipByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID membershipUuid) { final UUID membershipUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = membershipRepo.findByUuid(membershipUuid); final var result = membershipRepo.findByUuid(membershipUuid);
if (result.isEmpty()) { if (result.isEmpty()) {
@ -90,10 +90,10 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deleteMembershipByUuid( public ResponseEntity<Void> deleteMembershipByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID membershipUuid) { final UUID membershipUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = membershipRepo.deleteByUuid(membershipUuid); final var result = membershipRepo.deleteByUuid(membershipUuid);
if (result == 0) { if (result == 0) {
@ -106,12 +106,12 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeMembershipResource> patchMembership( public ResponseEntity<HsOfficeMembershipResource> patchMembership(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID membershipUuid, final UUID membershipUuid,
final HsOfficeMembershipPatchResource body) { final HsOfficeMembershipPatchResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var current = membershipRepo.findByUuid(membershipUuid).orElseThrow(); final var current = membershipRepo.findByUuid(membershipUuid).orElseThrow();

View File

@ -50,10 +50,10 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsOfficePartnerResource>> listPartners( public ResponseEntity<List<HsOfficePartnerResource>> listPartners(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final String name) { final String name) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = partnerRepo.findPartnerByOptionalNameLike(name); final var entities = partnerRepo.findPartnerByOptionalNameLike(name);
@ -64,11 +64,11 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficePartnerResource> addPartner( public ResponseEntity<HsOfficePartnerResource> addPartner(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsOfficePartnerInsertResource body) { final HsOfficePartnerInsertResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entityToSave = createPartnerEntity(body); final var entityToSave = createPartnerEntity(body);
@ -86,11 +86,11 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsOfficePartnerResource> getPartnerByUuid( public ResponseEntity<HsOfficePartnerResource> getPartnerByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID partnerUuid) { final UUID partnerUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = partnerRepo.findByUuid(partnerUuid); final var result = partnerRepo.findByUuid(partnerUuid);
if (result.isEmpty()) { if (result.isEmpty()) {
@ -102,10 +102,10 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deletePartnerByUuid( public ResponseEntity<Void> deletePartnerByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID partnerUuid) { final UUID partnerUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var partnerToDelete = partnerRepo.findByUuid(partnerUuid); final var partnerToDelete = partnerRepo.findByUuid(partnerUuid);
if (partnerToDelete.isEmpty()) { if (partnerToDelete.isEmpty()) {
@ -122,12 +122,12 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficePartnerResource> patchPartner( public ResponseEntity<HsOfficePartnerResource> patchPartner(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID partnerUuid, final UUID partnerUuid,
final HsOfficePartnerPatchResource body) { final HsOfficePartnerPatchResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var current = partnerRepo.findByUuid(partnerUuid).orElseThrow(); final var current = partnerRepo.findByUuid(partnerUuid).orElseThrow();
final var previousPartnerRel = current.getPartnerRel(); final var previousPartnerRel = current.getPartnerRel();

View File

@ -31,10 +31,10 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsOfficePersonResource>> listPersons( public ResponseEntity<List<HsOfficePersonResource>> listPersons(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final String caption) { final String caption) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = personRepo.findPersonByOptionalNameLike(caption); final var entities = personRepo.findPersonByOptionalNameLike(caption);
@ -45,11 +45,11 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficePersonResource> addPerson( public ResponseEntity<HsOfficePersonResource> addPerson(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsOfficePersonInsertResource body) { final HsOfficePersonInsertResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsOfficePersonEntity.class); final var entityToSave = mapper.map(body, HsOfficePersonEntity.class);
@ -67,11 +67,11 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsOfficePersonResource> getPersonByUuid( public ResponseEntity<HsOfficePersonResource> getPersonByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID personUuid) { final UUID personUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = personRepo.findByUuid(personUuid); final var result = personRepo.findByUuid(personUuid);
if (result.isEmpty()) { if (result.isEmpty()) {
@ -83,10 +83,10 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deletePersonByUuid( public ResponseEntity<Void> deletePersonByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID personUuid) { final UUID personUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = personRepo.deleteByUuid(personUuid); final var result = personRepo.deleteByUuid(personUuid);
if (result == 0) { if (result == 0) {
@ -99,12 +99,12 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficePersonResource> patchPerson( public ResponseEntity<HsOfficePersonResource> patchPerson(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID personUuid, final UUID personUuid,
final HsOfficePersonPatchResource body) { final HsOfficePersonPatchResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var current = personRepo.findByUuid(personUuid).orElseThrow(); final var current = personRepo.findByUuid(personUuid).orElseThrow();

View File

@ -45,11 +45,11 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeRelationResource>> listRelations( public ResponseEntity<List<HsOfficeRelationResource>> listRelations(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID personUuid, final UUID personUuid,
final HsOfficeRelationTypeResource relationType) { final HsOfficeRelationTypeResource relationType) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = relationRbacRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid, final var entities = relationRbacRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid,
mapper.map(relationType, HsOfficeRelationType.class)); mapper.map(relationType, HsOfficeRelationType.class));
@ -62,11 +62,11 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeRelationResource> addRelation( public ResponseEntity<HsOfficeRelationResource> addRelation(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsOfficeRelationInsertResource body) { final HsOfficeRelationInsertResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entityToSave = new HsOfficeRelationRbacEntity(); final var entityToSave = new HsOfficeRelationRbacEntity();
entityToSave.setType(HsOfficeRelationType.valueOf(body.getType())); entityToSave.setType(HsOfficeRelationType.valueOf(body.getType()));
@ -96,11 +96,11 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsOfficeRelationResource> getRelationByUuid( public ResponseEntity<HsOfficeRelationResource> getRelationByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID relationUuid) { final UUID relationUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = relationRbacRepo.findByUuid(relationUuid); final var result = relationRbacRepo.findByUuid(relationUuid);
if (result.isEmpty()) { if (result.isEmpty()) {
@ -112,10 +112,10 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deleteRelationByUuid( public ResponseEntity<Void> deleteRelationByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID relationUuid) { final UUID relationUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = relationRbacRepo.deleteByUuid(relationUuid); final var result = relationRbacRepo.deleteByUuid(relationUuid);
if (result == 0) { if (result == 0) {
@ -128,12 +128,12 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeRelationResource> patchRelation( public ResponseEntity<HsOfficeRelationResource> patchRelation(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID relationUuid, final UUID relationUuid,
final HsOfficeRelationPatchResource body) { final HsOfficeRelationPatchResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var current = relationRbacRepo.findByUuid(relationUuid).orElseThrow(); final var current = relationRbacRepo.findByUuid(relationUuid).orElseThrow();

View File

@ -39,10 +39,10 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<HsOfficeSepaMandateResource>> listSepaMandatesByIban( public ResponseEntity<List<HsOfficeSepaMandateResource>> listSepaMandatesByIban(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final String iban) { final String iban) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entities = sepaMandateRepo.findSepaMandateByOptionalIban(iban); final var entities = sepaMandateRepo.findSepaMandateByOptionalIban(iban);
@ -54,11 +54,11 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeSepaMandateResource> addSepaMandate( public ResponseEntity<HsOfficeSepaMandateResource> addSepaMandate(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final HsOfficeSepaMandateInsertResource body) { final HsOfficeSepaMandateInsertResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var entityToSave = mapper.map(body, HsOfficeSepaMandateEntity.class, SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER); final var entityToSave = mapper.map(body, HsOfficeSepaMandateEntity.class, SEPA_MANDATE_RESOURCE_TO_ENTITY_POSTMAPPER);
@ -77,11 +77,11 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<HsOfficeSepaMandateResource> getSepaMandateByUuid( public ResponseEntity<HsOfficeSepaMandateResource> getSepaMandateByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID sepaMandateUuid) { final UUID sepaMandateUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = sepaMandateRepo.findByUuid(sepaMandateUuid); final var result = sepaMandateRepo.findByUuid(sepaMandateUuid);
if (result.isEmpty()) { if (result.isEmpty()) {
@ -94,10 +94,10 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deleteSepaMandateByUuid( public ResponseEntity<Void> deleteSepaMandateByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID sepaMandateUuid) { final UUID sepaMandateUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = sepaMandateRepo.deleteByUuid(sepaMandateUuid); final var result = sepaMandateRepo.deleteByUuid(sepaMandateUuid);
if (result == 0) { if (result == 0) {
@ -110,12 +110,12 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<HsOfficeSepaMandateResource> patchSepaMandate( public ResponseEntity<HsOfficeSepaMandateResource> patchSepaMandate(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID sepaMandateUuid, final UUID sepaMandateUuid,
final HsOfficeSepaMandatePatchResource body) { final HsOfficeSepaMandatePatchResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var current = sepaMandateRepo.findByUuid(sepaMandateUuid).orElseThrow(); final var current = sepaMandateRepo.findByUuid(sepaMandateUuid).orElseThrow();

View File

@ -255,7 +255,7 @@ public class InsertTriggerGenerator {
plPgSql.writeLn(); plPgSql.writeLn();
plPgSql.writeLn(""" plPgSql.writeLn("""
raise exception '[403] insert into ${rawSubTable} values(%) not allowed for current subjects % (%)', raise exception '[403] insert into ${rawSubTable} values(%) not allowed for current subjects % (%)',
NEW, currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), currentSubjectOrAssumedRolesUuids();
end; $$; end; $$;
create trigger ${rawSubTable}_insert_permission_check_tg create trigger ${rawSubTable}_insert_permission_check_tg

View File

@ -580,7 +580,7 @@ class RolesGrantsAndPermissionsGenerator {
private String toPlPgSqlReference(final RbacView.RbacUserReference userRef) { private String toPlPgSqlReference(final RbacView.RbacUserReference userRef) {
return switch (userRef.role) { return switch (userRef.role) {
case CREATOR -> "currentUserUuid()"; case CREATOR -> "currentSubjectUuid()";
default -> throw new IllegalArgumentException("unknown user role: " + userRef); default -> throw new IllegalArgumentException("unknown user role: " + userRef);
}; };
} }

View File

@ -33,12 +33,12 @@ public class RbacGrantController implements RbacGrantsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<RbacGrantResource> getGrantById( public ResponseEntity<RbacGrantResource> getGrantById(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID grantedRoleUuid, final UUID grantedRoleUuid,
final UUID granteeUserUuid) { final UUID granteeUserUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var id = new RbacGrantId(granteeUserUuid, grantedRoleUuid); final var id = new RbacGrantId(granteeUserUuid, grantedRoleUuid);
final var result = rbacGrantRepository.findById(id); final var result = rbacGrantRepository.findById(id);
@ -51,10 +51,10 @@ public class RbacGrantController implements RbacGrantsApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<RbacGrantResource>> listUserGrants( public ResponseEntity<List<RbacGrantResource>> listUserGrants(
final String currentUser, final String currentSubject,
final String assumedRoles) { final String assumedRoles) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
return ResponseEntity.ok(mapper.mapList(rbacGrantRepository.findAll(), RbacGrantResource.class)); return ResponseEntity.ok(mapper.mapList(rbacGrantRepository.findAll(), RbacGrantResource.class));
} }
@ -62,11 +62,11 @@ public class RbacGrantController implements RbacGrantsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<RbacGrantResource> grantRoleToUser( public ResponseEntity<RbacGrantResource> grantRoleToUser(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final RbacGrantResource body) { final RbacGrantResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var granted = rbacGrantRepository.save(mapper.map(body, RbacGrantEntity.class)); final var granted = rbacGrantRepository.save(mapper.map(body, RbacGrantEntity.class));
em.flush(); em.flush();
@ -83,12 +83,12 @@ public class RbacGrantController implements RbacGrantsApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> revokeRoleFromUser( public ResponseEntity<Void> revokeRoleFromUser(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID grantedRoleUuid, final UUID grantedRoleUuid,
final UUID granteeUserUuid) { final UUID granteeUserUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
rbacGrantRepository.deleteByRbacGrantId(new RbacGrantId(granteeUserUuid, grantedRoleUuid)); rbacGrantRepository.deleteByRbacGrantId(new RbacGrantId(granteeUserUuid, grantedRoleUuid));
@ -101,9 +101,9 @@ public class RbacGrantController implements RbacGrantsApi {
// produces = {"text/vnd.mermaid"}) // produces = {"text/vnd.mermaid"})
// @Transactional(readOnly = true) // @Transactional(readOnly = true)
// public ResponseEntity<String> allGrantsOfUserAsMermaid( // public ResponseEntity<String> allGrantsOfUserAsMermaid(
// @RequestHeader(name = "current-user") String currentUser, // @RequestHeader(name = "current-subject") String currentSubject,
// @RequestHeader(name = "assumed-roles", required = false) String assumedRoles) { // @RequestHeader(name = "assumed-roles", required = false) String assumedRoles) {
// final var graph = RbacGrantsDiagramService.allGrantsToUser(currentUser); // final var graph = RbacGrantsDiagramService.allGrantsToUser(currentSubject);
// return ResponseEntity.ok(graph); // return ResponseEntity.ok(graph);
// } // }

View File

@ -64,9 +64,9 @@ public class RbacGrantsDiagramService {
private Map<UUID, List<RawRbacGrantEntity>> descendantsByUuid = new HashMap<>(); private Map<UUID, List<RawRbacGrantEntity>> descendantsByUuid = new HashMap<>();
public String allGrantsToCurrentUser(final EnumSet<Include> includes) { public String allGrantsTocurrentSubject(final EnumSet<Include> includes) {
final var graph = new LimitedHashSet<RawRbacGrantEntity>(); final var graph = new LimitedHashSet<RawRbacGrantEntity>();
for ( UUID subjectUuid: context.currentSubjectsUuids() ) { for ( UUID subjectUuid: context.fetchCurrentSubjectOrAssumedRolesUuids() ) {
traverseGrantsTo(graph, subjectUuid, includes); traverseGrantsTo(graph, subjectUuid, includes);
} }
return toMermaidFlowchart(graph, includes); return toMermaidFlowchart(graph, includes);

View File

@ -26,10 +26,10 @@ public class RbacRoleController implements RbacRolesApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<RbacRoleResource>> listRoles( public ResponseEntity<List<RbacRoleResource>> listRoles(
final String currentUser, final String currentSubject,
final String assumedRoles) { final String assumedRoles) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final List<RbacRoleEntity> result = rbacRoleRepository.findAll(); final List<RbacRoleEntity> result = rbacRoleRepository.findAll();

View File

@ -49,11 +49,11 @@ public class RbacUserController implements RbacUsersApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<Void> deleteUserByUuid( public ResponseEntity<Void> deleteUserByUuid(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID userUuid final UUID userUuid
) { ) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
rbacUserRepository.deleteByUuid(userUuid); rbacUserRepository.deleteByUuid(userUuid);
@ -63,11 +63,11 @@ public class RbacUserController implements RbacUsersApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<RbacUserResource> getUserById( public ResponseEntity<RbacUserResource> getUserById(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID userUuid) { final UUID userUuid) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = rbacUserRepository.findByUuid(userUuid); final var result = rbacUserRepository.findByUuid(userUuid);
if (result == null) { if (result == null) {
@ -79,11 +79,11 @@ public class RbacUserController implements RbacUsersApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<RbacUserResource>> listUsers( public ResponseEntity<List<RbacUserResource>> listUsers(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final String userName final String userName
) { ) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
return ResponseEntity.ok(mapper.mapList(rbacUserRepository.findByOptionalNameLike(userName), RbacUserResource.class)); return ResponseEntity.ok(mapper.mapList(rbacUserRepository.findByOptionalNameLike(userName), RbacUserResource.class));
} }
@ -91,11 +91,11 @@ public class RbacUserController implements RbacUsersApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<RbacUserPermissionResource>> listUserPermissions( public ResponseEntity<List<RbacUserPermissionResource>> listUserPermissions(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID userUuid final UUID userUuid
) { ) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
return ResponseEntity.ok(mapper.mapList( return ResponseEntity.ok(mapper.mapList(
rbacUserRepository.findPermissionsOfUserByUuid(userUuid), rbacUserRepository.findPermissionsOfUserByUuid(userUuid),

View File

@ -17,7 +17,7 @@ public interface RbacUserRepository extends Repository<RbacUserEntity, UUID> {
List<RbacUserEntity> findByOptionalNameLike(String userName); List<RbacUserEntity> findByOptionalNameLike(String userName);
// bypasses the restricted view, to be able to grant rights to arbitrary user // bypasses the restricted view, to be able to grant rights to arbitrary user
@Query(value = "select * from rbacuser where name=:userName", nativeQuery = true) @Query(value = "select * from rbac.subject where name=:userName", nativeQuery = true)
RbacUserEntity findByName(String userName); RbacUserEntity findByName(String userName);
RbacUserEntity findByUuid(UUID uuid); RbacUserEntity findByUuid(UUID uuid);
@ -28,7 +28,7 @@ public interface RbacUserRepository extends Repository<RbacUserEntity, UUID> {
/* /*
Can't use save/saveAndFlush from SpringData because the uuid is not generated on the entity level, Can't use save/saveAndFlush from SpringData because the uuid is not generated on the entity level,
but explicitly, and then SpringData check's if it exists using an SQL SELECT. but explicitly, and then SpringData check's if it exists using an SQL SELECT.
And SQL SELECT needs a currentUser which we don't yet have in the case of self registration. And SQL SELECT needs a currentSubject which we don't yet have in the case of self registration.
*/ */
@Modifying @Modifying
@Query(value = "insert into RBacUser_RV (uuid, name) values( :#{#newUser.uuid}, :#{#newUser.name})", nativeQuery = true) @Query(value = "insert into RBacUser_RV (uuid, name) values( :#{#newUser.uuid}, :#{#newUser.name})", nativeQuery = true)

View File

@ -32,11 +32,11 @@ public class TestCustomerController implements TestCustomersApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<TestCustomerResource>> listCustomers( public ResponseEntity<List<TestCustomerResource>> listCustomers(
String currentUser, String currentSubject,
String assumedRoles, String assumedRoles,
String prefix String prefix
) { ) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = testCustomerRepository.findCustomerByOptionalPrefixLike(prefix); final var result = testCustomerRepository.findCustomerByOptionalPrefixLike(prefix);
@ -46,11 +46,11 @@ public class TestCustomerController implements TestCustomersApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<TestCustomerResource> addCustomer( public ResponseEntity<TestCustomerResource> addCustomer(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final TestCustomerResource customer) { final TestCustomerResource customer) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var saved = testCustomerRepository.save(mapper.map(customer, TestCustomerEntity.class)); final var saved = testCustomerRepository.save(mapper.map(customer, TestCustomerEntity.class));
final var uri = final var uri =

View File

@ -29,11 +29,11 @@ public class TestPackageController implements TestPackagesApi {
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseEntity<List<TestPackageResource>> listPackages( public ResponseEntity<List<TestPackageResource>> listPackages(
String currentUser, String currentSubject,
String assumedRoles, String assumedRoles,
String name String name
) { ) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var result = testPackageRepository.findAllByOptionalNameLike(name); final var result = testPackageRepository.findAllByOptionalNameLike(name);
return ResponseEntity.ok(mapper.mapList(result, TestPackageResource.class)); return ResponseEntity.ok(mapper.mapList(result, TestPackageResource.class));
@ -42,12 +42,12 @@ public class TestPackageController implements TestPackagesApi {
@Override @Override
@Transactional @Transactional
public ResponseEntity<TestPackageResource> updatePackage( public ResponseEntity<TestPackageResource> updatePackage(
final String currentUser, final String currentSubject,
final String assumedRoles, final String assumedRoles,
final UUID packageUuid, final UUID packageUuid,
final TestPackageUpdateResource body) { final TestPackageUpdateResource body) {
context.define(currentUser, assumedRoles); context.define(currentSubject, assumedRoles);
final var current = testPackageRepository.findByUuid(packageUuid); final var current = testPackageRepository.findByUuid(packageUuid);
OptionalFromJson.of(body.getDescription()).ifPresent(current::setDescription); OptionalFromJson.of(body.getDescription()).ifPresent(current::setDescription);

View File

@ -3,8 +3,8 @@ components:
parameters: parameters:
currentUser: currentSubject:
name: current-user name: current-subject
in: header in: header
required: true required: true
schema: schema:

View File

@ -3,8 +3,8 @@ components:
parameters: parameters:
currentUser: currentSubject:
name: current-user name: current-subject
in: header in: header
required: true required: true
schema: schema:

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single booking item its uuid, if visible for the current subject.' description: 'Fetch a single booking item its uuid, if visible for the current subject.'
operationId: getBookingItemByUuid operationId: getBookingItemByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingItemUuid - name: bookingItemUuid
in: path in: path
@ -32,7 +32,7 @@ patch:
description: 'Updates a single booking item identified by its uuid, if permitted for the current subject.' description: 'Updates a single booking item identified by its uuid, if permitted for the current subject.'
operationId: patchBookingItem operationId: patchBookingItem
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingItemUuid - name: bookingItemUuid
in: path in: path
@ -63,7 +63,7 @@ delete:
description: 'Delete a single booking item identified by its uuid, if permitted for the current subject.' description: 'Delete a single booking item identified by its uuid, if permitted for the current subject.'
operationId: deleteBookingIemByUuid operationId: deleteBookingIemByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingItemUuid - name: bookingItemUuid
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-booking-items - hs-booking-items
operationId: listBookingItemsByProjectUuid operationId: listBookingItemsByProjectUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: projectUuid - name: projectUuid
in: query in: query
@ -34,7 +34,7 @@ post:
- hs-booking-items - hs-booking-items
operationId: addBookingItem operationId: addBookingItem
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
description: A JSON object describing the new booking item. description: A JSON object describing the new booking item.

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single booking project its uuid, if visible for the current subject.' description: 'Fetch a single booking project its uuid, if visible for the current subject.'
operationId: getBookingProjectByUuid operationId: getBookingProjectByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingProjectUuid - name: bookingProjectUuid
in: path in: path
@ -32,7 +32,7 @@ patch:
description: 'Updates a single booking project identified by its uuid, if permitted for the current subject.' description: 'Updates a single booking project identified by its uuid, if permitted for the current subject.'
operationId: patchBookingProject operationId: patchBookingProject
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingProjectUuid - name: bookingProjectUuid
in: path in: path
@ -63,7 +63,7 @@ delete:
description: 'Delete a single booking project identified by its uuid, if permitted for the current subject.' description: 'Delete a single booking project identified by its uuid, if permitted for the current subject.'
operationId: deleteBookingIemByUuid operationId: deleteBookingIemByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bookingProjectUuid - name: bookingProjectUuid
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-booking-projects - hs-booking-projects
operationId: listBookingProjectsByDebitorUuid operationId: listBookingProjectsByDebitorUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: debitorUuid - name: debitorUuid
in: query in: query
@ -34,7 +34,7 @@ post:
- hs-booking-projects - hs-booking-projects
operationId: addBookingProject operationId: addBookingProject
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
description: A JSON object describing the new booking project. description: A JSON object describing the new booking project.

View File

@ -3,8 +3,8 @@ components:
parameters: parameters:
currentUser: currentSubject:
name: current-user name: current-subject
in: header in: header
required: true required: true
schema: schema:

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single managed asset by its uuid, if visible for the current subject.' description: 'Fetch a single managed asset by its uuid, if visible for the current subject.'
operationId: getAssetByUuid operationId: getAssetByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: assetUuid - name: assetUuid
in: path in: path
@ -32,7 +32,7 @@ patch:
description: 'Updates a single hosting asset identified by its uuid, if permitted for the current subject.' description: 'Updates a single hosting asset identified by its uuid, if permitted for the current subject.'
operationId: patchAsset operationId: patchAsset
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: assetUuid - name: assetUuid
in: path in: path
@ -63,7 +63,7 @@ delete:
description: 'Delete a single hosting asset identified by its uuid, if permitted for the current subject.' description: 'Delete a single hosting asset identified by its uuid, if permitted for the current subject.'
operationId: deleteAssetUuid operationId: deleteAssetUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: assetUuid - name: assetUuid
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-hosting-assets - hs-hosting-assets
operationId: listAssets operationId: listAssets
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: projectUuid - name: projectUuid
in: query in: query
@ -47,7 +47,7 @@ post:
- hs-hosting-assets - hs-hosting-assets
operationId: addAsset operationId: addAsset
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
description: A JSON object describing the new hosting asset. description: A JSON object describing the new hosting asset.

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single bank account by its uuid, if visible for the current subject.' description: 'Fetch a single bank account by its uuid, if visible for the current subject.'
operationId: getBankAccountByUuid operationId: getBankAccountByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bankAccountUUID - name: bankAccountUUID
in: path in: path
@ -31,7 +31,7 @@ delete:
description: 'Delete a single bank account by its uuid, if permitted for the current subject.' description: 'Delete a single bank account by its uuid, if permitted for the current subject.'
operationId: deleteBankAccountByUuid operationId: deleteBankAccountByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: bankAccountUUID - name: bankAccountUUID
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-office-bank-accounts - hs-office-bank-accounts
operationId: listBankAccounts operationId: listBankAccounts
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: holder - name: holder
in: query in: query
@ -33,7 +33,7 @@ post:
- hs-office-bank-accounts - hs-office-bank-accounts
operationId: addBankAccount operationId: addBankAccount
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
content: content:

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single business contact by its uuid, if visible for the current subject.' description: 'Fetch a single business contact by its uuid, if visible for the current subject.'
operationId: getContactByUuid operationId: getContactByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: contactUUID - name: contactUUID
in: path in: path
@ -32,7 +32,7 @@ patch:
description: 'Updates a single contact by its uuid, if permitted for the current subject.' description: 'Updates a single contact by its uuid, if permitted for the current subject.'
operationId: patchContact operationId: patchContact
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: contactUUID - name: contactUUID
in: path in: path
@ -63,7 +63,7 @@ delete:
description: 'Delete a single business contact by its uuid, if permitted for the current subject.' description: 'Delete a single business contact by its uuid, if permitted for the current subject.'
operationId: deleteContactByUuid operationId: deleteContactByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: contactUUID - name: contactUUID
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-office-contacts - hs-office-contacts
operationId: listContacts operationId: listContacts
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name - name: name
in: query in: query
@ -33,7 +33,7 @@ post:
- hs-office-contacts - hs-office-contacts
operationId: addContact operationId: addContact
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
content: content:

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single asset transaction by its uuid, if visible for the current subject.' description: 'Fetch a single asset transaction by its uuid, if visible for the current subject.'
operationId: getCoopAssetTransactionByUuid operationId: getCoopAssetTransactionByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: assetTransactionUUID - name: assetTransactionUUID
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-office-coopAssets - hs-office-coopAssets
operationId: listCoopAssets operationId: listCoopAssets
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: membershipUuid - name: membershipUuid
in: query in: query
@ -48,7 +48,7 @@ post:
- hs-office-coopAssets - hs-office-coopAssets
operationId: addCoopAssetsTransaction operationId: addCoopAssetsTransaction
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
description: A JSON object describing the new cooperative assets transaction. description: A JSON object describing the new cooperative assets transaction.

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single share transaction by its uuid, if visible for the current subject.' description: 'Fetch a single share transaction by its uuid, if visible for the current subject.'
operationId: getCoopShareTransactionByUuid operationId: getCoopShareTransactionByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: shareTransactionUUID - name: shareTransactionUUID
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-office-coopShares - hs-office-coopShares
operationId: listCoopShares operationId: listCoopShares
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: membershipUuid - name: membershipUuid
in: query in: query
@ -48,7 +48,7 @@ post:
- hs-office-coopShares - hs-office-coopShares
operationId: addCoopSharesTransaction operationId: addCoopSharesTransaction
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
description: A JSON object describing the new cooperative shares transaction. description: A JSON object describing the new cooperative shares transaction.

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single debitor by its uuid, if visible for the current subject.' description: 'Fetch a single debitor by its uuid, if visible for the current subject.'
operationId: getDebitorByUuid operationId: getDebitorByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: debitorUUID - name: debitorUUID
in: path in: path
@ -32,7 +32,7 @@ patch:
description: 'Updates a single debitor by its uuid, if permitted for the current subject.' description: 'Updates a single debitor by its uuid, if permitted for the current subject.'
operationId: patchDebitor operationId: patchDebitor
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: debitorUUID - name: debitorUUID
in: path in: path
@ -63,7 +63,7 @@ delete:
description: 'Delete a single debitor by its uuid, if permitted for the current subject.' description: 'Delete a single debitor by its uuid, if permitted for the current subject.'
operationId: deleteDebitorByUuid operationId: deleteDebitorByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: debitorUUID - name: debitorUUID
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-office-debitors - hs-office-debitors
operationId: listDebitors operationId: listDebitors
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name - name: name
in: query in: query
@ -39,7 +39,7 @@ post:
- hs-office-debitors - hs-office-debitors
operationId: addDebitor operationId: addDebitor
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
content: content:

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single membership by its uuid, if visible for the current subject.' description: 'Fetch a single membership by its uuid, if visible for the current subject.'
operationId: getMembershipByUuid operationId: getMembershipByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: membershipUUID - name: membershipUUID
in: path in: path
@ -32,7 +32,7 @@ patch:
description: 'Updates a single membership by its uuid, if permitted for the current subject.' description: 'Updates a single membership by its uuid, if permitted for the current subject.'
operationId: patchMembership operationId: patchMembership
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: membershipUUID - name: membershipUUID
in: path in: path
@ -63,7 +63,7 @@ delete:
description: 'Delete a single membership by its uuid, if permitted for the current subject.' description: 'Delete a single membership by its uuid, if permitted for the current subject.'
operationId: deleteMembershipByUuid operationId: deleteMembershipByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: membershipUUID - name: membershipUUID
in: path in: path

View File

@ -6,7 +6,7 @@ get:
- hs-office-memberships - hs-office-memberships
operationId: listMemberships operationId: listMemberships
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: partnerUuid - name: partnerUuid
in: query in: query
@ -41,7 +41,7 @@ post:
- hs-office-memberships - hs-office-memberships
operationId: addMembership operationId: addMembership
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
description: A JSON object describing the new membership. description: A JSON object describing the new membership.

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single business partner by its uuid, if visible for the current subject.' description: 'Fetch a single business partner by its uuid, if visible for the current subject.'
operationId: getPartnerByUuid operationId: getPartnerByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: partnerUUID - name: partnerUUID
in: path in: path
@ -32,7 +32,7 @@ patch:
description: 'Updates a single business partner by its uuid, if permitted for the current subject.' description: 'Updates a single business partner by its uuid, if permitted for the current subject.'
operationId: patchPartner operationId: patchPartner
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: partnerUUID - name: partnerUUID
in: path in: path
@ -63,7 +63,7 @@ delete:
description: 'Delete a single business partner by its uuid, if permitted for the current subject.' description: 'Delete a single business partner by its uuid, if permitted for the current subject.'
operationId: deletePartnerByUuid operationId: deletePartnerByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: partnerUUID - name: partnerUUID
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-office-partners - hs-office-partners
operationId: listPartners operationId: listPartners
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name - name: name
in: query in: query
@ -33,7 +33,7 @@ post:
- hs-office-partners - hs-office-partners
operationId: addPartner operationId: addPartner
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
content: content:

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single business person by its uuid, if visible for the current subject.' description: 'Fetch a single business person by its uuid, if visible for the current subject.'
operationId: getPersonByUuid operationId: getPersonByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: personUUID - name: personUUID
in: path in: path
@ -32,7 +32,7 @@ patch:
description: 'Updates a single person by its uuid, if permitted for the current subject.' description: 'Updates a single person by its uuid, if permitted for the current subject.'
operationId: patchPerson operationId: patchPerson
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: personUUID - name: personUUID
in: path in: path
@ -63,7 +63,7 @@ delete:
description: 'Delete a single business person by its uuid, if permitted for the current subject.' description: 'Delete a single business person by its uuid, if permitted for the current subject.'
operationId: deletePersonByUuid operationId: deletePersonByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: personUUID - name: personUUID
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-office-persons - hs-office-persons
operationId: listPersons operationId: listPersons
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name - name: name
in: query in: query
@ -33,7 +33,7 @@ post:
- hs-office-persons - hs-office-persons
operationId: addPerson operationId: addPerson
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
content: content:

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single person relation by its uuid, if visible for the current subject.' description: 'Fetch a single person relation by its uuid, if visible for the current subject.'
operationId: getRelationByUuid operationId: getRelationByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: relationUUID - name: relationUUID
in: path in: path
@ -32,7 +32,7 @@ patch:
description: 'Updates a single person relation by its uuid, if permitted for the current subject.' description: 'Updates a single person relation by its uuid, if permitted for the current subject.'
operationId: patchRelation operationId: patchRelation
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: relationUUID - name: relationUUID
in: path in: path
@ -63,7 +63,7 @@ delete:
description: 'Delete a single person relation by its uuid, if permitted for the current subject.' description: 'Delete a single person relation by its uuid, if permitted for the current subject.'
operationId: deleteRelationByUuid operationId: deleteRelationByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: relationUUID - name: relationUUID
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-office-relations - hs-office-relations
operationId: listRelations operationId: listRelations
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: personUuid - name: personUuid
in: query in: query
@ -40,7 +40,7 @@ post:
- hs-office-relations - hs-office-relations
operationId: addRelation operationId: addRelation
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
content: content:

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single SEPA Mandate by its uuid, if visible for the current subject.' description: 'Fetch a single SEPA Mandate by its uuid, if visible for the current subject.'
operationId: getSepaMandateByUuid operationId: getSepaMandateByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: sepaMandateUUID - name: sepaMandateUUID
in: path in: path
@ -32,7 +32,7 @@ patch:
description: 'Updates a single SEPA Mandate by its uuid, if permitted for the current subject.' description: 'Updates a single SEPA Mandate by its uuid, if permitted for the current subject.'
operationId: patchSepaMandate operationId: patchSepaMandate
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: sepaMandateUUID - name: sepaMandateUUID
in: path in: path
@ -63,7 +63,7 @@ delete:
description: 'Delete a single SEPA Mandate by its uuid, if permitted for the current subject.' description: 'Delete a single SEPA Mandate by its uuid, if permitted for the current subject.'
operationId: deleteSepaMandateByUuid operationId: deleteSepaMandateByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: sepaMandateUUID - name: sepaMandateUUID
in: path in: path

View File

@ -5,7 +5,7 @@ get:
- hs-office-sepaMandates - hs-office-sepaMandates
operationId: listSepaMandatesByIBAN operationId: listSepaMandatesByIBAN
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name - name: name
in: query in: query
@ -33,7 +33,7 @@ post:
- hs-office-sepaMandates - hs-office-sepaMandates
operationId: addSepaMandate operationId: addSepaMandate
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
description: A JSON object describing the new SEPA-Mandate. description: A JSON object describing the new SEPA-Mandate.

View File

@ -3,7 +3,7 @@ get:
- rbac-grants - rbac-grants
operationId: getGrantById operationId: getGrantById
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: grantedRoleUuid - name: grantedRoleUuid
in: path in: path
@ -38,7 +38,7 @@ delete:
- rbac-grants - rbac-grants
operationId: revokeRoleFromUser operationId: revokeRoleFromUser
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: grantedRoleUuid - name: grantedRoleUuid
in: path in: path

View File

@ -3,7 +3,7 @@ get:
- rbac-grants - rbac-grants
operationId: listUserGrants operationId: listUserGrants
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
responses: responses:
"200": "200":
@ -20,7 +20,7 @@ post:
- rbac-grants - rbac-grants
operationId: grantRoleToUser operationId: grantRoleToUser
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
required: true required: true

View File

@ -3,7 +3,7 @@ get:
- rbac-roles - rbac-roles
operationId: listRoles operationId: listRoles
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
responses: responses:
"200": "200":

View File

@ -4,7 +4,7 @@ get:
description: 'List all visible permissions granted to the given user; reduced ' description: 'List all visible permissions granted to the given user; reduced '
operationId: listUserPermissions operationId: listUserPermissions
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: userUuid - name: userUuid
in: path in: path

View File

@ -4,7 +4,7 @@ get:
description: 'Fetch a single user by its id, if visible for the current subject.' description: 'Fetch a single user by its id, if visible for the current subject.'
operationId: getUserById operationId: getUserById
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: userUuid - name: userUuid
in: path in: path
@ -31,7 +31,7 @@ delete:
- rbac-users - rbac-users
operationId: deleteUserByUuid operationId: deleteUserByUuid
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: userUuid - name: userUuid
in: path in: path

View File

@ -4,7 +4,7 @@ get:
description: List accessible RBAC users with optional filter by name. description: List accessible RBAC users with optional filter by name.
operationId: listUsers operationId: listUsers
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name - name: name
in: query in: query

View File

@ -5,7 +5,7 @@ get:
- testCustomers - testCustomers
operationId: listCustomers operationId: listCustomers
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: prefix - name: prefix
in: query in: query
@ -33,7 +33,7 @@ post:
- testCustomers - testCustomers
operationId: addCustomer operationId: addCustomer
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
requestBody: requestBody:
content: content:

View File

@ -3,7 +3,7 @@ patch:
- testPackages - testPackages
operationId: updatePackage operationId: updatePackage
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: packageUUID - name: packageUUID
in: path in: path

View File

@ -3,7 +3,7 @@ get:
- testPackages - testPackages
operationId: listPackages operationId: listPackages
parameters: parameters:
- $ref: 'auth.yaml#/components/parameters/currentUser' - $ref: 'auth.yaml#/components/parameters/currentSubject'
- $ref: 'auth.yaml#/components/parameters/assumedRoles' - $ref: 'auth.yaml#/components/parameters/assumedRoles'
- name: name - name: name
in: query in: query

View File

@ -2,7 +2,7 @@
-- ============================================================================ -- ============================================================================
--changeset basis-schema:1 endDelimiter:--// --changeset basis-SCHEMA:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
CREATE SCHEMA basis; CREATE SCHEMA basis;
--// --//

View File

@ -12,7 +12,7 @@
create procedure basis.contextDefined( create procedure basis.contextDefined(
currentTask varchar(127), currentTask varchar(127),
currentRequest text, currentRequest text,
currentUser varchar(63), currentSubject varchar(63),
assumedRoles varchar(1023) assumedRoles varchar(1023)
) )
language plpgsql as $$ language plpgsql as $$
@ -25,7 +25,7 @@ end; $$;
create or replace procedure basis.defineContext( create or replace procedure basis.defineContext(
currentTask varchar(127), currentTask varchar(127),
currentRequest text = null, currentRequest text = null,
currentUser varchar(63) = null, currentSubject varchar(63) = null,
assumedRoles varchar(1023) = null assumedRoles varchar(1023) = null
) )
language plpgsql as $$ language plpgsql as $$
@ -38,15 +38,15 @@ begin
currentRequest := coalesce(currentRequest, ''); currentRequest := coalesce(currentRequest, '');
execute format('set local hsadminng.currentRequest to %L', currentRequest); execute format('set local hsadminng.currentRequest to %L', currentRequest);
currentUser := coalesce(currentUser, ''); currentSubject := coalesce(currentSubject, '');
assert length(currentUser) <= 63, FORMAT('currentUser must not be longer than 63 characters: "%s"', currentUser); assert length(currentSubject) <= 63, FORMAT('currentSubject must not be longer than 63 characters: "%s"', currentSubject);
execute format('set local hsadminng.currentUser to %L', currentUser); execute format('set local hsadminng.currentSubject to %L', currentSubject);
assumedRoles := coalesce(assumedRoles, ''); assumedRoles := coalesce(assumedRoles, '');
assert length(assumedRoles) <= 1023, FORMAT('assumedRoles must not be longer than 1023 characters: "%s"', assumedRoles); assert length(assumedRoles) <= 1023, FORMAT('assumedRoles must not be longer than 1023 characters: "%s"', assumedRoles);
execute format('set local hsadminng.assumedRoles to %L', assumedRoles); execute format('set local hsadminng.assumedRoles to %L', assumedRoles);
call basis.contextDefined(currentTask, currentRequest, currentUser, assumedRoles); call basis.contextDefined(currentTask, currentRequest, currentSubject, assumedRoles);
end; $$; end; $$;
--// --//
@ -105,25 +105,25 @@ end; $$;
-- ============================================================================ -- ============================================================================
--changeset context-CURRENT-USER:1 endDelimiter:--// --changeset context-current-subject:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
Returns the current user as defined by `basis.defineContext(...)`. Returns the current user as defined by `basis.defineContext(...)`.
*/ */
create or replace function basis.currentUser() create or replace function basis.currentSubject() -- FIXME: move to schema rbac?
returns varchar(63) returns varchar(63)
stable -- leakproof stable -- leakproof
language plpgsql as $$ language plpgsql as $$
declare declare
currentUser varchar(63); currentSubject varchar(63);
begin begin
begin begin
currentUser := current_setting('hsadminng.currentUser'); currentSubject := current_setting('hsadminng.currentSubject');
exception exception
when others then when others then
currentUser := null; currentSubject := null;
end; end;
return currentUser; return currentSubject;
end; $$; end; $$;
--// --//
@ -217,7 +217,7 @@ begin
if array_length(assumedRoles, 1) > 0 then if array_length(assumedRoles, 1) > 0 then
return assumedRoles; return assumedRoles;
else else
return array [basis.currentUser()]::varchar(1023)[]; return array [basis.currentSubject()]::varchar(1023)[];
end if; end if;
end; $$; end; $$;

View File

@ -25,7 +25,7 @@ create table basis.tx_context
( (
txId xid8 primary key not null, txId xid8 primary key not null,
txTimestamp timestamp not null, txTimestamp timestamp not null,
currentUser varchar(63) not null, -- not the uuid, because users can be deleted currentSubject varchar(63) not null, -- not the uuid, because users can be deleted
assumedRoles varchar(1023) not null, -- not the uuids, because roles can be deleted assumedRoles varchar(1023) not null, -- not the uuids, because roles can be deleted
currentTask varchar(127) not null, currentTask varchar(127) not null,
currentRequest text not null currentRequest text not null
@ -82,9 +82,9 @@ begin
curTxId := pg_current_xact_id(); curTxId := pg_current_xact_id();
insert insert
into basis.tx_context (txId, txTimestamp, currentUser, assumedRoles, currentTask, currentRequest) into basis.tx_context (txId, txTimestamp, currentSubject, assumedRoles, currentTask, currentRequest)
values ( curTxId, now(), values ( curTxId, now(),
basis.currentUser(), basis.assumedRoles(), curTask, basis.currentRequest()) basis.currentSubject(), basis.assumedRoles(), curTask, basis.currentRequest())
on conflict do nothing; on conflict do nothing;
case tg_op case tg_op
@ -123,7 +123,7 @@ declare
begin begin
targetTable := lower(targetTable); targetTable := lower(targetTable);
createTriggerSQL = 'CREATE TRIGGER ' || targetTable || '_journal' || createTriggerSQL = 'CREATE TRIGGER tx_journal_tg' ||
' AFTER INSERT OR UPDATE OR DELETE ON ' || targetTable || ' AFTER INSERT OR UPDATE OR DELETE ON ' || targetTable ||
' FOR EACH ROW EXECUTE PROCEDURE basis.tx_journal_trigger()'; ' FOR EACH ROW EXECUTE PROCEDURE basis.tx_journal_trigger()';
execute createTriggerSQL; execute createTriggerSQL;

View File

@ -47,7 +47,7 @@ create or replace function tx_historicize_tf()
language plpgsql language plpgsql
strict as $$ strict as $$
declare declare
currentUser varchar(63); currentSubject varchar(63);
currentTask varchar(127); currentTask varchar(127);
"row" record; "row" record;
"alive" boolean; "alive" boolean;
@ -55,15 +55,15 @@ declare
begin begin
-- determine user_id -- determine user_id
begin begin
currentUser := current_setting('hsadminng.currentUser'); currentSubject := current_setting('hsadminng.currentSubject');
exception exception
when others then when others then
currentUser := null; currentSubject := null;
end; end;
if (currentUser is null or currentUser = '') then if (currentSubject is null or currentSubject = '') then
raise exception 'hsadminng.currentUser must be defined, please use "SET LOCAL ...;"'; raise exception 'hsadminng.currentSubject must be defined, please use "SET LOCAL ...;"';
end if; end if;
raise notice 'currentUser: %', currentUser; raise notice 'currentSubject: %', currentSubject;
-- determine task -- determine task
currentTask = current_setting('hsadminng.currentTask'); currentTask = current_setting('hsadminng.currentTask');

View File

@ -0,0 +1,8 @@
--liquibase formatted sql
-- ============================================================================
--changeset rbac-SCHEMA:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
CREATE SCHEMA rbac;
--//

View File

@ -6,25 +6,25 @@
/* /*
*/ */
create type ReferenceType as enum ('RbacUser', 'RbacRole', 'RbacPermission'); create type rbac.referenceType as enum ('rbac.subject', 'RbacRole', 'RbacPermission');
create table RbacReference create table rbac.reference
( (
uuid uuid unique default uuid_generate_v4(), uuid uuid unique default uuid_generate_v4(),
type ReferenceType not null type rbac.referenceType not null
); );
create or replace function assertReferenceType(argument varchar, referenceId uuid, expectedType ReferenceType) create or replace function rbac.assertReferenceType(argument varchar, referenceId uuid, expectedType rbac.referenceType)
returns ReferenceType returns rbac.referenceType
language plpgsql as $$ language plpgsql as $$
declare declare
actualType ReferenceType; actualType rbac.referenceType;
begin begin
if referenceId is null then if referenceId is null then
raise exception '% must be a % and not null', argument, expectedType; raise exception '% must be a % and not null', argument, expectedType;
end if; end if;
actualType = (select type from RbacReference where uuid = referenceId); actualType = (select type from rbac.reference where uuid = referenceId);
if (actualType <> expectedType) then if (actualType <> expectedType) then
raise exception '% must reference a %, but got a %', argument, expectedType, actualType; raise exception '% must reference a %, but got a %', argument, expectedType, actualType;
end if; end if;
@ -33,20 +33,20 @@ end; $$;
--// --//
-- ============================================================================ -- ============================================================================
--changeset rbac-base-USER:1 endDelimiter:--// --changeset rbac-base-SUBJECT:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
*/ */
create table RbacUser create table rbac.subject
( (
uuid uuid primary key references RbacReference (uuid) on delete cascade, uuid uuid primary key references rbac.reference (uuid) on delete cascade,
name varchar(63) not null unique name varchar(63) not null unique
); );
call basis.create_journal('RbacUser'); call basis.create_journal('rbac.subject');
create or replace function createRbacUser(userName varchar) create or replace function rbac.create_subject(subjectName varchar)
returns uuid returns uuid
returns null on null input returns null on null input
language plpgsql as $$ language plpgsql as $$
@ -54,37 +54,37 @@ declare
objectId uuid; objectId uuid;
begin begin
insert insert
into RbacReference (type) into rbac.reference (type)
values ('RbacUser') values ('rbac.subject')
returning uuid into objectId; returning uuid into objectId;
insert insert
into RbacUser (uuid, name) into rbac.subject (uuid, name)
values (objectid, userName); values (objectid, subjectName);
return objectId; return objectId;
end; end;
$$; $$;
create or replace function createRbacUser(refUuid uuid, userName varchar) create or replace function rbac.create_subject(refUuid uuid, subjectName varchar)
returns uuid returns uuid
called on null input called on null input
language plpgsql as $$ language plpgsql as $$
begin begin
insert insert
into RbacReference as r (uuid, type) into rbac.reference as r (uuid, type)
values (coalesce(refUuid, uuid_generate_v4()), 'RbacUser') values (coalesce(refUuid, uuid_generate_v4()), 'rbac.subject')
returning r.uuid into refUuid; returning r.uuid into refUuid;
insert insert
into RbacUser (uuid, name) into rbac.subject (uuid, name)
values (refUuid, userName); values (refUuid, subjectName);
return refUuid; return refUuid;
end; end;
$$; $$;
create or replace function findRbacUserId(userName varchar) create or replace function rbac.find_subject_id(subjectName varchar)
returns uuid returns uuid
returns null on null input returns null on null input
language sql as $$ language sql as $$
select uuid from RbacUser where name = userName select uuid from rbac.subject where name = subjectName
$$; $$;
--// --//
@ -94,7 +94,7 @@ $$;
/* /*
*/ */
create table RbacObject create table rbac.object
( (
uuid uuid primary key default uuid_generate_v4(), uuid uuid primary key default uuid_generate_v4(),
serialId serial, -- TODO.perf: only needed for reverse deletion of temp test data serialId serial, -- TODO.perf: only needed for reverse deletion of temp test data
@ -102,7 +102,7 @@ create table RbacObject
unique (objectTable, uuid) unique (objectTable, uuid)
); );
call basis.create_journal('RbacObject'); call basis.create_journal('rbac.object');
--// --//
@ -112,9 +112,9 @@ call basis.create_journal('RbacObject');
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
Inserts related RbacObject for use in the BEFORE ONSERT TRIGGERs on the business objects. Inserts related rbac.object for use in the BEFORE INSERT TRIGGERs on the business objects.
*/ */
create or replace function insertRelatedRbacObject() create or replace function rbac.insert_related_object()
returns trigger returns trigger
language plpgsql language plpgsql
strict as $$ strict as $$
@ -124,13 +124,13 @@ begin
if TG_OP = 'INSERT' then if TG_OP = 'INSERT' then
if NEW.uuid is null then if NEW.uuid is null then
insert insert
into RbacObject (objectTable) into rbac.object (objectTable)
values (TG_TABLE_NAME) values (TG_TABLE_NAME)
returning uuid into objectUuid; returning uuid into objectUuid;
NEW.uuid = objectUuid; NEW.uuid = objectUuid;
else else
insert insert
into RbacObject (uuid, objectTable) into rbac.object (uuid, objectTable)
values (NEW.uuid, TG_TABLE_NAME) values (NEW.uuid, TG_TABLE_NAME)
returning uuid into objectUuid; returning uuid into objectUuid;
end if; end if;
@ -141,7 +141,7 @@ begin
end; $$; end; $$;
/* /*
Deletes related RbacObject for use in the BEFORE DELETE TRIGGERs on the business objects. Deletes related rbac.object for use in the BEFORE DELETE TRIGGERs on the business objects.
*/ */
create or replace function deleteRelatedRbacObject() create or replace function deleteRelatedRbacObject()
returns trigger returns trigger
@ -149,7 +149,7 @@ create or replace function deleteRelatedRbacObject()
strict as $$ strict as $$
begin begin
if TG_OP = 'DELETE' then if TG_OP = 'DELETE' then
delete from RbacObject where rbacobject.uuid = old.uuid; delete from rbac.object where rbac.object.uuid = old.uuid;
else else
raise exception 'invalid usage of TRIGGER BEFORE DELETE'; raise exception 'invalid usage of TRIGGER BEFORE DELETE';
end if; end if;
@ -168,8 +168,8 @@ create type RbacRoleType as enum ('OWNER', 'ADMIN', 'AGENT', 'TENANT', 'GUEST',
create table RbacRole create table RbacRole
( (
uuid uuid primary key references RbacReference (uuid) on delete cascade initially deferred, -- initially deferred uuid uuid primary key references rbac.reference (uuid) on delete cascade initially deferred, -- initially deferred
objectUuid uuid not null references RbacObject (uuid) initially deferred, objectUuid uuid not null references rbac.object (uuid) initially deferred,
roleType RbacRoleType not null, roleType RbacRoleType not null,
unique (objectUuid, roleType) unique (objectUuid, roleType)
); );
@ -217,7 +217,7 @@ declare
referenceId uuid; referenceId uuid;
begin begin
insert insert
into RbacReference (type) into rbac.reference (type)
values ('RbacRole') values ('RbacRole')
returning uuid into referenceId; returning uuid into referenceId;
insert insert
@ -231,7 +231,7 @@ $$;
create or replace procedure deleteRole(roleUUid uuid) create or replace procedure deleteRole(roleUUid uuid)
language plpgsql as $$ language plpgsql as $$
begin begin
--raise exception '% deleting role uuid %', currentsubjectsuuids(), roleUUid; --raise exception '% deleting role uuid %', rbac.currentSubjectOrAssumedRolesUuids(), roleUUid;
delete from RbacRole where uuid = roleUUid; delete from RbacRole where uuid = roleUUid;
end; end;
$$; $$;
@ -323,7 +323,7 @@ execute procedure deleteRbacGrantsOfRbacRole();
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
RbacObject BEFORE DELETE TRIGGER function which deletes all related roles. rbac.object BEFORE DELETE TRIGGER function which deletes all related roles.
*/ */
create or replace function deleteRbacRolesOfRbacObject() create or replace function deleteRbacRolesOfRbacObject()
returns trigger returns trigger
@ -344,7 +344,7 @@ end; $$;
*/ */
create trigger deleteRbacRolesOfRbacObject_Trigger create trigger deleteRbacRolesOfRbacObject_Trigger
before delete before delete
on RbacObject on rbac.object
for each row for each row
execute procedure deleteRbacRolesOfRbacObject(); execute procedure deleteRbacRolesOfRbacObject();
--// --//
@ -367,8 +367,8 @@ create domain RbacOp as varchar(6)
create table RbacPermission create table RbacPermission
( (
uuid uuid primary key references RbacReference (uuid) on delete cascade, uuid uuid primary key references rbac.reference (uuid) on delete cascade,
objectUuid uuid not null references RbacObject, objectUuid uuid not null references rbac.object,
op RbacOp not null, op RbacOp not null,
opTableName varchar(60) opTableName varchar(60)
); );
@ -402,7 +402,7 @@ begin
where objectUuid = forObjectUuid where objectUuid = forObjectUuid
and op = forOp and opTableName is not distinct from forOpTableName); and op = forOp and opTableName is not distinct from forOpTableName);
if (permissionUuid is null) then if (permissionUuid is null) then
insert into RbacReference ("type") insert into rbac.reference ("type")
values ('RbacPermission') values ('RbacPermission')
returning uuid into permissionUuid; returning uuid into permissionUuid;
begin begin
@ -482,15 +482,15 @@ $$;
--changeset rbac-base-GRANTS:1 endDelimiter:--// --changeset rbac-base-GRANTS:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
Table to store grants / role- or permission assignments to users or roles. Table to store grants / role- or permission assignments to subjects or roles.
*/ */
create table RbacGrants create table RbacGrants
( (
uuid uuid primary key default uuid_generate_v4(), uuid uuid primary key default uuid_generate_v4(),
grantedByTriggerOf uuid references RbacObject (uuid) on delete cascade initially deferred , grantedByTriggerOf uuid references rbac.object (uuid) on delete cascade initially deferred ,
grantedByRoleUuid uuid references RbacRole (uuid), grantedByRoleUuid uuid references RbacRole (uuid),
ascendantUuid uuid references RbacReference (uuid), ascendantUuid uuid references rbac.reference (uuid),
descendantUuid uuid references RbacReference (uuid), descendantUuid uuid references rbac.reference (uuid),
assumed boolean not null default true, -- auto assumed (true) vs. needs assumeRoles (false) assumed boolean not null default true, -- auto assumed (true) vs. needs assumeRoles (false)
unique (ascendantUuid, descendantUuid), unique (ascendantUuid, descendantUuid),
constraint rbacGrant_createdBy check ( grantedByRoleUuid is null or grantedByTriggerOf is null) ); constraint rbacGrant_createdBy check ( grantedByRoleUuid is null or grantedByTriggerOf is null) );
@ -499,7 +499,7 @@ create index on RbacGrants (descendantUuid);
call basis.create_journal('RbacGrants'); call basis.create_journal('RbacGrants');
create or replace function findGrantees(grantedId uuid) create or replace function findGrantees(grantedId uuid)
returns setof RbacReference returns setof rbac.reference
returns null on null input returns null on null input
language sql as $$ language sql as $$
with recursive grants as ( with recursive grants as (
@ -513,7 +513,7 @@ with recursive grants as (
) )
select ref.* select ref.*
from grants from grants
join RbacReference ref on ref.uuid = grants.ascendantUuid; join rbac.reference ref on ref.uuid = grants.ascendantUuid;
$$; $$;
create or replace function isGranted(granteeIds uuid[], grantedId uuid) create or replace function isGranted(granteeIds uuid[], grantedId uuid)
@ -574,7 +574,7 @@ begin
end; end;
$$; $$;
create or replace function hasGlobalRoleGranted(userUuid uuid) create or replace function hasGlobalRoleGranted(forAscendantUuid uuid)
returns bool returns bool
stable -- leakproof stable -- leakproof
language sql as $$ language sql as $$
@ -582,8 +582,8 @@ select exists(
select r.uuid select r.uuid
from RbacGrants as g from RbacGrants as g
join RbacRole as r on r.uuid = g.descendantuuid join RbacRole as r on r.uuid = g.descendantuuid
join RbacObject as o on o.uuid = r.objectuuid join rbac.object as o on o.uuid = r.objectuuid
where g.ascendantuuid = userUuid where g.ascendantuuid = forAscendantUuid
and o.objecttable = 'global' and o.objecttable = 'global'
); );
$$; $$;
@ -591,8 +591,8 @@ $$;
create or replace procedure grantPermissionToRole(permissionUuid uuid, roleUuid uuid) create or replace procedure grantPermissionToRole(permissionUuid uuid, roleUuid uuid)
language plpgsql as $$ language plpgsql as $$
begin begin
perform assertReferenceType('roleId (ascendant)', roleUuid, 'RbacRole'); perform rbac.assertReferenceType('roleId (ascendant)', roleUuid, 'RbacRole');
perform assertReferenceType('permissionId (descendant)', permissionUuid, 'RbacPermission'); perform rbac.assertReferenceType('permissionId (descendant)', permissionUuid, 'RbacPermission');
insert insert
into RbacGrants (grantedByTriggerOf, ascendantUuid, descendantUuid, assumed) into RbacGrants (grantedByTriggerOf, ascendantUuid, descendantUuid, assumed)
@ -611,8 +611,8 @@ $$;
create or replace procedure grantRoleToRole(subRoleId uuid, superRoleId uuid, doAssume bool = true) create or replace procedure grantRoleToRole(subRoleId uuid, superRoleId uuid, doAssume bool = true)
language plpgsql as $$ language plpgsql as $$
begin begin
perform assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole'); perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole');
perform assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole'); perform rbac.assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole');
if isGranted(subRoleId, superRoleId) then if isGranted(subRoleId, superRoleId) then
call raiseDuplicateRoleGrantException(subRoleId, superRoleId); call raiseDuplicateRoleGrantException(subRoleId, superRoleId);
@ -639,8 +639,8 @@ begin
superRoleId := findRoleId(superRole); superRoleId := findRoleId(superRole);
subRoleId := findRoleId(subRole); subRoleId := findRoleId(subRole);
perform assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole'); perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole');
perform assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole'); perform rbac.assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole');
if isGranted(subRoleId, superRoleId) then if isGranted(subRoleId, superRoleId) then
call raiseDuplicateRoleGrantException(subRoleId, superRoleId); call raiseDuplicateRoleGrantException(subRoleId, superRoleId);
@ -661,8 +661,8 @@ begin
superRoleId := findRoleId(superRole); superRoleId := findRoleId(superRole);
subRoleId := findRoleId(subRole); subRoleId := findRoleId(subRole);
perform assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole'); perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole');
perform assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole'); perform rbac.assertReferenceType('subRoleId (descendant)', subRoleId, 'RbacRole');
if (isGranted(superRoleId, subRoleId)) then if (isGranted(superRoleId, subRoleId)) then
delete from RbacGrants where ascendantUuid = superRoleId and descendantUuid = subRoleId; delete from RbacGrants where ascendantUuid = superRoleId and descendantUuid = subRoleId;
@ -682,8 +682,8 @@ declare
begin begin
superRoleId := findRoleId(superRole); superRoleId := findRoleId(superRole);
perform assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole'); perform rbac.assertReferenceType('superRoleId (ascendant)', superRoleId, 'RbacRole');
perform assertReferenceType('permission (descendant)', permissionId, 'RbacPermission'); perform rbac.assertReferenceType('permission (descendant)', permissionId, 'RbacPermission');
if (isGranted(superRoleId, permissionId)) then if (isGranted(superRoleId, permissionId)) then
delete from RbacGrants where ascendantUuid = superRoleId and descendantUuid = permissionId; delete from RbacGrants where ascendantUuid = superRoleId and descendantUuid = permissionId;
@ -691,7 +691,7 @@ begin
select p.op, o.objectTable, o.uuid select p.op, o.objectTable, o.uuid
from rbacGrants g from rbacGrants g
join rbacPermission p on p.uuid=g.descendantUuid join rbacPermission p on p.uuid=g.descendantUuid
join rbacobject o on o.uuid=p.objectUuid join rbac.object o on o.uuid=p.objectUuid
where g.uuid=permissionId where g.uuid=permissionId
into permissionOp, objectTable, objectUuid; into permissionOp, objectTable, objectUuid;
@ -736,7 +736,7 @@ begin
SELECT DISTINCT perm.objectUuid SELECT DISTINCT perm.objectUuid
FROM granted FROM granted
JOIN RbacPermission perm ON granted.descendantUuid = perm.uuid JOIN RbacPermission perm ON granted.descendantUuid = perm.uuid
JOIN RbacObject obj ON obj.uuid = perm.objectUuid JOIN rbac.object obj ON obj.uuid = perm.objectUuid
WHERE (requiredOp = 'SELECT' OR perm.op = requiredOp) WHERE (requiredOp = 'SELECT' OR perm.op = requiredOp)
AND obj.objectTable = forObjectTable AND obj.objectTable = forObjectTable
LIMIT maxObjects+1; LIMIT maxObjects+1;
@ -756,7 +756,7 @@ $$;
--changeset rbac-base-QUERY-GRANTED-PERMISSIONS:1 endDelimiter:--// --changeset rbac-base-QUERY-GRANTED-PERMISSIONS:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
Returns all permissions accessible to the given subject UUID (user or role). Returns all permissions accessible to the given subject UUID (subject or role).
*/ */
create or replace function queryPermissionsGrantedToSubjectId(subjectId uuid) create or replace function queryPermissionsGrantedToSubjectId(subjectId uuid)
returns setof RbacPermission returns setof RbacPermission
@ -782,18 +782,18 @@ $$;
--// --//
-- ============================================================================ -- ============================================================================
--changeset rbac-base-QUERY-USERS-WITH-PERMISSION-FOR-OBJECT:1 endDelimiter:--// --changeset rbac-base-QUERY-SUBJECTS-WITH-PERMISSION-FOR-OBJECT:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
Returns all user UUIDs which have any permission for the given object UUID. Returns all subject UUIDs which have any permission for the given object UUID.
*/ */
create or replace function queryAllRbacUsersWithPermissionsFor(objectId uuid) create or replace function queryAllRbacSubjectsWithPermissionsFor(objectId uuid)
returns setof RbacUser returns setof rbac.subject
returns null on null input returns null on null input
language sql as $$ language sql as $$
select * select *
from RbacUser from rbac.subject
where uuid in ( where uuid in (
-- @formatter:off -- @formatter:off
with recursive grants as ( with recursive grants as (

View File

@ -9,23 +9,23 @@ create or replace function assumedRoleUuid()
stable -- leakproof stable -- leakproof
language plpgsql as $$ language plpgsql as $$
declare declare
currentSubjectsUuids uuid[]; currentSubjectOrAssumedRolesUuids uuid[];
begin begin
-- exactly one role must be assumed, not none not more than one -- exactly one role must be assumed, not none not more than one
if cardinality(basis.assumedRoles()) <> 1 then if cardinality(basis.assumedRoles()) <> 1 then
raise exception '[400] Granting roles to user is only possible if exactly one role is assumed, given: %', basis.assumedRoles(); raise exception '[400] Granting roles to user is only possible if exactly one role is assumed, given: %', basis.assumedRoles();
end if; end if;
currentSubjectsUuids := currentSubjectsUuids(); currentSubjectOrAssumedRolesUuids := rbac.currentSubjectOrAssumedRolesUuids();
return currentSubjectsUuids[1]; return currentSubjectOrAssumedRolesUuids[1];
end; $$; end; $$;
create or replace procedure grantRoleToUserUnchecked(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid, doAssume boolean = true) create or replace procedure grantRoleToUserUnchecked(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid, doAssume boolean = true)
language plpgsql as $$ language plpgsql as $$
begin begin
perform assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'RbacRole'); perform rbac.assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'RbacRole');
perform assertReferenceType('roleId (descendant)', grantedRoleUuid, 'RbacRole'); perform rbac.assertReferenceType('roleId (descendant)', grantedRoleUuid, 'RbacRole');
perform assertReferenceType('userId (ascendant)', userUuid, 'RbacUser'); perform rbac.assertReferenceType('userId (ascendant)', userUuid, 'rbac.subject');
insert insert
into RbacGrants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed) into RbacGrants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed)
@ -40,18 +40,18 @@ declare
grantedByRoleIdName text; grantedByRoleIdName text;
grantedRoleIdName text; grantedRoleIdName text;
begin begin
perform assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'RbacRole'); perform rbac.assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'RbacRole');
perform assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole'); perform rbac.assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole');
perform assertReferenceType('userUuid (ascendant)', userUuid, 'RbacUser'); perform rbac.assertReferenceType('userUuid (ascendant)', userUuid, 'rbac.subject');
assert grantedByRoleUuid is not null, 'grantedByRoleUuid must not be null'; assert grantedByRoleUuid is not null, 'grantedByRoleUuid must not be null';
assert grantedRoleUuid is not null, 'grantedRoleUuid must not be null'; assert grantedRoleUuid is not null, 'grantedRoleUuid must not be null';
assert userUuid is not null, 'userUuid must not be null'; assert userUuid is not null, 'userUuid must not be null';
if NOT isGranted(currentSubjectsUuids(), grantedByRoleUuid) then if NOT isGranted(rbac.currentSubjectOrAssumedRolesUuids(), grantedByRoleUuid) then
select roleIdName from rbacRole_ev where uuid=grantedByRoleUuid into grantedByRoleIdName; select roleIdName from rbacRole_ev where uuid=grantedByRoleUuid into grantedByRoleIdName;
raise exception '[403] Access to granted-by-role % (%) forbidden for % (%)', raise exception '[403] Access to granted-by-role % (%) forbidden for % (%)',
grantedByRoleIdName, grantedByRoleUuid, currentSubjects(), currentSubjectsUuids(); grantedByRoleIdName, grantedByRoleUuid, currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end if; end if;
if NOT isGranted(grantedByRoleUuid, grantedRoleUuid) then if NOT isGranted(grantedByRoleUuid, grantedRoleUuid) then
select roleIdName from rbacRole_ev where uuid=grantedByRoleUuid into grantedByRoleIdName; select roleIdName from rbacRole_ev where uuid=grantedByRoleUuid into grantedByRoleIdName;
@ -77,11 +77,11 @@ end; $$;
create or replace procedure checkRevokeRoleFromUserPreconditions(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid) create or replace procedure checkRevokeRoleFromUserPreconditions(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid)
language plpgsql as $$ language plpgsql as $$
begin begin
perform assertReferenceType('grantedByRoleUuid', grantedByRoleUuid, 'RbacRole'); perform rbac.assertReferenceType('grantedByRoleUuid', grantedByRoleUuid, 'RbacRole');
perform assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole'); perform rbac.assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole');
perform assertReferenceType('userUuid (ascendant)', userUuid, 'RbacUser'); perform rbac.assertReferenceType('userUuid (ascendant)', userUuid, 'rbac.subject');
if NOT isGranted(currentSubjectsUuids(), grantedByRoleUuid) then if NOT isGranted(rbac.currentSubjectOrAssumedRolesUuids(), grantedByRoleUuid) then
raise exception '[403] Revoking role created by % is forbidden for %.', grantedByRoleUuid, currentSubjects(); raise exception '[403] Revoking role created by % is forbidden for %.', grantedByRoleUuid, currentSubjects();
end if; end if;
@ -89,8 +89,8 @@ begin
raise exception '[403] Revoking role % is forbidden for %.', grantedRoleUuid, currentSubjects(); raise exception '[403] Revoking role % is forbidden for %.', grantedRoleUuid, currentSubjects();
end if; end if;
--raise exception 'isGranted(%, %)', currentSubjectsUuids(), grantedByRoleUuid; --raise exception 'isGranted(%, %)', rbac.currentSubjectOrAssumedRolesUuids(), grantedByRoleUuid;
if NOT isGranted(currentSubjectsUuids(), grantedByRoleUuid) then if NOT isGranted(rbac.currentSubjectOrAssumedRolesUuids(), grantedByRoleUuid) then
raise exception '[403] Revoking role granted by % is forbidden for %.', grantedByRoleUuid, currentSubjects(); raise exception '[403] Revoking role granted by % is forbidden for %.', grantedByRoleUuid, currentSubjects();
end if; end if;

View File

@ -5,25 +5,25 @@
--changeset rbac-context-DETERMINE:1 endDelimiter:--// --changeset rbac-context-DETERMINE:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
create or replace function determineCurrentUserUuid(currentUser varchar) create or replace function determineCurrentSubjectUuid(currentSubject varchar)
returns uuid returns uuid
stable -- leakproof stable -- leakproof
language plpgsql as $$ language plpgsql as $$
declare declare
currentUserUuid uuid; currentSubjectUuid uuid;
begin begin
if currentUser = '' then if currentSubject = '' then
return null; return null;
end if; end if;
select uuid from RbacUser where name = currentUser into currentUserUuid; select uuid from rbac.subject where name = currentSubject into currentSubjectUuid;
if currentUserUuid is null then if currentSubjectUuid is null then
raise exception '[401] user % given in `basis.defineContext(...)` does not exist', currentUser; raise exception '[401] subject % given in `basis.defineContext(...)` does not exist', currentSubject;
end if; end if;
return currentUserUuid; return currentSubjectUuid;
end; $$; end; $$;
create or replace function determineCurrentSubjectsUuids(currentUserUuid uuid, assumedRoles varchar) create or replace function determineCurrentSubjectOrAssumedRolesUuids(currentSubjectOrAssumedRolesUuids uuid, assumedRoles varchar)
returns uuid[] returns uuid[]
stable -- leakproof stable -- leakproof
language plpgsql as $$ language plpgsql as $$
@ -37,7 +37,7 @@ declare
roleIdsToAssume uuid[]; roleIdsToAssume uuid[];
roleUuidToAssume uuid; roleUuidToAssume uuid;
begin begin
if currentUserUuid is null then if currentSubjectOrAssumedRolesUuids is null then
if length(coalesce(assumedRoles, '')) > 0 then if length(coalesce(assumedRoles, '')) > 0 then
raise exception '[403] undefined has no permission to assume role %', assumedRoles; raise exception '[403] undefined has no permission to assume role %', assumedRoles;
else else
@ -45,7 +45,7 @@ begin
end if; end if;
end if; end if;
if length(coalesce(assumedRoles, '')) = 0 then if length(coalesce(assumedRoles, '')) = 0 then
return array [currentUserUuid]; return array [currentSubjectOrAssumedRolesUuids];
end if; end if;
foreach roleName in array string_to_array(assumedRoles, ';') foreach roleName in array string_to_array(assumedRoles, ';')
@ -66,10 +66,10 @@ begin
and r.roleType = roleTypeToAssume and r.roleType = roleTypeToAssume
into roleUuidToAssume; into roleUuidToAssume;
if roleUuidToAssume is null then if roleUuidToAssume is null then
raise exception '[403] role % does not exist or is not accessible for user %', roleName, basis.currentUser(); raise exception '[403] role % does not exist or is not accessible for subject %', roleName, basis.currentSubject();
end if; end if;
if not isGranted(currentUserUuid, roleUuidToAssume) then if not isGranted(currentSubjectOrAssumedRolesUuids, roleUuidToAssume) then
raise exception '[403] user % has no permission to assume role %', basis.currentUser(), roleName; raise exception '[403] subject % has no permission to assume role %', basis.currentSubject(), roleName;
end if; end if;
roleIdsToAssume := roleIdsToAssume || roleUuidToAssume; roleIdsToAssume := roleIdsToAssume || roleUuidToAssume;
end loop; end loop;
@ -87,59 +87,59 @@ end; $$;
create or replace procedure basis.contextDefined( create or replace procedure basis.contextDefined(
currentTask varchar(127), currentTask varchar(127),
currentRequest text, currentRequest text,
currentUser varchar(63), currentSubject varchar(63),
assumedRoles varchar(1023) assumedRoles varchar(1023)
) )
language plpgsql as $$ language plpgsql as $$
declare declare
currentUserUuid uuid; currentSubjectUuid uuid;
begin begin
execute format('set local hsadminng.currentTask to %L', currentTask); execute format('set local hsadminng.currentTask to %L', currentTask);
execute format('set local hsadminng.currentRequest to %L', currentRequest); execute format('set local hsadminng.currentRequest to %L', currentRequest);
execute format('set local hsadminng.currentUser to %L', currentUser); execute format('set local hsadminng.currentSubject to %L', currentSubject);
select determineCurrentUserUuid(currentUser) into currentUserUuid; select determineCurrentSubjectUuid(currentSubject) into currentSubjectUuid;
execute format('set local hsadminng.currentUserUuid to %L', coalesce(currentUserUuid::text, '')); execute format('set local hsadminng.currentSubjectUuid to %L', coalesce(currentSubjectUuid::text, ''));
execute format('set local hsadminng.assumedRoles to %L', assumedRoles); execute format('set local hsadminng.assumedRoles to %L', assumedRoles);
execute format('set local hsadminng.currentSubjectsUuids to %L', execute format('set local hsadminng.currentSubjectOrAssumedRolesUuids to %L',
(select array_to_string(determinecurrentSubjectsUuids(currentUserUuid, assumedRoles), ';'))); (select array_to_string(determineCurrentSubjectOrAssumedRolesUuids(currentSubjectUuid, assumedRoles), ';')));
raise notice 'Context defined as: %, %, %, [%]', currentTask, currentRequest, currentUser, assumedRoles; raise notice 'Context defined as: %, %, %, [%]', currentTask, currentRequest, currentSubject, assumedRoles;
end; $$; end; $$;
-- ============================================================================ -- ============================================================================
--changeset rbac-context-CURRENT-USER-ID:1 endDelimiter:--// --changeset rbac-context-current-subject-ID:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
Returns the uuid of the current user as set via `basis.defineContext(...)`. Returns the uuid of the current subject as set via `basis.defineContext(...)`.
*/ */
create or replace function currentUserUuid() create or replace function rbac.currentSubjectUuid()
returns uuid returns uuid
stable -- leakproof stable -- leakproof
language plpgsql as $$ language plpgsql as $$
declare declare
currentUserUuid text; currentSubjectUuid text;
currentUserName text; currentSubjectName text;
begin begin
begin begin
currentUserUuid := current_setting('hsadminng.currentUserUuid'); currentSubjectUuid := current_setting('hsadminng.currentSubjectUuid');
exception exception
when others then when others then
currentUserUuid := null; currentSubjectUuid := null;
end; end;
if (currentUserUuid is null or currentUserUuid = '') then if (currentSubjectUuid is null or currentSubjectUuid = '') then
currentUserName := basis.currentUser(); currentSubjectName := basis.currentSubject();
if (length(currentUserName) > 0) then if (length(currentSubjectName) > 0) then
raise exception '[401] currentUserUuid cannot be determined, unknown user name "%"', currentUserName; raise exception '[401] currentSubjectUuid cannot be determined, unknown subject name "%"', currentSubjectName;
else else
raise exception '[401] currentUserUuid cannot be determined, please call `basis.defineContext(...)` first;"'; raise exception '[401] currentSubjectUuid cannot be determined, please call `basis.defineContext(...)` first;"';
end if; end if;
end if; end if;
return currentUserUuid::uuid; return currentSubjectUuid::uuid;
end; $$; end; $$;
--// --//
@ -147,33 +147,33 @@ end; $$;
--changeset rbac-context-CURRENT-SUBJECT-UUIDS:1 endDelimiter:--// --changeset rbac-context-CURRENT-SUBJECT-UUIDS:1 endDelimiter:--//
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
Returns the uuid of the current user as set via `basis.defineContext(...)`, Returns the uuid of the current subject as set via `basis.defineContext(...)`,
or, if any, the uuids of all assumed roles as set via `basis.defineContext(...)` or, if any, the uuids of all assumed roles as set via `basis.defineContext(...)`
or empty array, if context is not defined. or empty array, if context is not defined.
*/ */
create or replace function currentSubjectsUuids() create or replace function rbac.currentSubjectOrAssumedRolesUuids()
returns uuid[] returns uuid[]
stable -- leakproof stable -- leakproof
language plpgsql as $$ language plpgsql as $$
declare declare
currentSubjectsUuids text; currentSubjectOrAssumedRolesUuids text;
currentUserName text; currentSubjectName text;
begin begin
begin begin
currentSubjectsUuids := current_setting('hsadminng.currentSubjectsUuids'); currentSubjectOrAssumedRolesUuids := current_setting('hsadminng.currentSubjectOrAssumedRolesUuids');
exception exception
when others then when others then
currentSubjectsUuids := null; currentSubjectOrAssumedRolesUuids := null;
end; end;
if (currentSubjectsUuids is null or length(currentSubjectsUuids) = 0 ) then if (currentSubjectOrAssumedRolesUuids is null or length(currentSubjectOrAssumedRolesUuids) = 0 ) then
currentUserName := basis.currentUser(); currentSubjectName := basis.currentSubject();
if (length(currentUserName) > 0) then if (length(currentSubjectName) > 0) then
raise exception '[401] currentSubjectsUuids (%) cannot be determined, unknown user name "%"', currentSubjectsUuids, currentUserName; raise exception '[401] currentSubjectOrAssumedRolesUuids (%) cannot be determined, unknown subject name "%"', currentSubjectOrAssumedRolesUuids, currentSubjectName;
else else
raise exception '[401] currentSubjectsUuids cannot be determined, please call `basis.defineContext(...)` with a valid user;"'; raise exception '[401] currentSubjectOrAssumedRolesUuids cannot be determined, please call `basis.defineContext(...)` with a valid subject;"';
end if; end if;
end if; end if;
return string_to_array(currentSubjectsUuids, ';'); return string_to_array(currentSubjectOrAssumedRolesUuids, ';');
end; $$; end; $$;
--// --//

View File

@ -15,7 +15,7 @@ select (objectTable || '#' || objectIdName || ':' || roleType) as roleIdName, *
select r.*, select r.*,
o.objectTable, findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName o.objectTable, findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
from rbacrole as r from rbacrole as r
join rbacobject as o on o.uuid = r.objectuuid join rbac.object as o on o.uuid = r.objectuuid
) as unordered ) as unordered
-- @formatter:on -- @formatter:on
order by roleIdName; order by roleIdName;
@ -36,8 +36,8 @@ select *
select r.*, o.objectTable, select r.*, o.objectTable,
findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
from rbacrole as r from rbacrole as r
join rbacobject as o on o.uuid = r.objectuuid join rbac.object as o on o.uuid = r.objectuuid
where isGranted(currentSubjectsUuids(), r.uuid) where isGranted(rbac.currentSubjectOrAssumedRolesUuids(), r.uuid)
) as unordered ) as unordered
-- @formatter:on -- @formatter:on
order by objectTable || '#' || objectIdName || ':' || roleType; order by objectTable || '#' || objectIdName || ':' || roleType;
@ -88,17 +88,17 @@ create or replace view rbacgrants_ev as
from rbacgrants as g from rbacgrants as g
left outer join rbacrole as ar on ar.uuid = g.ascendantUuid left outer join rbacrole as ar on ar.uuid = g.ascendantUuid
left outer join rbacobject as aro on aro.uuid = ar.objectuuid left outer join rbac.object as aro on aro.uuid = ar.objectuuid
left outer join rbacuser as au on au.uuid = g.ascendantUuid left outer join rbac.subject as au on au.uuid = g.ascendantUuid
left outer join rbacrole as dr on dr.uuid = g.descendantUuid left outer join rbacrole as dr on dr.uuid = g.descendantUuid
left outer join rbacobject as dro on dro.uuid = dr.objectuuid left outer join rbac.object as dro on dro.uuid = dr.objectuuid
left outer join rbacpermission dp on dp.uuid = g.descendantUuid left outer join rbacpermission dp on dp.uuid = g.descendantUuid
left outer join rbacobject as dpo on dpo.uuid = dp.objectUuid left outer join rbac.object as dpo on dpo.uuid = dp.objectUuid
) as x ) as x
left outer join rbacrole as r on r.uuid = grantedByRoleUuid left outer join rbacrole as r on r.uuid = grantedByRoleUuid
left outer join rbacuser u on u.uuid = x.ascendantuuid left outer join rbac.subject u on u.uuid = x.ascendantuuid
left outer join rbacobject go on go.uuid = r.objectuuid left outer join rbac.object go on go.uuid = r.objectuuid
order by x.ascendingIdName, x.descendingIdName; order by x.ascendingIdName, x.descendingIdName;
-- @formatter:on -- @formatter:on
@ -125,12 +125,12 @@ select o.objectTable || '#' || findIdNameByObjectUuid(o.objectTable, o.uuid) ||
findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
from rbacgrants as g from rbacgrants as g
join rbacrole as r on r.uuid = g.descendantUuid join rbacrole as r on r.uuid = g.descendantUuid
join rbacobject o on o.uuid = r.objectuuid join rbac.object o on o.uuid = r.objectuuid
left outer join rbacuser u on u.uuid = g.ascendantuuid left outer join rbac.subject u on u.uuid = g.ascendantuuid
where isGranted(currentSubjectsUuids(), r.uuid) where isGranted(rbac.currentSubjectOrAssumedRolesUuids(), r.uuid)
) as g ) as g
join RbacRole as r on r.uuid = grantedByRoleUuid join RbacRole as r on r.uuid = grantedByRoleUuid
join RbacObject as o on o.uuid = r.objectUuid join rbac.object as o on o.uuid = r.objectUuid
order by grantedRoleIdName; order by grantedRoleIdName;
-- @formatter:on -- @formatter:on
grant all privileges on rbacrole_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}; grant all privileges on rbacrole_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
@ -209,13 +209,13 @@ create or replace view RbacUser_ev as
select distinct * select distinct *
-- @formatter:off -- @formatter:off
from ( from (
select usersInRolesOfCurrentUser.* select usersInRolesOfcurrentSubject.*
from RbacUser as usersInRolesOfCurrentUser from rbac.subject as usersInRolesOfcurrentSubject
join RbacGrants as g on g.ascendantuuid = usersInRolesOfCurrentUser.uuid join RbacGrants as g on g.ascendantuuid = usersInRolesOfcurrentSubject.uuid
join rbacrole_ev as r on r.uuid = g.descendantuuid join rbacrole_ev as r on r.uuid = g.descendantuuid
union union
select users.* select users.*
from RbacUser as users from rbac.subject as users
) as unordered ) as unordered
-- @formatter:on -- @formatter:on
order by unordered.name; order by unordered.name;
@ -234,15 +234,15 @@ create or replace view RbacUser_rv as
select distinct * select distinct *
-- @formatter:off -- @formatter:off
from ( from (
select usersInRolesOfCurrentUser.* select usersInRolesOfcurrentSubject.*
from RbacUser as usersInRolesOfCurrentUser from rbac.subject as usersInRolesOfcurrentSubject
join RbacGrants as g on g.ascendantuuid = usersInRolesOfCurrentUser.uuid join RbacGrants as g on g.ascendantuuid = usersInRolesOfcurrentSubject.uuid
join rbacrole_rv as r on r.uuid = g.descendantuuid join rbacrole_rv as r on r.uuid = g.descendantuuid
union union
select users.* select users.*
from RbacUser as users from rbac.subject as users
where cardinality(basis.assumedRoles()) = 0 and where cardinality(basis.assumedRoles()) = 0 and
(currentUserUuid() = users.uuid or hasGlobalRoleGranted(currentUserUuid())) (rbac.currentSubjectUuid() = users.uuid or hasGlobalRoleGranted(rbac.currentSubjectUuid()))
) as unordered ) as unordered
-- @formatter:on -- @formatter:on
@ -262,14 +262,14 @@ create or replace function insertRbacUser()
language plpgsql as $$ language plpgsql as $$
declare declare
refUuid uuid; refUuid uuid;
newUser RbacUser; newUser rbac.subject;
begin begin
insert insert
into RbacReference as r (uuid, type) into rbac.reference as r (uuid, type)
values( new.uuid, 'RbacUser') values( new.uuid, 'rbac.subject')
returning r.uuid into refUuid; returning r.uuid into refUuid;
insert insert
into RbacUser (uuid, name) into rbac.subject (uuid, name)
values (refUuid, new.name) values (refUuid, new.name)
returning * into newUser; returning * into newUser;
return newUser; return newUser;
@ -299,11 +299,11 @@ create or replace function deleteRbacUser()
returns trigger returns trigger
language plpgsql as $$ language plpgsql as $$
begin begin
if currentUserUuid() = old.uuid or hasGlobalRoleGranted(currentUserUuid()) then if rbac.currentSubjectUuid() = old.uuid or hasGlobalRoleGranted(rbac.currentSubjectUuid()) then
delete from RbacUser where uuid = old.uuid; delete from rbac.subject where uuid = old.uuid;
return old; return old;
end if; end if;
raise exception '[403] User % not allowed to delete user uuid %', basis.currentUser(), old.uuid; raise exception '[403] User % not allowed to delete user uuid %', basis.currentSubject(), old.uuid;
end; $$; end; $$;
/* /*
@ -332,7 +332,7 @@ select r.uuid as roleuuid, p.uuid as permissionUuid,
from rbacrole_rv r from rbacrole_rv r
join rbacgrants g on g.ascendantuuid = r.uuid join rbacgrants g on g.ascendantuuid = r.uuid
join rbacpermission p on p.uuid = g.descendantuuid join rbacpermission p on p.uuid = g.descendantuuid
join rbacobject o on o.uuid = p.objectuuid; join rbac.object o on o.uuid = p.objectuuid;
grant all privileges on RbacOwnGrantedPermissions_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}; grant all privileges on RbacOwnGrantedPermissions_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
-- @formatter:om -- @formatter:om
@ -348,13 +348,13 @@ create or replace function grantedPermissionsRaw(targetUserUuid uuid)
returns null on null input returns null on null input
language plpgsql as $$ language plpgsql as $$
declare declare
currentUserUuid uuid; currentSubjectUuid uuid;
begin begin
-- @formatter:off -- @formatter:off
currentUserUuid := currentUserUuid(); currentSubjectUuid := rbac.currentSubjectUuid();
if hasGlobalRoleGranted(targetUserUuid) and not hasGlobalRoleGranted(currentUserUuid) then if hasGlobalRoleGranted(targetUserUuid) and not hasGlobalRoleGranted(currentSubjectUuid) then
raise exception '[403] permissions of user "%" are not accessible to user "%"', targetUserUuid, basis.currentUser(); raise exception '[403] permissions of user "%" are not accessible to user "%"', targetUserUuid, basis.currentSubject();
end if; end if;
return query select return query select
@ -371,9 +371,9 @@ begin
po.uuid as permissionObjectUuid po.uuid as permissionObjectUuid
from queryPermissionsGrantedToSubjectId( targetUserUuid) as p from queryPermissionsGrantedToSubjectId( targetUserUuid) as p
join rbacgrants as g on g.descendantUuid = p.uuid join rbacgrants as g on g.descendantUuid = p.uuid
join rbacobject as po on po.uuid = p.objectUuid join rbac.object as po on po.uuid = p.objectUuid
join rbacrole_rv as r on r.uuid = g.ascendantUuid join rbacrole_rv as r on r.uuid = g.ascendantUuid
join rbacobject as ro on ro.uuid = r.objectUuid join rbac.object as ro on ro.uuid = r.objectUuid
where isGranted(targetUserUuid, r.uuid) where isGranted(targetUserUuid, r.uuid)
) xp; ) xp;
-- @formatter:on -- @formatter:on

View File

@ -15,7 +15,7 @@ begin
create trigger createRbacObjectFor_%s_Trigger create trigger createRbacObjectFor_%s_Trigger
before insert on %s before insert on %s
for each row for each row
execute procedure insertRelatedRbacObject(); execute procedure rbac.insert_related_object();
$sql$, targetTable, targetTable); $sql$, targetTable, targetTable);
execute createInsertTriggerSQL; execute createInsertTriggerSQL;
@ -185,7 +185,7 @@ begin
true true
from rbacgrants from rbacgrants
where rbacgrants.assumed where rbacgrants.assumed
and (rbacgrants.ascendantuuid = any (currentsubjectsuuids())) and (rbacgrants.ascendantuuid = any (rbac.currentSubjectOrAssumedRolesUuids()))
union all union all
select distinct g.descendantuuid, select distinct g.descendantuuid,
g.ascendantuuid, g.ascendantuuid,
@ -203,7 +203,7 @@ begin
select distinct perm.objectuuid select distinct perm.objectuuid
from recursive_grants from recursive_grants
join rbacpermission perm on recursive_grants.descendantuuid = perm.uuid join rbacpermission perm on recursive_grants.descendantuuid = perm.uuid
join rbacobject obj on obj.uuid = perm.objectuuid join rbac.object obj on obj.uuid = perm.objectuuid
join count_check cc on cc.valid join count_check cc on cc.valid
where obj.objectTable = '%1$s' -- 'SELECT' permission is included in all other permissions where obj.objectTable = '%1$s' -- 'SELECT' permission is included in all other permissions
) )
@ -256,11 +256,11 @@ begin
returns trigger returns trigger
language plpgsql as $f$ language plpgsql as $f$
begin begin
if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('DELETE', '%1$s', currentSubjectsUuids())) then if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('DELETE', '%1$s', rbac.currentSubjectOrAssumedRolesUuids())) then
delete from %1$s p where p.uuid = old.uuid; delete from %1$s p where p.uuid = old.uuid;
return old; return old;
end if; end if;
raise exception '[403] Subject %% is not allowed to delete %1$s uuid %%', currentSubjectsUuids(), old.uuid; raise exception '[403] Subject %% is not allowed to delete %1$s uuid %%', rbac.currentSubjectOrAssumedRolesUuids(), old.uuid;
end; $f$; end; $f$;
$sql$, targetTable); $sql$, targetTable);
execute sql; execute sql;
@ -287,13 +287,13 @@ begin
returns trigger returns trigger
language plpgsql as $f$ language plpgsql as $f$
begin begin
if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('UPDATE', '%1$s', currentSubjectsUuids())) then if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('UPDATE', '%1$s', rbac.currentSubjectOrAssumedRolesUuids())) then
update %1$s update %1$s
set %2$s set %2$s
where uuid = old.uuid; where uuid = old.uuid;
return old; return old;
end if; end if;
raise exception '[403] Subject %% is not allowed to update %1$s uuid %%', currentSubjectsUuids(), old.uuid; raise exception '[403] Subject %% is not allowed to update %1$s uuid %%', rbac.currentSubjectOrAssumedRolesUuids(), old.uuid;
end; $f$; end; $f$;
$sql$, targetTable, columnUpdates); $sql$, targetTable, columnUpdates);
execute sql; execute sql;

View File

@ -8,7 +8,7 @@
create view RbacStatisticsView as create view RbacStatisticsView as
select no, to_char("count", '9 999 999 999') as "count", "table" select no, to_char("count", '9 999 999 999') as "count", "table"
from (select 1 as no, count(*) as "count", 'login users' as "table" from (select 1 as no, count(*) as "count", 'login users' as "table"
from RbacUser from rbac.subject
union union
select 2 as no, count(*) as "count", 'roles' as "table" select 2 as no, count(*) as "count", 'roles' as "table"
from RbacRole from RbacRole
@ -17,12 +17,12 @@ select no, to_char("count", '9 999 999 999') as "count", "table"
from RbacPermission from RbacPermission
union union
select 4 as no, count(*) as "count", 'references' as "table" select 4 as no, count(*) as "count", 'references' as "table"
from RbacReference from rbac.reference
union union
select 5 as no, count(*) as "count", 'grants' as "table" select 5 as no, count(*) as "count", 'grants' as "table"
from RbacGrants from RbacGrants
union union
select 6 as no, count(*) as "count", 'objects' as "table" select 6 as no, count(*) as "count", 'objects' as "table"
from RbacObject) as totals from rbac.object) as totals
order by totals.no; order by totals.no;
--// --//

View File

@ -13,7 +13,7 @@
*/ */
create table Global create table Global
( (
uuid uuid primary key references RbacObject (uuid) on delete cascade, uuid uuid primary key references rbac.object (uuid) on delete cascade,
name varchar(63) unique name varchar(63) unique
); );
create unique index Global_Singleton on Global ((0)); create unique index Global_Singleton on Global ((0));
@ -30,7 +30,7 @@ create or replace function isGlobalAdmin()
returns boolean returns boolean
language plpgsql as $$ language plpgsql as $$
begin begin
return isGranted(currentSubjectsUuids(), findRoleId(globalAdmin())); return isGranted(rbac.currentSubjectOrAssumedRolesUuids(), findRoleId(globalAdmin()));
end; $$; end; $$;
--// --//
@ -45,7 +45,7 @@ create or replace function hasGlobalPermission(op RbacOp)
$$ $$
-- TODO.perf: this could to be optimized -- TODO.perf: this could to be optimized
select (select uuid from global) in select (select uuid from global) in
(select queryAccessibleObjectUuidsOfSubjectIds(op, 'global', currentSubjectsUuids())); (select queryAccessibleObjectUuidsOfSubjectIds(op, 'global', rbac.currentSubjectOrAssumedRolesUuids()));
$$; $$;
--// --//
@ -96,9 +96,9 @@ $$;
begin transaction; begin transaction;
call basis.defineContext('initializing table "global"', null, null, null); call basis.defineContext('initializing table "global"', null, null, null);
insert insert
into RbacObject (objecttable) values ('global'); into rbac.object (objecttable) values ('global');
insert insert
into Global (uuid, name) values ((select uuid from RbacObject where objectTable = 'global'), 'global'); into Global (uuid, name) values ((select uuid from rbac.object where objectTable = 'global'), 'global');
commit; commit;
--// --//
@ -114,7 +114,7 @@ create or replace function globalAdmin(assumed boolean = true)
returns null on null input returns null on null input
stable -- leakproof stable -- leakproof
language sql as $$ language sql as $$
select 'global', (select uuid from RbacObject where objectTable = 'global'), 'ADMIN'::RbacRoleType, assumed; select 'global', (select uuid from rbac.object where objectTable = 'global'), 'ADMIN'::RbacRoleType, assumed;
$$; $$;
begin transaction; begin transaction;
@ -135,7 +135,7 @@ create or replace function globalGuest(assumed boolean = true)
returns null on null input returns null on null input
stable -- leakproof stable -- leakproof
language sql as $$ language sql as $$
select 'global', (select uuid from RbacObject where objectTable = 'global'), 'GUEST'::RbacRoleType, assumed; select 'global', (select uuid from rbac.object where objectTable = 'global'), 'GUEST'::RbacRoleType, assumed;
$$; $$;
begin transaction; begin transaction;
@ -158,10 +158,10 @@ do language plpgsql $$
call basis.defineContext('creating fake test-realm admin users', null, null, null); call basis.defineContext('creating fake test-realm admin users', null, null, null);
admins = findRoleId(globalAdmin()); admins = findRoleId(globalAdmin());
call grantRoleToUserUnchecked(admins, admins, createRbacUser('superuser-alex@hostsharing.net')); call grantRoleToUserUnchecked(admins, admins, rbac.create_subject('superuser-alex@hostsharing.net'));
hsh-michaelhoennig marked this conversation as resolved Outdated

müsste das nicht grantRoleToSubjectUnchecked heißen

müsste das nicht grantRoleToSubjectUnchecked heißen
call grantRoleToUserUnchecked(admins, admins, createRbacUser('superuser-fran@hostsharing.net')); call grantRoleToUserUnchecked(admins, admins, rbac.create_subject('superuser-fran@hostsharing.net'));
perform createRbacUser('selfregistered-user-drew@hostsharing.org'); perform rbac.create_subject('selfregistered-user-drew@hostsharing.org');
perform createRbacUser('selfregistered-test-user@hostsharing.org'); perform rbac.create_subject('selfregistered-test-user@hostsharing.org');
end; end;
$$; $$;
--// --//
@ -172,23 +172,23 @@ $$;
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
/* /*
Tests if currentUserUuid() can fetch the user from the session variable. Tests if rbac.currentSubjectUuid() can fetch the user from the session variable.
*/ */
do language plpgsql $$ do language plpgsql $$
declare declare
userName varchar; userName varchar;
begin begin
call basis.defineContext('testing currentUserUuid', null, 'superuser-fran@hostsharing.net', null); call basis.defineContext('testing currentSubjectUuid', null, 'superuser-fran@hostsharing.net', null);
select userName from RbacUser where uuid = currentUserUuid() into userName; select userName from rbac.subject where uuid = rbac.currentSubjectUuid() into userName;
if userName <> 'superuser-fran@hostsharing.net' then if userName <> 'superuser-fran@hostsharing.net' then
raise exception 'setting or fetching initial currentUser failed, got: %', userName; raise exception 'setting or fetching initial currentSubject failed, got: %', userName;
end if; end if;
call basis.defineContext('testing currentUserUuid', null, 'superuser-alex@hostsharing.net', null); call basis.defineContext('testing currentSubjectUuid', null, 'superuser-alex@hostsharing.net', null);
select userName from RbacUser where uuid = currentUserUuid() into userName; select userName from rbac.subject where uuid = rbac.currentSubjectUuid() into userName;
if userName = 'superuser-alex@hostsharing.net' then if userName = 'superuser-alex@hostsharing.net' then
raise exception 'currentUser should not change in one transaction, but did change, got: %', userName; raise exception 'currentSubject should not change in one transaction, but did change, got: %', userName;
end if; end if;
end; $$; end; $$;
--// --//

View File

@ -6,7 +6,7 @@
create table if not exists test_customer create table if not exists test_customer
( (
uuid uuid unique references RbacObject (uuid), uuid uuid unique references rbac.object (uuid),
version int not null default 0, version int not null default 0,
reference int not null unique check (reference between 10000 and 99999), reference int not null unique check (reference between 10000 and 99999),
prefix character(3) unique, prefix character(3) unique,

View File

@ -38,7 +38,7 @@ begin
testCustomerOWNER(NEW), testCustomerOWNER(NEW),
permissions => array['DELETE'], permissions => array['DELETE'],
incomingSuperRoles => array[globalADMIN(unassumed())], incomingSuperRoles => array[globalADMIN(unassumed())],
userUuids => array[currentUserUuid()] userUuids => array[rbac.currentSubjectUuid()]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
@ -143,7 +143,7 @@ begin
end if; end if;
raise exception '[403] insert into test_customer values(%) not allowed for current subjects % (%)', raise exception '[403] insert into test_customer values(%) not allowed for current subjects % (%)',
NEW, currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$; end; $$;
create trigger test_customer_insert_permission_check_tg create trigger test_customer_insert_permission_check_tg

View File

@ -32,7 +32,7 @@ declare
begin begin
custRowId = uuid_generate_v4(); custRowId = uuid_generate_v4();
custAdminName = 'customer-admin@' || custPrefix || '.example.com'; custAdminName = 'customer-admin@' || custPrefix || '.example.com';
custAdminUuid = createRbacUser(custAdminName); custAdminUuid = rbac.create_subject(custAdminName);
insert insert
into test_customer (reference, prefix, adminUserName) into test_customer (reference, prefix, adminUserName)

View File

@ -6,7 +6,7 @@
create table if not exists test_package create table if not exists test_package
( (
uuid uuid unique references RbacObject (uuid), uuid uuid unique references rbac.object (uuid),
version int not null default 0, version int not null default 0,
customerUuid uuid references test_customer (uuid), customerUuid uuid references test_customer (uuid),
name varchar(5), name varchar(5),

View File

@ -208,7 +208,7 @@ begin
end if; end if;
raise exception '[403] insert into test_package values(%) not allowed for current subjects % (%)', raise exception '[403] insert into test_package values(%) not allowed for current subjects % (%)',
NEW, currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$; end; $$;
create trigger test_package_insert_permission_check_tg create trigger test_package_insert_permission_check_tg

View File

@ -32,7 +32,7 @@ begin
call grantRoleToUser( call grantRoleToUser(
getRoleId(testCustomerAdmin(cust)), getRoleId(testCustomerAdmin(cust)),
findRoleId(testPackageAdmin(pac)), findRoleId(testPackageAdmin(pac)),
createRbacUser('pac-admin-' || pacName || '@' || cust.prefix || '.example.com'), rbac.create_subject('pac-admin-' || pacName || '@' || cust.prefix || '.example.com'),
true); true);
end loop; end loop;

View File

@ -6,7 +6,7 @@
create table if not exists test_domain create table if not exists test_domain
( (
uuid uuid unique references RbacObject (uuid), uuid uuid unique references rbac.object (uuid),
packageUuid uuid references test_package (uuid), packageUuid uuid references test_package (uuid),
name character varying(253), name character varying(253),
description character varying(96) description character varying(96)

View File

@ -207,7 +207,7 @@ begin
end if; end if;
raise exception '[403] insert into test_domain values(%) not allowed for current subjects % (%)', raise exception '[403] insert into test_domain values(%) not allowed for current subjects % (%)',
NEW, currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$; end; $$;
create trigger test_domain_insert_permission_check_tg create trigger test_domain_insert_permission_check_tg

View File

@ -6,7 +6,7 @@
create table if not exists hs_office_contact create table if not exists hs_office_contact
( (
uuid uuid unique references RbacObject (uuid) initially deferred, uuid uuid unique references rbac.object (uuid) initially deferred,
version int not null default 0, version int not null default 0,
caption varchar(128) not null, caption varchar(128) not null,
postalAddress text, postalAddress text,

View File

@ -38,7 +38,7 @@ begin
hsOfficeContactOWNER(NEW), hsOfficeContactOWNER(NEW),
permissions => array['DELETE'], permissions => array['DELETE'],
incomingSuperRoles => array[globalADMIN()], incomingSuperRoles => array[globalADMIN()],
userUuids => array[currentUserUuid()] userUuids => array[rbac.currentSubjectUuid()]
); );
perform createRoleWithGrants( perform createRoleWithGrants(

View File

@ -16,7 +16,7 @@ declare
begin begin
emailAddr = 'contact-admin@' || cleanIdentifier(contCaption) || '.example.com'; emailAddr = 'contact-admin@' || cleanIdentifier(contCaption) || '.example.com';
call basis.defineContext('creating contact test-data'); call basis.defineContext('creating contact test-data');
perform createRbacUser(emailAddr); perform rbac.create_subject(emailAddr);
call basis.defineContext('creating contact test-data', null, emailAddr); call basis.defineContext('creating contact test-data', null, emailAddr);
postalAddr := E'Vorname Nachname\nStraße Hnr\nPLZ Stadt'; postalAddr := E'Vorname Nachname\nStraße Hnr\nPLZ Stadt';

View File

@ -16,7 +16,7 @@ CREATE CAST (character varying as HsOfficePersonType) WITH INOUT AS IMPLICIT;
create table if not exists hs_office_person create table if not exists hs_office_person
( (
uuid uuid unique references RbacObject (uuid) initially deferred, uuid uuid unique references rbac.object (uuid) initially deferred,
version int not null default 0, version int not null default 0,
personType HsOfficePersonType not null, personType HsOfficePersonType not null,
tradeName varchar(96), tradeName varchar(96),

View File

@ -38,7 +38,7 @@ begin
hsOfficePersonOWNER(NEW), hsOfficePersonOWNER(NEW),
permissions => array['DELETE'], permissions => array['DELETE'],
incomingSuperRoles => array[globalADMIN()], incomingSuperRoles => array[globalADMIN()],
userUuids => array[currentUserUuid()] userUuids => array[rbac.currentSubjectUuid()]
); );
perform createRoleWithGrants( perform createRoleWithGrants(

View File

@ -22,7 +22,7 @@ begin
fullName := concat_ws(', ', newTradeName, newFamilyName, newGivenName); fullName := concat_ws(', ', newTradeName, newFamilyName, newGivenName);
emailAddr = 'person-' || left(cleanIdentifier(fullName), 32) || '@example.com'; emailAddr = 'person-' || left(cleanIdentifier(fullName), 32) || '@example.com';
call basis.defineContext('creating person test-data'); call basis.defineContext('creating person test-data');
perform createRbacUser(emailAddr); perform rbac.create_subject(emailAddr);
call basis.defineContext('creating person test-data', null, emailAddr); call basis.defineContext('creating person test-data', null, emailAddr);
raise notice 'creating test person: % by %', fullName, emailAddr; raise notice 'creating test person: % by %', fullName, emailAddr;

View File

@ -18,7 +18,7 @@ CREATE CAST (character varying as HsOfficeRelationType) WITH INOUT AS IMPLICIT;
create table if not exists hs_office_relation create table if not exists hs_office_relation
( (
uuid uuid unique references RbacObject (uuid) initially deferred, -- on delete cascade uuid uuid unique references rbac.object (uuid) initially deferred, -- on delete cascade
version int not null default 0, version int not null default 0,
anchorUuid uuid not null references hs_office_person(uuid), anchorUuid uuid not null references hs_office_person(uuid),
holderUuid uuid not null references hs_office_person(uuid), holderUuid uuid not null references hs_office_person(uuid),

View File

@ -51,7 +51,7 @@ begin
hsOfficeRelationOWNER(NEW), hsOfficeRelationOWNER(NEW),
permissions => array['DELETE'], permissions => array['DELETE'],
incomingSuperRoles => array[globalADMIN()], incomingSuperRoles => array[globalADMIN()],
userUuids => array[currentUserUuid()] userUuids => array[rbac.currentSubjectUuid()]
); );
perform createRoleWithGrants( perform createRoleWithGrants(
@ -217,7 +217,7 @@ begin
end if; end if;
raise exception '[403] insert into hs_office_relation not allowed for current subjects % (%)', raise exception '[403] insert into hs_office_relation not allowed for current subjects % (%)',
currentSubjects(), currentSubjectsUuids(); currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$; end; $$;
create trigger hs_office_relation_insert_permission_check_tg create trigger hs_office_relation_insert_permission_check_tg

View File

@ -7,7 +7,7 @@
create table hs_office_partner_details create table hs_office_partner_details
( (
uuid uuid unique references RbacObject (uuid) initially deferred, uuid uuid unique references rbac.object (uuid) initially deferred,
version int not null default 0, version int not null default 0,
registrationOffice varchar(96), registrationOffice varchar(96),
registrationNumber varchar(96), registrationNumber varchar(96),
@ -32,7 +32,7 @@ call basis.create_journal('hs_office_partner_details');
create table hs_office_partner create table hs_office_partner
( (
uuid uuid unique references RbacObject (uuid) initially deferred, uuid uuid unique references rbac.object (uuid) initially deferred,
version int not null default 0, version int not null default 0,
partnerNumber numeric(5) unique not null, partnerNumber numeric(5) unique not null,
partnerRelUuid uuid not null references hs_office_relation(uuid), -- deleted in after delete trigger partnerRelUuid uuid not null references hs_office_relation(uuid), -- deleted in after delete trigger

View File

@ -220,7 +220,7 @@ begin
end if; end if;
raise exception '[403] insert into hs_office_partner values(%) not allowed for current subjects % (%)', raise exception '[403] insert into hs_office_partner values(%) not allowed for current subjects % (%)',
NEW, currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$; end; $$;
create trigger hs_office_partner_insert_permission_check_tg create trigger hs_office_partner_insert_permission_check_tg

View File

@ -124,7 +124,7 @@ begin
end if; end if;
raise exception '[403] insert into hs_office_partner_details values(%) not allowed for current subjects % (%)', raise exception '[403] insert into hs_office_partner_details values(%) not allowed for current subjects % (%)',
NEW, currentSubjects(), currentSubjectsUuids(); NEW, currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
end; $$; end; $$;
create trigger hs_office_partner_details_insert_permission_check_tg create trigger hs_office_partner_details_insert_permission_check_tg

View File

@ -5,7 +5,7 @@
create table hs_office_bankaccount create table hs_office_bankaccount
( (
uuid uuid unique references RbacObject (uuid) initially deferred, uuid uuid unique references rbac.object (uuid) initially deferred,
version int not null default 0, version int not null default 0,
holder varchar(64) not null, holder varchar(64) not null,
iban varchar(34) not null, iban varchar(34) not null,

Some files were not shown because too many files have changed in this diff Show More