introduce separate database-schemas base+rbac #103
@ -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:
|
||||
curl \
|
||||
-H 'current-user: superuser-alex@hostsharing.net' \
|
||||
-H 'current-subject: superuser-alex@hostsharing.net' \
|
||||
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:
|
||||
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
|
||||
|
||||
# add a new customer
|
||||
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" }' \
|
||||
-X POST http://localhost:8080/api/test/customers
|
||||
|
||||
|
36
bin/git-pull-and-if-origin-changed-run-tests
Executable file
36
bin/git-pull-and-if-origin-changed-run-tests
Executable file
@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
# get the current branch name
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
|
||||
while true; do
|
||||
|
||||
# get the latest commit hashes from origin and local
|
||||
git fetch origin
|
||||
LOCAL=$(git rev-parse HEAD)
|
||||
REMOTE=$(git rev-parse origin/$BRANCH)
|
||||
|
||||
# check if the local branch differs from the remote branch
|
||||
if [ "$LOCAL" != "$REMOTE" ]; then
|
||||
echo "local $LOCAL differs from remote $REMOTE => pulling changes from origin"
|
||||
git pull origin $BRANCH
|
||||
|
||||
# run the command
|
||||
echo "Running ./gradlew test"
|
||||
source .aliases # only variables, aliases are not expanded in scripts
|
||||
./gradlew test
|
||||
fi
|
||||
|
||||
# wait 10s with a little animation
|
||||
echo -e -n " waiting for changes (/) ..."
|
||||
sleep 2
|
||||
echo -e -n "\r\033[K waiting for changes (-) ..."
|
||||
sleep 2
|
||||
echo -e -n "\r\033[K waiting for changes (\) ..."
|
||||
sleep 2
|
||||
echo -e -n "\r\033[K waiting for changes (|) ..."
|
||||
sleep 2
|
||||
echo -e -n "\r\033[K waiting for changes ( ) ... "
|
||||
sleep 2
|
||||
echo -e -n "\r\033[K"
|
||||
done
|
@ -14,9 +14,9 @@ The core problem here is, that in our RBAC system, determining the permissions o
|
||||
|
||||
### 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.
|
||||
|
||||
@ -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.
|
||||
|
||||
The role-hierarchy and permissions for currently logged-in users user could be cached in the backend.
|
||||
The role-hierarchy and permissions for current subjects (e.g. logged-in users) could be cached in the backend.
|
||||
|
||||
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
|
||||
TO restricted
|
||||
USING (
|
||||
isPermissionGrantedToSubject(findEffectivePermissionId('customer', id, 'view'), currentUserUuid())
|
||||
rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('customer', id, 'view'), currentSubjectUuid())
|
||||
);
|
||||
|
||||
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
|
||||
|
||||
#### Advantages
|
||||
@ -101,10 +101,10 @@ We are bound to PostgreSQL, including integration tests and testing the RBAC sys
|
||||
CREATE OR REPLACE RULE "_RETURN" AS
|
||||
ON SELECT TO cust_view
|
||||
DO INSTEAD
|
||||
SELECT * FROM customer WHERE isPermissionGrantedToSubject(findEffectivePermissionId('customer', id, 'view'), currentUserUuid());
|
||||
SELECT * FROM customer WHERE rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('customer', id, 'view'), currentSubjectUuid());
|
||||
|
||||
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
|
||||
|
||||
#### 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
|
||||
SELECT c.id, c.reference, c.prefix
|
||||
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';
|
||||
GRANT ALL PRIVILEGES ON cust_view TO 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
|
||||
|
||||
Alternatively the JOIN could also be applied in a "ON SELECT DO INSTEAD"-RULE, if there is any advantage for later features.
|
||||
|
@ -239,7 +239,7 @@ This did not improve the performance.
|
||||
We were suspicious about the sequential scan over all `rbacpermission` rows which was done by PostgreSQL to execute a HashJoin strategy. Turning off that strategy by
|
||||
|
||||
```SQL
|
||||
ALTER FUNCTION queryAccessibleObjectUuidsOfSubjectIds SET enable_hashjoin = off;
|
||||
ALTER FUNCTION rbac.queryAccessibleObjectUuidsOfSubjectIds SET enable_hashjoin = off;
|
||||
```
|
||||
|
||||
did not improve the performance though. The HashJoin was actually still applied, but no full table scan anymore:
|
||||
@ -273,9 +273,9 @@ At this point, the import took 21mins with these statistics:
|
||||
| select hore1_0.uuid,a1_0.uuid,a1_0.familyname,a1_0.givenname,a1_0.persontype,a1_0.salutation,a1_0.title,a1_0.tradename,a1_0.version,c1_0.uuid,c1_0.caption,c1_0.emailaddresses,c1_0.phonenumbers,c1_0.postaladdress, c1_0.version,h1_0.uuid,h1_0.familyname,h1_0.givenname,h1_0.persontype,h1_0.salutation,h1_0.title,h1_0.tradename,h1_0.version,hore1_0.mark,hore1_0.type,hore1_0.version from public.hs_office_relation_rv hore1_0 left join public.hs_office_person_rv a1_0 on a1_0.uuid=hore1_0.anchoruuid left join public.hs_office_contact_rv c1_0 on c1_0.uuid=hore1_0.contactuuid left join public.hs_office_person_rv h1_0 on h1_0.uuid=hore1_0.holderuuid where hore1_0.uuid=$1 | 517 | 11 | 1282 |
|
||||
| select hope1_0.uuid,hope1_0.familyname,hope1_0.givenname,hope1_0.persontype,hope1_0.salutation,hope1_0.title,hope1_0.tradename,hope1_0.version from public.hs_office_person_rv hope1_0 where hope1_0.uuid=$1 | 973 | 4 | 254 |
|
||||
| select hoce1_0.uuid,hoce1_0.caption,hoce1_0.emailaddresses,hoce1_0.phonenumbers,hoce1_0.postaladdress,hoce1_0.version from public.hs_office_contact_rv hoce1_0 where hoce1_0.uuid=$1 | 973 | 4 | 253 |
|
||||
| call grantRoleToRole(roleUuid, superRoleUuid, superRoleDesc.assumed) | 31316 | 0 | 1 |
|
||||
| call rbac.grantRoleToRole(roleUuid, superRoleUuid, superRoleDesc.assumed) | 31316 | 0 | 1 |
|
||||
| call buildRbacSystemForHsHostingAsset(NEW) | 2258 | 0 | 7 |
|
||||
| select * from isGranted(array[granteeId], grantedId) | 44613 | 0 | 0 |
|
||||
| select * from rbac.isGranted(array[granteeId], grantedId) | 44613 | 0 | 0 |
|
||||
| insert into public.hs_hosting_asset_rv (alarmcontactuuid,assignedtoassetuuid,bookingitemuuid,caption,config,identifier,parentassetuuid,type,version,uuid) values ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10) | 2207 | 0 | 7 |
|
||||
| insert into hs_hosting_asset (alarmcontactuuid, version, bookingitemuuid, type, parentassetuuid, assignedtoassetuuid, config, uuid, identifier, caption) values (new.alarmcontactuuid, new. version, new. bookingitemuuid, new. type, new. parentassetuuid, new. assignedtoassetuuid, new. config, new. uuid, new. identifier, new. caption) returning * | 2207 | 0 | 7 |
|
||||
| insert into public.hs_office_relation_rv (anchoruuid,contactuuid,holderuuid,mark,type,version,uuid) values ($1,$2,$3,$4,$5,$6,$7) | 1261 | 0 | 9 |
|
||||
@ -297,8 +297,8 @@ We changed these mappings from `EAGER` (default) to `LAZY` to `@ManyToOne(fetch
|
||||
| select hope1_0.uuid,hope1_0.familyname,hope1_0.givenname,hope1_0.persontype,hope1_0.salutation,hope1_0.title,hope1_0.tradename,hope1_0.version from public.hs_office_person_rv hope1_0 where hope1_0.uuid=$1 | 1015 | 4 | 238 |
|
||||
| select hore1_0.uuid,hore1_0.anchoruuid,hore1_0.contactuuid,hore1_0.holderuuid,hore1_0.mark,hore1_0.type,hore1_0.version from public.hs_office_relation_rv hore1_0 where hore1_0.uuid=$1 | 517 | 4 | 439 |
|
||||
| select hoce1_0.uuid,hoce1_0.caption,hoce1_0.emailaddresses,hoce1_0.phonenumbers,hoce1_0.postaladdress,hoce1_0.version from public.hs_office_contact_rv hoce1_0 where hoce1_0.uuid=$1 | 497 | 2 | 213 |
|
||||
| call grantRoleToRole(roleUuid, superRoleUuid, superRoleDesc.assumed) | 31316 | 0 | 1 |
|
||||
| select * from isGranted(array[granteeId], grantedId) | 44613 | 0 | 0 |
|
||||
| call rbac.grantRoleToRole(roleUuid, superRoleUuid, superRoleDesc.assumed) | 31316 | 0 | 1 |
|
||||
| select * from rbac.isGranted(array[granteeId], grantedId) | 44613 | 0 | 0 |
|
||||
| call buildRbacSystemForHsHostingAsset(NEW) | 2258 | 0 | 7 |
|
||||
| insert into public.hs_hosting_asset_rv (alarmcontactuuid,assignedtoassetuuid,bookingitemuuid,caption,config,identifier,parentassetuuid,type,version,uuid) values ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10) | 2207 | 0 | 7 |
|
||||
| insert into hs_hosting_asset (alarmcontactuuid, version, bookingitemuuid, type, parentassetuuid, assignedtoassetuuid, config, uuid, identifier, caption) values (new.alarmcontactuuid, new. version, new. bookingitemuuid, new. type, new. parentassetuuid, new. assignedtoassetuuid, new. config, new. uuid, new. identifier, new. caption) returning * | 2207 | 0 | 7 |
|
||||
@ -333,8 +333,8 @@ Now, the longest running queries are these:
|
||||
| 1 | 13.093 | 4 | 21 | insert into hs_hosting_asset( uuid, type, bookingitemuuid, parentassetuuid, assignedtoassetuuid, alarmcontactuuid, identifier, caption, config, version) values ( $1, $2, $3, $4, $5, $6, $7, $8, cast($9 as jsonb), $10) |
|
||||
| 2 | 517 | 4 | 502 | select hore1_0.uuid,hore1_0.anchoruuid,hore1_0.contactuuid,hore1_0.holderuuid,hore1_0.mark,hore1_0.type,hore1_0.version from public.hs_office_relation_rv hore1_0 where hore1_0.uuid=$1 |
|
||||
| 3 | 13.144 | 4 | 21 | call buildRbacSystemForHsHostingAsset(NEW) |
|
||||
| 4 | 96.632 | 3 | 2 | call grantRoleToRole(roleUuid, superRoleUuid, superRoleDesc.assumed) |
|
||||
| 5 | 120.815 | 3 | 2 | select * from isGranted(array[granteeId], grantedId) |
|
||||
| 4 | 96.632 | 3 | 2 | call rbac.grantRoleToRole(roleUuid, superRoleUuid, superRoleDesc.assumed) |
|
||||
| 5 | 120.815 | 3 | 2 | select * from rbac.isGranted(array[granteeId], grantedId) |
|
||||
| 6 | 123.740 | 3 | 2 | with recursive grants as ( select descendantUuid, ascendantUuid from RbacGrants where descendantUuid = grantedId union all select "grant".descendantUuid, "grant".ascendantUuid from RbacGrants "grant" inner join grants recur on recur.ascendantUuid = "grant".descendantUuid ) select exists ( select $3 from grants where ascendantUuid = any(granteeIds) ) or grantedId = any(granteeIds) |
|
||||
| 7 | 497 | 2 | 259 | select hoce1_0.uuid,hoce1_0.caption,hoce1_0.emailaddresses,hoce1_0.phonenumbers,hoce1_0.postaladdress,hoce1_0.version from public.hs_office_contact_rv hoce1_0 where hoce1_0.uuid=$1 |
|
||||
| 8 | 497 | 2 | 255 | select hope1_0.uuid,hope1_0.familyname,hope1_0.givenname,hope1_0.persontype,hope1_0.salutation,hope1_0.title,hope1_0.tradename,hope1_0.version from public.hs_office_person_rv hope1_0 where hope1_0.uuid=$1 |
|
||||
@ -392,9 +392,9 @@ We found some solution approaches:
|
||||
|
||||
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,
|
||||
then recurse down to the `currentsubjectsuuids()`.
|
||||
then recurse down to the `currentSubjectOrAssumedRolesUuids()`.
|
||||
|
||||
In the end, we need the object UUIDs, though.
|
||||
But if we start with the join of `rbacObject` with `rbacPermission`,
|
||||
|
56
doc/rbac.md
56
doc/rbac.md
@ -29,7 +29,7 @@ skinparam linetype ortho
|
||||
package RBAC {
|
||||
|
||||
' forward declarations
|
||||
entity RbacUser
|
||||
entity RbacSubject
|
||||
|
||||
together {
|
||||
|
||||
@ -37,8 +37,8 @@ package RBAC {
|
||||
entity RbacPermission
|
||||
|
||||
|
||||
RbacUser -[hidden]> RbacRole
|
||||
RbacRole -[hidden]> RbacUser
|
||||
RbacSubject -[hidden]> RbacRole
|
||||
RbacRole -[hidden]> RbacSubject
|
||||
}
|
||||
|
||||
together {
|
||||
@ -57,11 +57,11 @@ package RBAC {
|
||||
RbacGrant o-u-> RbacReference
|
||||
|
||||
enum RbacReferenceType {
|
||||
RbacUser
|
||||
RbacSubject
|
||||
RbacRole
|
||||
RbacPermission
|
||||
}
|
||||
RbacReferenceType ..> RbacUser
|
||||
RbacReferenceType ..> RbacSubject
|
||||
RbacReferenceType ..> RbacRole
|
||||
RbacReferenceType ..> RbacPermission
|
||||
|
||||
@ -71,12 +71,12 @@ package RBAC {
|
||||
type : RbacReferenceType
|
||||
}
|
||||
RbacReference o--> RbacReferenceType
|
||||
entity RbacUser {
|
||||
entity RbacSubject {
|
||||
*uuid : uuid <<generated>>
|
||||
--
|
||||
name : varchar
|
||||
}
|
||||
RbacUser o-- RbacReference
|
||||
RbacSubject o-- RbacReference
|
||||
|
||||
entity RbacRole {
|
||||
*uuid : uuid(RbacReference)
|
||||
@ -143,20 +143,20 @@ The primary key of the *RbacReference* and its referred object is always identic
|
||||
#### RbacReferenceType
|
||||
|
||||
The enum *RbacReferenceType* describes the type of reference.
|
||||
It's only needed to make it easier to find the referred object in *RbacUser*, *RbacRole* or *RbacPermission*.
|
||||
It's only needed to make it easier to find the referred object in *RbacSubject*, *RbacRole* or *RbacPermission*.
|
||||
|
||||
#### RbacUser
|
||||
#### RbacSubject
|
||||
|
||||
An *RbacUser* is a type of RBAC-subject which references a login account outside this system, identified by a name (usually an email-address).
|
||||
An *RbacSubject* is a type of RBAC-subject which references a login account outside this system, identified by a name (usually an email-address).
|
||||
|
||||
*RbacUser*s can be assigned to multiple *RbacRole*s, through which they can get permissions to *RbacObject*s.
|
||||
*RbacSubject*s can be assigned to multiple *RbacRole*s, through which they can get permissions to *RbacObject*s.
|
||||
|
||||
The primary key of the *RbacUser* is identical to its related *RbacReference*.
|
||||
The primary key of the *RbacSubject* is identical to its related *RbacReference*.
|
||||
|
||||
#### RbacRole
|
||||
|
||||
An *RbacRole* represents a collection of directly or indirectly assigned *RbacPermission*s.
|
||||
Each *RbacRole* can be assigned to *RbacUser*s or to another *RbacRole*.
|
||||
Each *RbacRole* can be assigned to *RbacSubject*s or to another *RbacRole*.
|
||||
|
||||
Both kinds of assignments are represented via *RbacGrant*.
|
||||
|
||||
@ -184,7 +184,7 @@ Only with this rule, the foreign key in *RbacPermission* can be defined as `NOT
|
||||
|
||||
#### RbacGrant
|
||||
|
||||
The *RbacGrant* entities represent the access-rights structure from *RbacUser*s via hierarchical *RbacRoles* down to *RbacPermission*s.
|
||||
The *RbacGrant* entities represent the access-rights structure from *RbacSubject*s via hierarchical *RbacRoles* down to *RbacPermission*s.
|
||||
|
||||
The core SQL queries to determine access rights are all recursive queries on the *RbacGrant* table.
|
||||
|
||||
@ -284,7 +284,7 @@ hide circle
|
||||
' use right-angled line routing
|
||||
' skinparam linetype ortho
|
||||
|
||||
package RbacUsers {
|
||||
package RbacSubjects {
|
||||
object UserMike
|
||||
object UserSuse
|
||||
object UserPaul
|
||||
@ -296,7 +296,7 @@ package RbacRoles {
|
||||
object RoleCustXyz_Admin
|
||||
object RolePackXyz00_Owner
|
||||
}
|
||||
RbacUsers -[hidden]> RbacRoles
|
||||
RbacSubjects -[hidden]> RbacRoles
|
||||
|
||||
package RbacPermissions {
|
||||
object PermCustXyz_SELECT
|
||||
@ -364,10 +364,10 @@ This way, each user can only select the data they have 'SELECT'-permission for,
|
||||
|
||||
### Current User
|
||||
|
||||
The current use is taken from the session variable `hsadminng.currentUser` which contains the name of the user as stored in the
|
||||
*RbacUser*s table. Example:
|
||||
The current use is taken from the session variable `hsadminng.currentSubject` which contains the name of the user as stored in the
|
||||
*RbacSubject*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.
|
||||
|
||||
@ -388,7 +388,7 @@ A full example is shown here:
|
||||
|
||||
BEGIN TRANSACTION;
|
||||
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';
|
||||
|
||||
SELECT c.prefix, p.name as "package", ema.localPart || '@' || dom.name as "email-address"
|
||||
@ -605,8 +605,8 @@ Find the SQL script here: `28-hs-tests.sql`.
|
||||
We have tested two variants of the query for the restricted view,
|
||||
both utilizing a PostgreSQL function like this:
|
||||
|
||||
FUNCTION queryAccessibleObjectUuidsOfSubjectIds(
|
||||
requiredOp RbacOp,
|
||||
FUNCTION rbac.queryAccessibleObjectUuidsOfSubjectIds(
|
||||
requiredOp rbac.RbacOp,
|
||||
forObjectTable varchar,
|
||||
subjectIds uuid[],
|
||||
maxObjects integer = 16000)
|
||||
@ -623,8 +623,8 @@ Let's have a look at the two view queries:
|
||||
FROM customer AS target
|
||||
WHERE target.uuid IN (
|
||||
SELECT uuid
|
||||
FROM queryAccessibleObjectUuidsOfSubjectIds(
|
||||
'SELECT, 'customer', currentSubjectsUuids()));
|
||||
FROM rbac.queryAccessibleObjectUuidsOfSubjectIds(
|
||||
'SELECT, 'customer', currentSubjectOrAssumedRolesUuids()));
|
||||
|
||||
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.
|
||||
@ -641,8 +641,8 @@ Looks like the query optimizer needed some statistics to find the best path.
|
||||
CREATE OR REPLACE VIEW customer_rv AS
|
||||
SELECT DISTINCT target.*
|
||||
FROM customer AS target
|
||||
JOIN queryAccessibleObjectUuidsOfSubjectIds(
|
||||
'SELECT, 'customer', currentSubjectsUuids()) AS allowedObjId
|
||||
JOIN rbac.queryAccessibleObjectUuidsOfSubjectIds(
|
||||
'SELECT, 'customer', currentSubjectOrAssumedRolesUuids()) AS allowedObjId
|
||||
ON target.uuid = allowedObjId;
|
||||
|
||||
This view cannot is not updatable automatically,
|
||||
@ -671,9 +671,9 @@ Access Control for business objects checked according to the assigned roles.
|
||||
But we decided not to create such roles and permissions for the RBAC-Objects itself.
|
||||
It would have overcomplicated the system and the necessary information can easily be added to the RBAC-Objects itself, mostly the `RbacGrant`s.
|
||||
|
||||
### RbacUser
|
||||
### RbacSubject
|
||||
|
||||
Users can self-register, thus to create a new RbacUser entity, no login is required.
|
||||
Users can self-register, thus to create a new RbacSubject entity, no login is required.
|
||||
But such a user has no access-rights except viewing itself.
|
||||
|
||||
Users can view themselves.
|
||||
|
@ -24,13 +24,13 @@ delete from hs_hosting_asset where uuid='5aea68d2-3b55-464f-8362-b05c76c5a681'::
|
||||
commit;
|
||||
|
||||
-- single version at point in time
|
||||
-- set hsadminng.tx_history_txid to (select max(txid) from tx_context where txtimestamp<='2024-08-27 12:13:13.450821');
|
||||
-- set hsadminng.tx_history_txid to (select max(txid) from base.tx_context where txtimestamp<='2024-08-27 12:13:13.450821');
|
||||
set hsadminng.tx_history_txid to '';
|
||||
set hsadminng.tx_history_timestamp to '2024-08-29 12:42';
|
||||
-- all versions
|
||||
select tx_history_txid(), txc.txtimestamp, txc.currentUser, txc.currentTask, haex.*
|
||||
select base.tx_history_txid(), txc.txtimestamp, txc.currentSubject, txc.currentTask, haex.*
|
||||
from hs_hosting_asset_ex haex
|
||||
join tx_context txc on haex.txid=txc.txid
|
||||
join base.tx_context txc on haex.txid=txc.txid
|
||||
where haex.identifier = 'test@thi.example.org';
|
||||
|
||||
select uuid, version, type, identifier, caption from hs_hosting_asset_hv p where identifier = 'test@thi.example.org';
|
||||
|
@ -3,28 +3,28 @@
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
||||
select isGranted(findRoleId('administrators'), findRoleId('test_package#aaa00:OWNER'));
|
||||
select isGranted(findRoleId('test_package#aaa00:OWNER'), findRoleId('administrators'));
|
||||
-- call grantRoleToRole(findRoleId('test_package#aaa00:OWNER'), findRoleId('administrators'));
|
||||
-- call grantRoleToRole(findRoleId('administrators'), findRoleId('test_package#aaa00:OWNER'));
|
||||
select rbac.isGranted(rbac.findRoleId('administrators'), rbac.findRoleId('test.package#aaa00:OWNER'));
|
||||
select rbac.isGranted(rbac.findRoleId('test.package#aaa00:OWNER'), rbac.findRoleId('administrators'));
|
||||
-- call rbac.grantRoleToRole(findRoleId('test.package#aaa00:OWNER'), findRoleId('administrators'));
|
||||
-- call rbac.grantRoleToRole(findRoleId('administrators'), findRoleId('test.package#aaa00:OWNER'));
|
||||
|
||||
select count(*)
|
||||
FROM queryAllPermissionsOfSubjectIdForObjectUuids(findRbacUser('superuser-fran@hostsharing.net'),
|
||||
ARRAY(select uuid from customer where reference < 1100000));
|
||||
FROM rbac.queryAllPermissionsOfSubjectIdForObjectUuids(rbac.findRbacSubject('superuser-fran@hostsharing.net'),
|
||||
ARRAY(select uuid from test.customer where reference < 1100000));
|
||||
select count(*)
|
||||
FROM queryAllPermissionsOfSubjectId(findRbacUser('superuser-fran@hostsharing.net'));
|
||||
FROM rbac.queryAllPermissionsOfSubjectId(findRbacSubject('superuser-fran@hostsharing.net'));
|
||||
select *
|
||||
FROM queryAllPermissionsOfSubjectId(findRbacUser('alex@example.com'));
|
||||
FROM rbac.queryAllPermissionsOfSubjectId(findRbacSubject('alex@example.com'));
|
||||
select *
|
||||
FROM queryAllPermissionsOfSubjectId(findRbacUser('rosa@example.com'));
|
||||
FROM rbac.queryAllPermissionsOfSubjectId(findRbacSubject('rosa@example.com'));
|
||||
|
||||
select *
|
||||
FROM queryAllRbacUsersWithPermissionsFor(findEffectivePermissionId('customer',
|
||||
(SELECT uuid FROM RbacObject WHERE objectTable = 'customer' LIMIT 1),
|
||||
FROM rbac.queryAllRbacSubjectsWithPermissionsFor(rbac.findEffectivePermissionId('customer',
|
||||
(SELECT uuid FROM rbac.RbacObject WHERE objectTable = 'customer' LIMIT 1),
|
||||
'add-package'));
|
||||
select *
|
||||
FROM queryAllRbacUsersWithPermissionsFor(findEffectivePermissionId('package',
|
||||
(SELECT uuid FROM RbacObject WHERE objectTable = 'package' LIMIT 1),
|
||||
FROM rbac.queryAllRbacSubjectsWithPermissionsFor(rbac.findEffectivePermissionId('package',
|
||||
(SELECT uuid FROM rbac.RbacObject WHERE objectTable = 'package' LIMIT 1),
|
||||
'DELETE'));
|
||||
|
||||
DO LANGUAGE plpgsql
|
||||
@ -33,13 +33,13 @@ $$
|
||||
userId uuid;
|
||||
result bool;
|
||||
BEGIN
|
||||
userId = findRbacUser('superuser-alex@hostsharing.net');
|
||||
result = (SELECT * FROM isPermissionGrantedToSubject(findPermissionId('package', 94928, 'add-package'), userId));
|
||||
userId = rbac.findRbacSubject('superuser-alex@hostsharing.net');
|
||||
result = (SELECT * FROM rbac.isPermissionGrantedToSubject(rbac.findPermissionId('package', 94928, 'add-package'), userId));
|
||||
IF (result) THEN
|
||||
RAISE EXCEPTION 'expected permission NOT to be granted, but it is';
|
||||
end if;
|
||||
|
||||
result = (SELECT * FROM isPermissionGrantedToSubject(findPermissionId('package', 94928, 'SELECT'), userId));
|
||||
result = (SELECT * FROM rbac.isPermissionGrantedToSubject(rbac.findPermissionId('package', 94928, 'SELECT'), userId));
|
||||
IF (NOT result) THEN
|
||||
RAISE EXCEPTION 'expected permission to be granted, but it is NOT';
|
||||
end if;
|
||||
|
@ -20,43 +20,43 @@ CREATE POLICY customer_policy ON customer
|
||||
TO restricted
|
||||
USING (
|
||||
-- id=1000
|
||||
isPermissionGrantedToSubject(findEffectivePermissionId('test_customer', id, 'SELECT'), currentUserUuid())
|
||||
rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('test.customer', id, 'SELECT'), rbac.currentSubjectUuid())
|
||||
);
|
||||
|
||||
SET SESSION AUTHORIZATION restricted;
|
||||
SET hsadminng.currentUser TO 'alex@example.com';
|
||||
SET hsadminng.currentSubject TO 'alex@example.com';
|
||||
SELECT * from customer;
|
||||
|
||||
-- access control via view-rule and isPermissionGrantedToSubject - way too slow (35 s 580 ms for 1 million rows)
|
||||
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||
DROP VIEW cust_view;
|
||||
CREATE VIEW cust_view AS
|
||||
SELECT * FROM customer;
|
||||
SELECT * FROM test.customer;
|
||||
CREATE OR REPLACE RULE "_RETURN" AS
|
||||
ON SELECT TO cust_view
|
||||
DO INSTEAD
|
||||
SELECT * FROM customer WHERE isPermissionGrantedToSubject(findEffectivePermissionId('test_customer', id, 'SELECT'), currentUserUuid());
|
||||
SELECT * FROM test.customer WHERE rbac.isPermissionGrantedToSubject(rbac.findEffectivePermissionId('test.customer', id, 'SELECT'), rbac.currentSubjectUuid());
|
||||
SELECT * from cust_view LIMIT 10;
|
||||
|
||||
select queryAllPermissionsOfSubjectId(findRbacUser('superuser-alex@hostsharing.net'));
|
||||
select rbac.queryAllPermissionsOfSubjectId(findRbacSubject('superuser-alex@hostsharing.net'));
|
||||
|
||||
-- access control via view-rule with join to recursive permissions - really fast (38ms for 1 million rows)
|
||||
SET SESSION SESSION AUTHORIZATION DEFAULT;
|
||||
ALTER TABLE customer ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE test.customer ENABLE ROW LEVEL SECURITY;
|
||||
DROP VIEW IF EXISTS cust_view;
|
||||
CREATE OR REPLACE VIEW cust_view AS
|
||||
SELECT *
|
||||
FROM customer;
|
||||
FROM test.customer;
|
||||
CREATE OR REPLACE RULE "_RETURN" AS
|
||||
ON SELECT TO cust_view
|
||||
DO INSTEAD
|
||||
SELECT c.uuid, c.reference, c.prefix FROM customer AS c
|
||||
JOIN queryAllPermissionsOfSubjectId(currentUserUuid()) AS p
|
||||
ON p.objectTable='test_customer' AND p.objectUuid=c.uuid;
|
||||
SELECT c.uuid, c.reference, c.prefix FROM test.customer AS c
|
||||
JOIN rbac.queryAllPermissionsOfSubjectId(rbac.currentSubjectUuid()) AS p
|
||||
ON p.objectTable='test.customer' AND p.objectUuid=c.uuid;
|
||||
GRANT ALL PRIVILEGES ON cust_view TO restricted;
|
||||
|
||||
SET SESSION SESSION AUTHORIZATION restricted;
|
||||
SET hsadminng.currentUser TO 'alex@example.com';
|
||||
SET hsadminng.currentSubject TO 'alex@example.com';
|
||||
SELECT * from cust_view;
|
||||
|
||||
|
||||
@ -67,23 +67,23 @@ DROP VIEW IF EXISTS cust_view;
|
||||
CREATE OR REPLACE VIEW cust_view AS
|
||||
SELECT c.uuid, c.reference, c.prefix
|
||||
FROM customer AS c
|
||||
JOIN queryAllPermissionsOfSubjectId(currentUserUuid()) AS p
|
||||
JOIN queryAllPermissionsOfSubjectId(rbac.currentSubjectUuid()) AS p
|
||||
ON p.objectUuid=c.uuid;
|
||||
GRANT ALL PRIVILEGES ON cust_view TO restricted;
|
||||
|
||||
SET SESSION SESSION AUTHORIZATION restricted;
|
||||
-- SET hsadminng.currentUser TO 'alex@example.com';
|
||||
SET hsadminng.currentUser TO 'superuser-alex@hostsharing.net';
|
||||
-- SET hsadminng.currentUser TO 'aaaaouq@example.com';
|
||||
-- SET hsadminng.currentSubject TO 'alex@example.com';
|
||||
SET hsadminng.currentSubject TO 'superuser-alex@hostsharing.net';
|
||||
-- SET hsadminng.currentSubject TO 'aaaaouq@example.com';
|
||||
SELECT * from cust_view where reference=1144150;
|
||||
|
||||
select rr.uuid, rr.type from RbacGrants g
|
||||
join RbacReference RR on g.ascendantUuid = RR.uuid
|
||||
select rr.uuid, rr.type from rbac.RbacGrants g
|
||||
join rbac.RbacReference RR on g.ascendantUuid = RR.uuid
|
||||
where g.descendantUuid in (
|
||||
select uuid from queryAllPermissionsOfSubjectId(findRbacUser('alex@example.com'))
|
||||
where objectTable='test_customer');
|
||||
select uuid from rbac.queryAllPermissionsOfSubjectId(findRbacSubject('alex@example.com'))
|
||||
where objectTable='test.customer');
|
||||
|
||||
call grantRoleToUser(findRoleId('test_customer#aaa:ADMIN'), findRbacUser('aaaaouq@example.com'));
|
||||
call rbac.grantRoleToUser(rbac.findRoleId('test.customer#aaa:ADMIN'), rbac.findRbacSubject('aaaaouq@example.com'));
|
||||
|
||||
select queryAllPermissionsOfSubjectId(findRbacUser('aaaaouq@example.com'));
|
||||
select rbac.queryAllPermissionsOfSubjectId(findRbacSubject('aaaaouq@example.com'));
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
-- just a permanent playground to explore optimization of the central recursive CTE query for RBAC
|
||||
|
||||
select * from hs_statistics_view;
|
||||
select * from hs_statistics_v;
|
||||
|
||||
-- ========================================================
|
||||
|
||||
@ -17,7 +17,7 @@ with recursive
|
||||
1 as level,
|
||||
true
|
||||
from rbacgrants
|
||||
where (rbacgrants.ascendantuuid = any (currentsubjectsuuids()))
|
||||
where (rbacgrants.ascendantuuid = any (rbac.currentSubjectOrAssumedRolesUuids()))
|
||||
and rbacgrants.assumed
|
||||
union all
|
||||
select distinct g.descendantuuid,
|
||||
|
@ -38,53 +38,53 @@ public class Context {
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Transactional(propagation = MANDATORY)
|
||||
public void define(final String currentUser) {
|
||||
define(currentUser, null);
|
||||
public void define(final String currentSubject) {
|
||||
define(currentSubject, null);
|
||||
}
|
||||
|
||||
@Transactional(propagation = MANDATORY)
|
||||
public void define(final String currentUser, final String assumedRoles) {
|
||||
define(toTask(request), toCurl(request), currentUser, assumedRoles);
|
||||
public void define(final String currentSubject, final String assumedRoles) {
|
||||
define(toTask(request), toCurl(request), currentSubject, assumedRoles);
|
||||
}
|
||||
|
||||
@Transactional(propagation = MANDATORY)
|
||||
public void define(
|
||||
final String currentTask,
|
||||
final String currentRequest,
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles) {
|
||||
final var query = em.createNativeQuery("""
|
||||
call defineContext(
|
||||
call base.defineContext(
|
||||
cast(:currentTask as varchar(127)),
|
||||
cast(:currentRequest as text),
|
||||
cast(:currentUser as varchar(63)),
|
||||
cast(:currentSubject as varchar(63)),
|
||||
cast(:assumedRoles as varchar(1023)));
|
||||
""");
|
||||
query.setParameter("currentTask", shortenToMaxLength(currentTask, 127));
|
||||
query.setParameter("currentRequest", currentRequest);
|
||||
query.setParameter("currentUser", currentUser);
|
||||
query.setParameter("currentSubject", currentSubject);
|
||||
query.setParameter("assumedRoles", assumedRoles != null ? assumedRoles : "");
|
||||
query.executeUpdate();
|
||||
}
|
||||
|
||||
public String getCurrentTask() {
|
||||
public String fetchCurrentTask() {
|
||||
return (String) em.createNativeQuery("select current_setting('hsadminng.currentTask');").getSingleResult();
|
||||
}
|
||||
|
||||
public String getCurrentUser() {
|
||||
return String.valueOf(em.createNativeQuery("select currentUser()").getSingleResult());
|
||||
public String fetchCurrentSubject() {
|
||||
return String.valueOf(em.createNativeQuery("select base.currentSubject()").getSingleResult());
|
||||
}
|
||||
|
||||
public UUID getCurrentUserUUid() {
|
||||
return (UUID) em.createNativeQuery("select currentUserUUid()", UUID.class).getSingleResult();
|
||||
public UUID fetchCurrentSubjectUuid() {
|
||||
return (UUID) em.createNativeQuery("select rbac.currentSubjectUuid()", UUID.class).getSingleResult();
|
||||
}
|
||||
|
||||
public String[] getAssumedRoles() {
|
||||
return (String[]) em.createNativeQuery("select assumedRoles() as roles", String[].class).getSingleResult();
|
||||
public String[] fetchAssumedRoles() {
|
||||
return (String[]) em.createNativeQuery("select base.assumedRoles() as roles", String[].class).getSingleResult();
|
||||
}
|
||||
|
||||
public UUID[] currentSubjectsUuids() {
|
||||
return (UUID[]) em.createNativeQuery("select currentSubjectsUuids() as uuids", UUID[].class).getSingleResult();
|
||||
public UUID[] fetchCurrentSubjectOrAssumedRolesUuids() {
|
||||
return (UUID[]) em.createNativeQuery("select rbac.currentSubjectOrAssumedRolesUuids() as uuids", UUID[].class).getSingleResult();
|
||||
}
|
||||
|
||||
public static String getCallerMethodNameFromStackFrame(final int skipFrames) {
|
||||
|
@ -14,7 +14,7 @@ import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
|
||||
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.Type;
|
||||
|
@ -41,10 +41,10 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsBookingItemResource>> listBookingItemsByProjectUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID projectUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = bookingItemRepo.findAllByProjectUuid(projectUuid);
|
||||
|
||||
@ -55,11 +55,11 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsBookingItemResource> addBookingItem(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final HsBookingItemInsertResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entityToSave = mapper.map(body, HsBookingItemRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
|
||||
@ -77,11 +77,11 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<HsBookingItemResource> getBookingItemByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID bookingItemUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = bookingItemRepo.findByUuid(bookingItemUuid);
|
||||
result.ifPresent(entity -> em.detach(entity)); // prevent further LAZY-loading
|
||||
@ -94,10 +94,10 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deleteBookingIemByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID bookingItemUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = bookingItemRepo.deleteByUuid(bookingItemUuid);
|
||||
return result == 0
|
||||
@ -108,12 +108,12 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsBookingItemResource> patchBookingItem(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID bookingItemUuid,
|
||||
final HsBookingItemPatchResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = bookingItemRepo.findByUuid(bookingItemUuid).orElseThrow();
|
||||
|
||||
|
@ -5,8 +5,8 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
|
||||
import jakarta.persistence.AttributeOverride;
|
||||
import jakarta.persistence.AttributeOverrides;
|
||||
@ -15,19 +15,20 @@ import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
import java.io.IOException;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NULLABLE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.DELETE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.OWNER;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_booking_item_rv")
|
||||
@ -45,8 +46,8 @@ public class HsBookingItemRbacEntity extends HsBookingItem {
|
||||
.withIdentityView(SQL.projection("caption"))
|
||||
.withRestrictedViewOrderBy(SQL.expression("validity"))
|
||||
.withUpdatableColumns("version", "caption", "validity", "resources")
|
||||
.toRole("global", ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
|
||||
.toRole("global", ADMIN).grantPermission(DELETE)
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(DELETE)
|
||||
|
||||
.importEntityAlias("project", HsBookingProject.class, usingDefaultCase(),
|
||||
dependsOnColumn("projectUuid"),
|
||||
@ -74,7 +75,7 @@ public class HsBookingItemRbacEntity extends HsBookingItem {
|
||||
with.permission(SELECT);
|
||||
})
|
||||
|
||||
.limitDiagramTo("bookingItem", "project", "global");
|
||||
.limitDiagramTo("bookingItem", "project", "rbac.global");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
@ -5,9 +5,9 @@ import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
@ -17,15 +17,16 @@ import java.util.UUID;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@MappedSuperclass
|
||||
@ -69,7 +70,7 @@ public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBo
|
||||
public static RbacView rbac() {
|
||||
return rbacViewFor("project", HsBookingProject.class)
|
||||
.withIdentityView(SQL.query("""
|
||||
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingProject.caption) as idName
|
||||
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || base.cleanIdentifier(bookingProject.caption) as idName
|
||||
FROM hs_booking_project bookingProject
|
||||
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
|
||||
"""))
|
||||
@ -91,7 +92,7 @@ public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBo
|
||||
"""),
|
||||
NOT_NULL)
|
||||
.toRole("debitorRel", ADMIN).grantPermission(INSERT)
|
||||
.toRole("global", ADMIN).grantPermission(DELETE)
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(DELETE)
|
||||
|
||||
.createRole(OWNER, (with) -> {
|
||||
with.incomingSuperRole("debitorRel", AGENT).unassumed();
|
||||
@ -105,7 +106,7 @@ public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBo
|
||||
with.permission(SELECT);
|
||||
})
|
||||
|
||||
.limitDiagramTo("project", "debitorRel", "global");
|
||||
.limitDiagramTo("project", "debitorRel", "rbac.global");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
@ -36,10 +36,10 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsBookingProjectResource>> listBookingProjectsByDebitorUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID debitorUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = bookingProjectRepo.findAllByDebitorUuid(debitorUuid);
|
||||
|
||||
@ -50,11 +50,11 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsBookingProjectResource> addBookingProject(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final HsBookingProjectInsertResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entityToSave = mapper.map(body, HsBookingProjectRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
|
||||
@ -72,11 +72,11 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<HsBookingProjectResource> getBookingProjectByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID bookingProjectUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = bookingProjectRepo.findByUuid(bookingProjectUuid);
|
||||
return result
|
||||
@ -88,10 +88,10 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deleteBookingIemByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID bookingProjectUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = bookingProjectRepo.deleteByUuid(bookingProjectUuid);
|
||||
return result == 0
|
||||
@ -102,12 +102,12 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsBookingProjectResource> patchBookingProject(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID bookingProjectUuid,
|
||||
final HsBookingProjectPatchResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = bookingProjectRepo.findByUuid(bookingProjectUuid).orElseThrow();
|
||||
|
||||
|
@ -6,29 +6,30 @@ import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
import java.io.IOException;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.DELETE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.OWNER;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_booking_project_rv")
|
||||
@ -41,7 +42,7 @@ public class HsBookingProjectRbacEntity extends HsBookingProject {
|
||||
public static RbacView rbac() {
|
||||
return rbacViewFor("project", HsBookingProjectRbacEntity.class)
|
||||
.withIdentityView(SQL.query("""
|
||||
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingProject.caption) as idName
|
||||
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || base.cleanIdentifier(bookingProject.caption) as idName
|
||||
FROM hs_booking_project bookingProject
|
||||
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
|
||||
"""))
|
||||
@ -63,7 +64,7 @@ public class HsBookingProjectRbacEntity extends HsBookingProject {
|
||||
"""),
|
||||
NOT_NULL)
|
||||
.toRole("debitorRel", ADMIN).grantPermission(INSERT)
|
||||
.toRole("global", ADMIN).grantPermission(DELETE)
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(DELETE)
|
||||
|
||||
.createRole(OWNER, (with) -> {
|
||||
with.incomingSuperRole("debitorRel", AGENT).unassumed();
|
||||
@ -77,7 +78,7 @@ public class HsBookingProjectRbacEntity extends HsBookingProject {
|
||||
with.permission(SELECT);
|
||||
})
|
||||
|
||||
.limitDiagramTo("project", "debitorRel", "global");
|
||||
.limitDiagramTo("project", "debitorRel", "rbac.global");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
@ -14,7 +14,7 @@ import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
|
||||
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.Type;
|
||||
|
@ -49,12 +49,12 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsHostingAssetResource>> listAssets(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID debitorUuid,
|
||||
final UUID parentAssetUuid,
|
||||
final HsHostingAssetTypeResource type) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = rbacAssetRepo.findAllByCriteria(debitorUuid, parentAssetUuid, HsHostingAssetType.of(type));
|
||||
|
||||
@ -66,11 +66,11 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsHostingAssetResource> addAsset(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final HsHostingAssetInsertResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entity = mapper.map(body, HsHostingAssetRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
|
||||
@ -94,11 +94,11 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<HsHostingAssetResource> getAssetByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID assetUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = rbacAssetRepo.findByUuid(assetUuid);
|
||||
return result
|
||||
@ -110,10 +110,10 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deleteAssetUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID assetUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = rbacAssetRepo.deleteByUuid(assetUuid);
|
||||
return result == 0
|
||||
@ -124,12 +124,12 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsHostingAssetResource> patchAsset(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID assetUuid,
|
||||
final HsHostingAssetPatchResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entity = rbacAssetRepo.findByUuid(assetUuid).orElseThrow();
|
||||
|
||||
|
@ -6,31 +6,31 @@ import lombok.Setter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
import java.io.IOException;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inCaseOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.GUEST;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.REFERRER;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.CaseDef.inCaseOf;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NULLABLE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.DELETE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.GUEST;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.OWNER;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.REFERRER;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_hosting_asset_rv")
|
||||
@ -106,7 +106,7 @@ public class HsHostingAssetRbacEntity extends HsHostingAsset {
|
||||
"parentAsset",
|
||||
"assignedToAsset",
|
||||
"alarmContact",
|
||||
"global");
|
||||
"rbac.global");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
@ -32,10 +32,10 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsOfficeBankAccountResource>> listBankAccounts(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final String holder) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = bankAccountRepo.findByOptionalHolderLike(holder);
|
||||
|
||||
@ -46,11 +46,11 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeBankAccountResource> addBankAccount(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final HsOfficeBankAccountInsertResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
IbanUtil.validate(body.getIban());
|
||||
BicUtil.validate(body.getBic());
|
||||
@ -72,11 +72,11 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<HsOfficeBankAccountResource> getBankAccountByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID bankAccountUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = bankAccountRepo.findByUuid(bankAccountUuid);
|
||||
if (result.isEmpty()) {
|
||||
@ -88,10 +88,10 @@ public class HsOfficeBankAccountController implements HsOfficeBankAccountsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deleteBankAccountByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID BankAccountUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = bankAccountRepo.deleteByUuid(BankAccountUuid);
|
||||
if (result == 0) {
|
||||
|
@ -3,8 +3,8 @@ package net.hostsharing.hsadminng.hs.office.bankaccount;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
@ -12,10 +12,10 @@ import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@ -62,7 +62,7 @@ public class HsOfficeBankAccountEntity implements BaseEntity<HsOfficeBankAccount
|
||||
.withIdentityView(SQL.projection("iban"))
|
||||
.withUpdatableColumns("holder", "iban", "bic")
|
||||
|
||||
.toRole("global", GUEST).grantPermission(INSERT)
|
||||
.toRole(GLOBAL, GUEST).grantPermission(INSERT)
|
||||
|
||||
.createRole(OWNER, (with) -> {
|
||||
with.owningUser(CREATOR);
|
||||
|
@ -11,7 +11,7 @@ import lombok.experimental.FieldNameConstants;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
|
@ -34,10 +34,10 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsOfficeContactResource>> listContacts(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final String caption) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = contactRepo.findContactByOptionalCaptionLike(caption);
|
||||
|
||||
@ -48,11 +48,11 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeContactResource> addContact(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final HsOfficeContactInsertResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entityToSave = mapper.map(body, HsOfficeContactRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
|
||||
@ -70,11 +70,11 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<HsOfficeContactResource> getContactByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID contactUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = contactRepo.findByUuid(contactUuid);
|
||||
if (result.isEmpty()) {
|
||||
@ -86,10 +86,10 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deleteContactByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID contactUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = contactRepo.deleteByUuid(contactUuid);
|
||||
if (result == 0) {
|
||||
@ -102,12 +102,12 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeContactResource> patchContact(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID contactUuid,
|
||||
final HsOfficeContactPatchResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = contactRepo.findByUuid(contactUuid).orElseThrow();
|
||||
|
||||
|
@ -3,17 +3,17 @@ package net.hostsharing.hsadminng.hs.office.contact;
|
||||
import lombok.*;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_contact_rv")
|
||||
|
@ -37,12 +37,12 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsOfficeCoopAssetsTransactionResource>> listCoopAssets(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID membershipUuid,
|
||||
final @DateTimeFormat(iso = ISO.DATE) LocalDate fromValueDate,
|
||||
final @DateTimeFormat(iso = ISO.DATE) LocalDate toValueDate) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = coopAssetsTransactionRepo.findCoopAssetsTransactionByOptionalMembershipUuidAndDateRange(
|
||||
membershipUuid,
|
||||
@ -56,11 +56,11 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeCoopAssetsTransactionResource> addCoopAssetsTransaction(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final HsOfficeCoopAssetsTransactionInsertResource requestBody) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
validate(requestBody);
|
||||
|
||||
final var entityToSave = mapper.map(requestBody, HsOfficeCoopAssetsTransactionEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
@ -79,9 +79,9 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
|
||||
@Transactional(readOnly = true)
|
||||
|
||||
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);
|
||||
if (result.isEmpty()) {
|
||||
|
@ -8,8 +8,8 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
@ -21,16 +21,16 @@ import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
|
@ -39,12 +39,12 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsOfficeCoopSharesTransactionResource>> listCoopShares(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID membershipUuid,
|
||||
final @DateTimeFormat(iso = ISO.DATE) LocalDate fromValueDate,
|
||||
final @DateTimeFormat(iso = ISO.DATE) LocalDate toValueDate) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = coopSharesTransactionRepo.findCoopSharesTransactionByOptionalMembershipUuidAndDateRange(
|
||||
membershipUuid,
|
||||
@ -58,11 +58,11 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeCoopSharesTransactionResource> addCoopSharesTransaction(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final HsOfficeCoopSharesTransactionInsertResource requestBody) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
validate(requestBody);
|
||||
|
||||
final var entityToSave = mapper.map(requestBody, HsOfficeCoopSharesTransactionEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
@ -81,9 +81,9 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
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);
|
||||
if (result.isEmpty()) {
|
||||
|
@ -7,9 +7,9 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
@ -19,16 +19,16 @@ import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
|
@ -8,7 +8,7 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebito
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -48,11 +48,11 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsOfficeDebitorResource>> listDebitors(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final String name,
|
||||
final Integer debitorNumber) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = debitorNumber != null
|
||||
? debitorRepo.findDebitorByDebitorNumber(debitorNumber)
|
||||
@ -65,11 +65,11 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeDebitorResource> addDebitor(
|
||||
String currentUser,
|
||||
String currentSubject,
|
||||
String assumedRoles,
|
||||
HsOfficeDebitorInsertResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
Validate.isTrue(body.getDebitorRel() == null || body.getDebitorRelUuid() == null,
|
||||
"ERROR: [400] exactly one of debitorRel and debitorRelUuid must be supplied, but found both");
|
||||
@ -112,11 +112,11 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<HsOfficeDebitorResource> getDebitorByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID debitorUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = debitorRepo.findByUuid(debitorUuid);
|
||||
if (result.isEmpty()) {
|
||||
@ -128,10 +128,10 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deleteDebitorByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID debitorUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = debitorRepo.deleteByUuid(debitorUuid);
|
||||
if (result == 0) {
|
||||
@ -144,12 +144,12 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeDebitorResource> patchDebitor(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID debitorUuid,
|
||||
final HsOfficeDebitorPatchResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = debitorRepo.findByUuid(debitorUuid).orElseThrow();
|
||||
|
||||
|
@ -11,9 +11,9 @@ import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
@ -40,16 +40,17 @@ import static jakarta.persistence.CascadeType.PERSIST;
|
||||
import static jakarta.persistence.CascadeType.REFRESH;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NULLABLE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@ -188,7 +189,7 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
|
||||
"vatBusiness",
|
||||
"vatReverseCharge",
|
||||
"defaultPrefix")
|
||||
.toRole("global", ADMIN).grantPermission(INSERT)
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
|
||||
|
||||
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationRbacEntity.class, usingCase(DEBITOR),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
|
@ -32,11 +32,11 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsOfficeMembershipResource>> listMemberships(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
UUID partnerUuid,
|
||||
Integer memberNumber) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = ( memberNumber != null)
|
||||
? List.of(membershipRepo.findMembershipByMemberNumber(memberNumber))
|
||||
@ -50,11 +50,11 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeMembershipResource> addMembership(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final HsOfficeMembershipInsertResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entityToSave = mapper.map(body, HsOfficeMembershipEntity.class);
|
||||
|
||||
@ -73,11 +73,11 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<HsOfficeMembershipResource> getMembershipByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID membershipUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = membershipRepo.findByUuid(membershipUuid);
|
||||
if (result.isEmpty()) {
|
||||
@ -90,10 +90,10 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deleteMembershipByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID membershipUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = membershipRepo.deleteByUuid(membershipUuid);
|
||||
if (result == 0) {
|
||||
@ -106,12 +106,12 @@ public class HsOfficeMembershipController implements HsOfficeMembershipsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeMembershipResource> patchMembership(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID membershipUuid,
|
||||
final HsOfficeMembershipPatchResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = membershipRepo.findByUuid(membershipUuid).orElseThrow();
|
||||
|
||||
|
@ -9,10 +9,10 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.Type;
|
||||
@ -38,20 +38,21 @@ import static io.hypersistence.utils.hibernate.type.range.Range.emptyRange;
|
||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.lowerInclusiveFromPostgresDateRange;
|
||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.upperInclusiveFromPostgresDateRange;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.DELETE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.OWNER;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.fetchedBySql;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@ -174,7 +175,7 @@ public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEn
|
||||
WHERE partner.uuid = ${REF}.partnerUuid
|
||||
"""),
|
||||
NOT_NULL)
|
||||
.toRole("global", ADMIN).grantPermission(INSERT)
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
|
||||
|
||||
.createRole(OWNER, (with) -> {
|
||||
with.owningUser(CREATOR);
|
||||
|
@ -13,7 +13,7 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@ -50,10 +50,10 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsOfficePartnerResource>> listPartners(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final String name) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = partnerRepo.findPartnerByOptionalNameLike(name);
|
||||
|
||||
@ -64,11 +64,11 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficePartnerResource> addPartner(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final HsOfficePartnerInsertResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entityToSave = createPartnerEntity(body);
|
||||
|
||||
@ -86,11 +86,11 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<HsOfficePartnerResource> getPartnerByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID partnerUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = partnerRepo.findByUuid(partnerUuid);
|
||||
if (result.isEmpty()) {
|
||||
@ -102,10 +102,10 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deletePartnerByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID partnerUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var partnerToDelete = partnerRepo.findByUuid(partnerUuid);
|
||||
if (partnerToDelete.isEmpty()) {
|
||||
@ -122,12 +122,12 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficePartnerResource> patchPartner(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID partnerUuid,
|
||||
final HsOfficePartnerPatchResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = partnerRepo.findByUuid(partnerUuid).orElseThrow();
|
||||
final var previousPartnerRel = current.getPartnerRel();
|
||||
|
@ -2,9 +2,9 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
@ -13,9 +13,10 @@ import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@ -82,7 +83,7 @@ public class HsOfficePartnerDetailsEntity implements BaseEntity<HsOfficePartnerD
|
||||
"birthName",
|
||||
"birthday",
|
||||
"dateOfDeath")
|
||||
.toRole("global", ADMIN).grantPermission(INSERT)
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
|
||||
|
||||
// The grants are defined in HsOfficePartnerEntity.rbac()
|
||||
// because they have to be changed when its partnerRel changes,
|
||||
|
@ -10,10 +10,10 @@ import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.NotFound;
|
||||
@ -24,13 +24,14 @@ import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import static jakarta.persistence.CascadeType.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@ -103,7 +104,7 @@ public class HsOfficePartnerEntity implements Stringifyable, BaseEntity<HsOffice
|
||||
return rbacViewFor("partner", HsOfficePartnerEntity.class)
|
||||
.withIdentityView(SQL.projection("'P-' || partnerNumber"))
|
||||
.withUpdatableColumns("partnerRelUuid")
|
||||
.toRole("global", ADMIN).grantPermission(INSERT)
|
||||
.toRole(GLOBAL, ADMIN).grantPermission(INSERT)
|
||||
|
||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationRbacEntity.class,
|
||||
usingDefaultCase(),
|
||||
|
@ -31,10 +31,10 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsOfficePersonResource>> listPersons(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final String caption) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = personRepo.findPersonByOptionalNameLike(caption);
|
||||
|
||||
@ -45,11 +45,11 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficePersonResource> addPerson(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final HsOfficePersonInsertResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entityToSave = mapper.map(body, HsOfficePersonEntity.class);
|
||||
|
||||
@ -67,11 +67,11 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<HsOfficePersonResource> getPersonByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID personUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = personRepo.findByUuid(personUuid);
|
||||
if (result.isEmpty()) {
|
||||
@ -83,10 +83,10 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deletePersonByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID personUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = personRepo.deleteByUuid(personUuid);
|
||||
if (result == 0) {
|
||||
@ -99,12 +99,12 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficePersonResource> patchPerson(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID personUuid,
|
||||
final HsOfficePersonPatchResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = personRepo.findByUuid(personUuid).orElseThrow();
|
||||
|
||||
|
@ -3,9 +3,9 @@ package net.hostsharing.hsadminng.hs.office.person;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -14,11 +14,11 @@ import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
@ -80,7 +80,7 @@ public class HsOfficePersonEntity implements BaseEntity<HsOfficePersonEntity>, S
|
||||
return rbacViewFor("person", HsOfficePersonEntity.class)
|
||||
.withIdentityView(SQL.projection("concat(tradeName, familyName, givenName)"))
|
||||
.withUpdatableColumns("personType", "title", "salutation", "tradeName", "givenName", "familyName")
|
||||
.toRole("global", GUEST).grantPermission(INSERT)
|
||||
.toRole(GLOBAL, GUEST).grantPermission(INSERT)
|
||||
|
||||
.createRole(OWNER, (with) -> {
|
||||
with.permission(DELETE);
|
||||
|
@ -5,7 +5,7 @@ import lombok.experimental.FieldNameConstants;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
|
@ -45,11 +45,11 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsOfficeRelationResource>> listRelations(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID personUuid,
|
||||
final HsOfficeRelationTypeResource relationType) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = relationRbacRepo.findRelationRelatedToPersonUuidAndRelationType(personUuid,
|
||||
mapper.map(relationType, HsOfficeRelationType.class));
|
||||
@ -62,11 +62,11 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeRelationResource> addRelation(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final HsOfficeRelationInsertResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entityToSave = new HsOfficeRelationRbacEntity();
|
||||
entityToSave.setType(HsOfficeRelationType.valueOf(body.getType()));
|
||||
@ -96,11 +96,11 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<HsOfficeRelationResource> getRelationByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID relationUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = relationRbacRepo.findByUuid(relationUuid);
|
||||
if (result.isEmpty()) {
|
||||
@ -112,10 +112,10 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deleteRelationByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID relationUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = relationRbacRepo.deleteByUuid(relationUuid);
|
||||
if (result == 0) {
|
||||
@ -128,12 +128,12 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeRelationResource> patchRelation(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID relationUuid,
|
||||
final HsOfficeRelationPatchResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = relationRbacRepo.findByUuid(relationUuid).orElseThrow();
|
||||
|
||||
|
@ -7,31 +7,31 @@ import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
import java.io.IOException;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inCaseOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inOtherCases;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.REFERRER;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.CaseDef.inCaseOf;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.CaseDef.inOtherCases;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.DELETE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.SELECT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.UPDATE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.AGENT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.OWNER;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.REFERRER;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.TENANT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(name = "hs_office_relation_rv")
|
||||
|
@ -39,10 +39,10 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<HsOfficeSepaMandateResource>> listSepaMandatesByIban(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final String iban) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = sepaMandateRepo.findSepaMandateByOptionalIban(iban);
|
||||
|
||||
@ -54,11 +54,11 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeSepaMandateResource> addSepaMandate(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
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);
|
||||
|
||||
@ -77,11 +77,11 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<HsOfficeSepaMandateResource> getSepaMandateByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID sepaMandateUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = sepaMandateRepo.findByUuid(sepaMandateUuid);
|
||||
if (result.isEmpty()) {
|
||||
@ -94,10 +94,10 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deleteSepaMandateByUuid(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID sepaMandateUuid) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = sepaMandateRepo.deleteByUuid(sepaMandateUuid);
|
||||
if (result == 0) {
|
||||
@ -110,12 +110,12 @@ public class HsOfficeSepaMandateController implements HsOfficeSepaMandatesApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<HsOfficeSepaMandateResource> patchSepaMandate(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID sepaMandateUuid,
|
||||
final HsOfficeSepaMandatePatchResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = sepaMandateRepo.findByUuid(sepaMandateUuid).orElseThrow();
|
||||
|
||||
|
@ -7,8 +7,8 @@ import net.hostsharing.hsadminng.errors.DisplayAs;
|
||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.Type;
|
||||
@ -20,16 +20,16 @@ import java.util.UUID;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
|
||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
@Entity
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@ -6,12 +6,12 @@ import java.util.function.BinaryOperator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.NEW;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.GUEST;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.PostgresTriggerReference.NEW;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.ADMIN;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.GUEST;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
|
||||
import static org.apache.commons.lang3.StringUtils.capitalize;
|
||||
import static org.apache.commons.lang3.StringUtils.uncapitalize;
|
||||
|
||||
@ -46,7 +46,7 @@ public class InsertTriggerGenerator {
|
||||
private void generateInsertPermissionGrants(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("""
|
||||
-- ============================================================================
|
||||
--changeset ${liquibaseTagPrefix}-rbac-GRANTING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||
--changeset InsertTriggerGenerator:${liquibaseTagPrefix}-rbac-GRANTING-INSERT-PERMISSION endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
""",
|
||||
with("liquibaseTagPrefix", liquibaseTagPrefix));
|
||||
@ -55,7 +55,7 @@ public class InsertTriggerGenerator {
|
||||
plPgSql.writeLn("""
|
||||
-- granting INSERT permission to ${rawSubTable} ----------------------------
|
||||
""",
|
||||
with("rawSubTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()));
|
||||
with("rawSubTable", g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema()));
|
||||
|
||||
if (isGrantToADifferentTable(g)) {
|
||||
plPgSql.writeLn(
|
||||
@ -67,13 +67,13 @@ public class InsertTriggerGenerator {
|
||||
declare
|
||||
row ${rawSuperTable};
|
||||
begin
|
||||
call defineContext('create INSERT INTO ${rawSubTable} permissions for pre-exising ${rawSuperTable} rows');
|
||||
call base.defineContext('create INSERT INTO ${rawSubTable} permissions for pre-exising ${rawSuperTable} rows');
|
||||
|
||||
FOR row IN SELECT * FROM ${rawSuperTable}
|
||||
${whenCondition}
|
||||
LOOP
|
||||
call grantPermissionToRole(
|
||||
createPermission(row.uuid, 'INSERT', '${rawSubTable}'),
|
||||
call rbac.grantPermissionToRole(
|
||||
rbac.createPermission(row.uuid, 'INSERT', '${rawSubTable}'),
|
||||
${superRoleRef});
|
||||
END LOOP;
|
||||
end;
|
||||
@ -84,40 +84,40 @@ public class InsertTriggerGenerator {
|
||||
? "WHERE type = '${value}'"
|
||||
.replace("${value}", g.getSuperRoleDef().getEntityAlias().usingCase().value)
|
||||
: "-- unconditional for all rows in that table"),
|
||||
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
||||
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()),
|
||||
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema()),
|
||||
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableNameWithSchema()),
|
||||
with("superRoleRef", toRoleDescriptor(g.getSuperRoleDef(), "row")));
|
||||
} else {
|
||||
plPgSql.writeLn("""
|
||||
-- Granting INSERT INTO hs_hosting_asset permissions to specified role of pre-existing hs_hosting_asset rows slipped,
|
||||
-- because there cannot yet be any pre-existing rows in the same table yet.
|
||||
""",
|
||||
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
||||
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()));
|
||||
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema()),
|
||||
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableNameWithSchema()));
|
||||
}
|
||||
|
||||
plPgSql.writeLn("""
|
||||
/**
|
||||
Grants ${rawSubTable} INSERT permission to specified role of new ${rawSuperTable} rows.
|
||||
*/
|
||||
create or replace function new_${rawSubTable}_grants_insert_to_${rawSuperTable}_tf()
|
||||
create or replace function ${rawSuperTableSchemaName}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
${ifConditionThen}
|
||||
call grantPermissionToRole(
|
||||
createPermission(NEW.uuid, 'INSERT', '${rawSubTable}'),
|
||||
call rbac.grantPermissionToRole(
|
||||
rbac.createPermission(NEW.uuid, 'INSERT', '${rawSubTable}'),
|
||||
${superRoleRef});
|
||||
${ifConditionEnd}
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
|
||||
-- z_... is to put it at the end of after insert triggers, to make sure the roles exist
|
||||
create trigger z_new_${rawSubTable}_grants_insert_to_${rawSuperTable}_tg
|
||||
after insert on ${rawSuperTable}
|
||||
create trigger z_new_${rawSubTable}_grants_after_insert_tg
|
||||
after insert on ${rawSuperTableWithSchema}
|
||||
for each row
|
||||
execute procedure new_${rawSubTable}_grants_insert_to_${rawSuperTable}_tf();
|
||||
execute procedure ${rawSuperTableSchemaName}new_${rawSubTableShortName}_grants_insert_to_${rawSuperTableShortName}_tf();
|
||||
""",
|
||||
with("ifConditionThen", g.getSuperRoleDef().getEntityAlias().isCaseDependent()
|
||||
// TODO.impl: .type needs to be dynamically generated
|
||||
@ -127,8 +127,12 @@ public class InsertTriggerGenerator {
|
||||
? "end if;"
|
||||
: "-- end."),
|
||||
with("superRoleRef", toRoleDescriptor(g.getSuperRoleDef(), NEW.name())),
|
||||
with("rawSuperTableWithSchema", g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema()),
|
||||
with("rawSuperTableShortName", g.getSuperRoleDef().getEntityAlias().getRawTableShortName()),
|
||||
with("rawSuperTable", g.getSuperRoleDef().getEntityAlias().getRawTableName()),
|
||||
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableName()));
|
||||
with("rawSuperTableSchemaName", g.getSuperRoleDef().getEntityAlias().getRawTableSchemaPrefix()),
|
||||
with("rawSubTable", g.getPermDef().getEntityAlias().getRawTableNameWithSchema()),
|
||||
with("rawSubTableShortName", g.getPermDef().getEntityAlias().getRawTableShortName()));
|
||||
|
||||
});
|
||||
}
|
||||
@ -136,7 +140,7 @@ public class InsertTriggerGenerator {
|
||||
private void generateInsertPermissionTriggerAlwaysDisallow(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("""
|
||||
-- ============================================================================
|
||||
--changeset ${liquibaseTagPrefix}-rbac-ALWAYS-DISALLOW-INSERT:1 endDelimiter:--//
|
||||
--changeset InsertTriggerGenerator:${liquibaseTagPrefix}-rbac-ALWAYS-DISALLOW-INSERT endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
""",
|
||||
with("liquibaseTagPrefix", liquibaseTagPrefix));
|
||||
@ -152,13 +156,13 @@ public class InsertTriggerGenerator {
|
||||
begin
|
||||
raise exception '[403] insert into ${rawSubTable} values(%) not allowed regardless of current subject, no insert permissions granted at all', NEW;
|
||||
end; $$;
|
||||
|
||||
|
||||
create trigger ${rawSubTable}_insert_permission_check_tg
|
||||
before insert on ${rawSubTable}
|
||||
for each row
|
||||
execute procedure ${rawSubTable}_insert_permission_missing_tf();
|
||||
""",
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
|
||||
|
||||
plPgSql.writeLn("--//");
|
||||
}
|
||||
@ -179,7 +183,7 @@ public class InsertTriggerGenerator {
|
||||
private void generateInsertPermissionsCheckHeader(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("""
|
||||
-- ============================================================================
|
||||
--changeset ${rawSubTable}-rbac-CHECKING-INSERT-PERMISSION:1 endDelimiter:--//
|
||||
--changeset InsertTriggerGenerator:${rawSubTable}-rbac-CHECKING-INSERT-PERMISSION endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@ -192,7 +196,7 @@ public class InsertTriggerGenerator {
|
||||
superObjectUuid uuid;
|
||||
begin
|
||||
""",
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
|
||||
plPgSql.chopEmptyLines();
|
||||
}
|
||||
|
||||
@ -206,7 +210,7 @@ public class InsertTriggerGenerator {
|
||||
if (g.getSuperRoleDef().isGlobal(GUEST)) {
|
||||
plPgSql.writeLn(
|
||||
"""
|
||||
-- check INSERT INSERT permission for global anyone
|
||||
-- check INSERT INSERT permission for rbac.global anyone
|
||||
if ${caseCondition}true then
|
||||
return NEW;
|
||||
end if;
|
||||
@ -215,8 +219,8 @@ public class InsertTriggerGenerator {
|
||||
} else if (g.getSuperRoleDef().isGlobal(ADMIN)) {
|
||||
plPgSql.writeLn(
|
||||
"""
|
||||
-- check INSERT INSERT if global ADMIN
|
||||
if ${caseCondition}isGlobalAdmin() then
|
||||
-- check INSERT INSERT if rbac.global ADMIN
|
||||
if ${caseCondition}rbac.isGlobalAdmin() then
|
||||
return NEW;
|
||||
end if;
|
||||
""",
|
||||
@ -225,25 +229,25 @@ public class InsertTriggerGenerator {
|
||||
plPgSql.writeLn(
|
||||
"""
|
||||
-- check INSERT permission via direct foreign key: NEW.${refColumn}
|
||||
if ${caseCondition}hasInsertPermission(NEW.${refColumn}, '${rawSubTable}') then
|
||||
if ${caseCondition}rbac.hasInsertPermission(NEW.${refColumn}, '${rawSubTable}') then
|
||||
return NEW;
|
||||
end if;
|
||||
""",
|
||||
with("caseCondition", caseCondition),
|
||||
with("refColumn", superRoleEntityAlias.dependsOnColumName()),
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
|
||||
} else {
|
||||
plPgSql.writeLn(
|
||||
"""
|
||||
-- check INSERT permission via indirect foreign key: NEW.${refColumn}
|
||||
superObjectUuid := (${fetchSql});
|
||||
assert superObjectUuid is not null, 'object uuid fetched depending on ${rawSubTable}.${refColumn} must not be null, also check fetchSql in RBAC DSL';
|
||||
if ${caseCondition}hasInsertPermission(superObjectUuid, '${rawSubTable}') then
|
||||
if ${caseCondition}rbac.hasInsertPermission(superObjectUuid, '${rawSubTable}') then
|
||||
return NEW;
|
||||
end if;
|
||||
""",
|
||||
with("caseCondition", caseCondition),
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()),
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()),
|
||||
with("refColumn", superRoleEntityAlias.dependsOnColumName()),
|
||||
with("fetchSql", g.getSuperRoleDef().getEntityAlias().fetchSql().sql),
|
||||
with("columns", g.getSuperRoleDef().getEntityAlias().aliasName() + ".uuid"),
|
||||
@ -255,7 +259,7 @@ public class InsertTriggerGenerator {
|
||||
plPgSql.writeLn();
|
||||
plPgSql.writeLn("""
|
||||
raise exception '[403] insert into ${rawSubTable} values(%) not allowed for current subjects % (%)',
|
||||
NEW, currentSubjects(), currentSubjectsUuids();
|
||||
NEW, base.currentSubjects(), rbac.currentSubjectOrAssumedRolesUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger ${rawSubTable}_insert_permission_check_tg
|
||||
@ -264,7 +268,7 @@ public class InsertTriggerGenerator {
|
||||
execute procedure ${rawSubTable}_insert_permission_check_tf();
|
||||
--//
|
||||
""",
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableName()));
|
||||
with("rawSubTable", rbacDef.getRootEntityAlias().getRawTableNameWithSchema()));
|
||||
}
|
||||
|
||||
private String toStringList(final Set<RbacView.CaseDef> cases) {
|
||||
@ -272,7 +276,7 @@ public class InsertTriggerGenerator {
|
||||
}
|
||||
|
||||
private boolean isGrantToADifferentTable(final RbacView.RbacGrantDefinition g) {
|
||||
return !rbacDef.getRootEntityAlias().getRawTableName().equals(g.getSuperRoleDef().getEntityAlias().getRawTableName());
|
||||
return !rbacDef.getRootEntityAlias().getRawTableNameWithSchema().equals(g.getSuperRoleDef().getEntityAlias().getRawTableNameWithSchema());
|
||||
}
|
||||
|
||||
private Stream<RbacView.RbacGrantDefinition> getInsertGrants() {
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
public enum PostgresTriggerReference {
|
||||
NEW, OLD
|
@ -1,6 +1,6 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
|
||||
|
||||
public class RbacIdentityViewGenerator {
|
||||
private final RbacView rbacDef;
|
||||
@ -12,13 +12,13 @@ public class RbacIdentityViewGenerator {
|
||||
this.rbacDef = rbacDef;
|
||||
this.liquibaseTagPrefix = liquibaseTagPrefix;
|
||||
this.simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
|
||||
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
|
||||
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
|
||||
}
|
||||
|
||||
void generateTo(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("""
|
||||
-- ============================================================================
|
||||
--changeset ${liquibaseTagPrefix}-rbac-IDENTITY-VIEW:1 endDelimiter:--//
|
||||
--changeset RbacIdentityViewGenerator:${liquibaseTagPrefix}-rbac-IDENTITY-VIEW endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
""",
|
||||
with("liquibaseTagPrefix", liquibaseTagPrefix));
|
||||
@ -26,13 +26,13 @@ public class RbacIdentityViewGenerator {
|
||||
plPgSql.writeLn(
|
||||
switch (rbacDef.getIdentityViewSqlQuery().part) {
|
||||
case SQL_PROJECTION -> """
|
||||
call generateRbacIdentityViewFromProjection('${rawTableName}',
|
||||
call rbac.generateRbacIdentityViewFromProjection('${rawTableName}',
|
||||
$idName$
|
||||
${identityViewSqlPart}
|
||||
$idName$);
|
||||
""";
|
||||
case SQL_QUERY -> """
|
||||
call generateRbacIdentityViewFromQuery('${rawTableName}',
|
||||
call rbac.generateRbacIdentityViewFromQuery('${rawTableName}',
|
||||
$idName$
|
||||
${identityViewSqlPart}
|
||||
$idName$);
|
@ -1,6 +1,6 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
|
||||
|
||||
public class RbacObjectGenerator {
|
||||
|
||||
@ -9,17 +9,17 @@ public class RbacObjectGenerator {
|
||||
|
||||
public RbacObjectGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) {
|
||||
this.liquibaseTagPrefix = liquibaseTagPrefix;
|
||||
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
|
||||
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
|
||||
}
|
||||
|
||||
void generateTo(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("""
|
||||
-- ============================================================================
|
||||
--changeset ${liquibaseTagPrefix}-rbac-OBJECT:1 endDelimiter:--//
|
||||
--changeset RbacObjectGenerator:${liquibaseTagPrefix}-rbac-OBJECT endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRelatedRbacObject('${rawTableName}');
|
||||
call rbac.generateRelatedRbacObject('${rawTableName}');
|
||||
--//
|
||||
|
||||
|
||||
""",
|
||||
with("liquibaseTagPrefix", liquibaseTagPrefix),
|
||||
with("rawTableName", rawTableName));
|
@ -1,9 +1,9 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.indented;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.indented;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
|
||||
|
||||
public class RbacRestrictedViewGenerator {
|
||||
private final RbacView rbacDef;
|
||||
@ -13,15 +13,15 @@ public class RbacRestrictedViewGenerator {
|
||||
public RbacRestrictedViewGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) {
|
||||
this.rbacDef = rbacDef;
|
||||
this.liquibaseTagPrefix = liquibaseTagPrefix;
|
||||
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
|
||||
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
|
||||
}
|
||||
|
||||
void generateTo(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("""
|
||||
-- ============================================================================
|
||||
--changeset ${liquibaseTagPrefix}-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||
--changeset RbacRestrictedViewGenerator:${liquibaseTagPrefix}-rbac-RESTRICTED-VIEW endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRestrictedView('${rawTableName}',
|
||||
call rbac.generateRbacRestrictedView('${rawTableName}',
|
||||
$orderBy$
|
||||
${orderBy}
|
||||
$orderBy$,
|
@ -1,6 +1,6 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
|
||||
|
||||
public class RbacRoleDescriptorsGenerator {
|
||||
|
||||
@ -11,15 +11,15 @@ public class RbacRoleDescriptorsGenerator {
|
||||
public RbacRoleDescriptorsGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) {
|
||||
this.liquibaseTagPrefix = liquibaseTagPrefix;
|
||||
this.simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
|
||||
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
|
||||
this.rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
|
||||
}
|
||||
|
||||
void generateTo(final StringWriter plPgSql) {
|
||||
plPgSql.writeLn("""
|
||||
-- ============================================================================
|
||||
--changeset ${liquibaseTagPrefix}-rbac-ROLE-DESCRIPTORS:1 endDelimiter:--//
|
||||
--changeset RbacRoleDescriptorsGenerator:${liquibaseTagPrefix}-rbac-ROLE-DESCRIPTORS endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call generateRbacRoleDescriptors('${simpleEntityVarName}', '${rawTableName}');
|
||||
call rbac.generateRbacRoleDescriptors('${simpleEntityVarName}', '${rawTableName}');
|
||||
--//
|
||||
|
||||
""",
|
@ -1,8 +1,8 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import org.reflections.Reflections;
|
||||
import org.reflections.scanners.TypeAnnotationsScanner;
|
||||
|
||||
@ -23,12 +23,12 @@ import static java.util.Arrays.asList;
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.Collections.max;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.ROLE_TO_ROLE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.Part.AUTO_FETCH;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition.GrantType.PERM_TO_ROLE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition.GrantType.ROLE_TO_ROLE;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.Part.AUTO_FETCH;
|
||||
import static org.apache.commons.collections4.SetUtils.hashSet;
|
||||
import static org.apache.commons.lang3.StringUtils.uncapitalize;
|
||||
|
||||
@ -36,12 +36,12 @@ import static org.apache.commons.lang3.StringUtils.uncapitalize;
|
||||
// TODO.refa: rename to RbacDSL
|
||||
public class RbacView {
|
||||
|
||||
public static final String GLOBAL = "global";
|
||||
public static final String GLOBAL = "rbac.global";
|
||||
public static final String OUTPUT_BASEDIR = "src/main/resources/db/changelog";
|
||||
|
||||
private final EntityAlias rootEntityAlias;
|
||||
|
||||
private final Set<RbacUserReference> userDefs = new LinkedHashSet<>();
|
||||
private final Set<RbacSubjectReference> userDefs = new LinkedHashSet<>();
|
||||
private final Set<RbacRoleDefinition> roleDefs = new LinkedHashSet<>();
|
||||
private final Set<RbacPermissionDefinition> permDefs = new LinkedHashSet<>();
|
||||
private final Map<String, EntityAlias> entityAliases = new HashMap<>() {
|
||||
@ -97,8 +97,8 @@ public class RbacView {
|
||||
RbacView(final String alias, final Class<? extends BaseEntity> entityClass) {
|
||||
rootEntityAlias = new EntityAlias(alias, entityClass);
|
||||
entityAliases.put(alias, rootEntityAlias);
|
||||
new RbacUserReference(CREATOR);
|
||||
entityAliases.put("global", new EntityAlias("global"));
|
||||
new RbacSubjectReference(CREATOR);
|
||||
entityAliases.put("rbac.global", new EntityAlias("rbac.global"));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -467,7 +467,7 @@ public class RbacView {
|
||||
return new RbacExampleRole(entityAlias, role);
|
||||
}
|
||||
|
||||
private RbacGrantDefinition grantRoleToUser(final RbacRoleDefinition roleDefinition, final RbacUserReference user) {
|
||||
private RbacGrantDefinition grantRoleToSubject(final RbacRoleDefinition roleDefinition, final RbacSubjectReference user) {
|
||||
return findOrCreateGrantDef(roleDefinition, user).toCreate();
|
||||
}
|
||||
|
||||
@ -548,7 +548,7 @@ public class RbacView {
|
||||
}
|
||||
|
||||
public RbacView grantPermission(final Permission perm) {
|
||||
final var forTable = rootEntityAlias.getRawTableName();
|
||||
final var forTable = rootEntityAlias.getRawTableNameWithSchema();
|
||||
findOrCreateGrantDef(findRbacPerm(rootEntityAlias, perm, forTable), superRoleDef).toCreate();
|
||||
return RbacView.this;
|
||||
}
|
||||
@ -564,7 +564,7 @@ public class RbacView {
|
||||
@EqualsAndHashCode
|
||||
public class RbacGrantDefinition {
|
||||
|
||||
private final RbacUserReference userDef;
|
||||
private final RbacSubjectReference userDef;
|
||||
private final RbacRoleDefinition superRoleDef;
|
||||
private final RbacRoleDefinition subRoleDef;
|
||||
private final RbacPermissionDefinition permDef;
|
||||
@ -605,7 +605,7 @@ public class RbacView {
|
||||
register(this);
|
||||
}
|
||||
|
||||
public RbacGrantDefinition(final RbacRoleDefinition roleDef, final RbacUserReference userDef) {
|
||||
public RbacGrantDefinition(final RbacRoleDefinition roleDef, final RbacSubjectReference userDef) {
|
||||
this.userDef = userDef;
|
||||
this.subRoleDef = roleDef;
|
||||
this.superRoleDef = null;
|
||||
@ -770,8 +770,8 @@ public class RbacView {
|
||||
* @return
|
||||
* The grant definition for further chained calls.
|
||||
*/
|
||||
public RbacGrantDefinition owningUser(final RbacUserReference.UserRole userRole) {
|
||||
return grantRoleToUser(this, findUserRef(userRole));
|
||||
public RbacGrantDefinition owningUser(final RbacSubjectReference.UserRole userRole) {
|
||||
return grantRoleToSubject(this, findUserRef(userRole));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -833,12 +833,12 @@ public class RbacView {
|
||||
}
|
||||
}
|
||||
|
||||
public RbacUserReference findUserRef(final RbacUserReference.UserRole userRole) {
|
||||
public RbacSubjectReference findUserRef(final RbacSubjectReference.UserRole userRole) {
|
||||
return userDefs.stream().filter(u -> u.role == userRole).findFirst().orElseThrow();
|
||||
}
|
||||
|
||||
@EqualsAndHashCode
|
||||
public class RbacUserReference {
|
||||
public class RbacSubjectReference {
|
||||
|
||||
public enum UserRole {
|
||||
GLOBAL_ADMIN,
|
||||
@ -847,7 +847,7 @@ public class RbacView {
|
||||
|
||||
final UserRole role;
|
||||
|
||||
public RbacUserReference(final UserRole creator) {
|
||||
public RbacSubjectReference(final UserRole creator) {
|
||||
this.role = creator;
|
||||
userDefs.add(this);
|
||||
}
|
||||
@ -885,7 +885,7 @@ public class RbacView {
|
||||
.orElseGet(() -> new RbacPermissionDefinition(entityAlias, perm, tableName, true)); // TODO: true => toCreate
|
||||
}
|
||||
|
||||
private RbacGrantDefinition findOrCreateGrantDef(final RbacRoleDefinition roleDefinition, final RbacUserReference user) {
|
||||
private RbacGrantDefinition findOrCreateGrantDef(final RbacRoleDefinition roleDefinition, final RbacSubjectReference user) {
|
||||
return grantDefs.stream()
|
||||
.filter(g -> g.subRoleDef == roleDefinition && g.userDef == user)
|
||||
.findFirst()
|
||||
@ -922,7 +922,7 @@ public class RbacView {
|
||||
}
|
||||
|
||||
boolean isGlobal() {
|
||||
return aliasName().equals("global");
|
||||
return aliasName().equals("rbac.global");
|
||||
}
|
||||
|
||||
boolean isPlaceholder() {
|
||||
@ -937,7 +937,7 @@ public class RbacView {
|
||||
return switch (fetchSql.part) {
|
||||
case SQL_QUERY -> fetchSql;
|
||||
case AUTO_FETCH ->
|
||||
SQL.query("SELECT * FROM " + getRawTableName() + " WHERE uuid = ${ref}." + dependsOnColum.column);
|
||||
SQL.query("SELECT * FROM " + getRawTableNameWithSchema() + " WHERE uuid = ${ref}." + dependsOnColum.column);
|
||||
default -> throw new IllegalStateException("unexpected SQL definition: " + fetchSql);
|
||||
};
|
||||
}
|
||||
@ -960,13 +960,39 @@ public class RbacView {
|
||||
: uncapitalize(withoutEntitySuffix(entityClass.getSimpleName()));
|
||||
}
|
||||
|
||||
String getRawTableName() {
|
||||
if ( aliasName.equals("global")) {
|
||||
return "global"; // TODO: maybe we should introduce a GlobalEntity class?
|
||||
String getRawTableNameWithSchema() {
|
||||
if ( aliasName.equals("rbac.global")) {
|
||||
return "rbac.global"; // TODO: maybe we should introduce a GlobalEntity class?
|
||||
}
|
||||
return withoutRvSuffix(entityClass.getAnnotation(Table.class).name());
|
||||
}
|
||||
|
||||
String getRawTableSchemaPrefix() {
|
||||
final var rawTableNameWithSchema = getRawTableNameWithSchema();
|
||||
final var parts = rawTableNameWithSchema.split("\\.");
|
||||
final var rawTableSchemaPrefix = parts.length > 1 ? parts[0] + "." : "";
|
||||
return rawTableSchemaPrefix;
|
||||
}
|
||||
|
||||
String getRawTableName() {
|
||||
final var rawTableNameWithSchema = getRawTableNameWithSchema();
|
||||
final var parts = rawTableNameWithSchema.split("\\.");
|
||||
final var rawTableName = parts.length > 1 ? parts[1] : rawTableNameWithSchema;
|
||||
return rawTableName;
|
||||
}
|
||||
|
||||
String getRawTableShortName() {
|
||||
// TODO.impl: some combined function and trigger names are too long
|
||||
// maybe we should shorten the table name e.g. hs_office_coopsharestransaction -> hsof.coopsharetx
|
||||
// this is just a workaround:
|
||||
return getRawTableName()
|
||||
.replace("hs_office_", "hsof_")
|
||||
.replace("hs_booking_", "hsbk_")
|
||||
.replace("hs_hosting_", "hsho_")
|
||||
.replace("coopsharestransaction", "coopsharetx")
|
||||
.replace("coopassetstransaction", "coopassettx");
|
||||
}
|
||||
|
||||
String dependsOnColumName() {
|
||||
if (dependsOnColum == null) {
|
||||
throw new IllegalStateException(
|
||||
@ -1166,7 +1192,7 @@ public class RbacView {
|
||||
}
|
||||
|
||||
String map(final String originalAliasName) {
|
||||
if (outerAliasNames.contains(originalAliasName) || originalAliasName.equals("global")) {
|
||||
if (outerAliasNames.contains(originalAliasName) || originalAliasName.equals("rbac.global")) {
|
||||
return originalAliasName;
|
||||
}
|
||||
if (originalAliasName.equals(importedRbacView.rootEntityAlias.aliasName)) {
|
@ -1,7 +1,7 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.CaseDef;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.nio.file.*;
|
||||
@ -12,7 +12,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition.GrantType.*;
|
||||
|
||||
public class RbacViewMermaidFlowchartGenerator {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
@ -6,8 +6,8 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.NEW;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.PostgresTriggerReference.NEW;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
|
||||
|
||||
public class RbacViewPostgresGenerator {
|
||||
|
||||
@ -17,7 +17,7 @@ public class RbacViewPostgresGenerator {
|
||||
|
||||
public RbacViewPostgresGenerator(final RbacView forRbacDef) {
|
||||
rbacDef = forRbacDef;
|
||||
liqibaseTagPrefix = rbacDef.getRootEntityAlias().getRawTableName().replace("_", "-");
|
||||
liqibaseTagPrefix = rbacDef.getRootEntityAlias().getRawTableNameWithSchema().replace("_", "-");
|
||||
plPgSql.writeLn("""
|
||||
--liquibase formatted sql
|
||||
-- This code generated was by ${generator}, do not amend manually.
|
@ -1,8 +1,8 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacPermissionDefinition;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.CaseDef;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.RbacPermissionDefinition;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@ -13,12 +13,12 @@ import java.util.stream.Stream;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.NEW;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.PostgresTriggerReference.OLD;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacGrantDefinition.GrantType.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.StringWriter.with;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.PostgresTriggerReference.NEW;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.PostgresTriggerReference.OLD;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.INSERT;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacGrantDefinition.GrantType.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.StringWriter.with;
|
||||
import static org.apache.commons.lang3.StringUtils.capitalize;
|
||||
import static org.apache.commons.lang3.StringUtils.uncapitalize;
|
||||
|
||||
@ -40,7 +40,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
|
||||
simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
|
||||
simpleEntityName = capitalize(simpleEntityVarName);
|
||||
rawTableName = rbacDef.getRootEntityAlias().getRawTableName();
|
||||
rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
|
||||
}
|
||||
|
||||
void generateTo(final StringWriter plPgSql) {
|
||||
@ -53,7 +53,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
private void generateHeader(final StringWriter plPgSql, final String triggerType) {
|
||||
plPgSql.writeLn("""
|
||||
-- ============================================================================
|
||||
--changeset ${liquibaseTagPrefix}-rbac-${triggerType}-trigger:1 endDelimiter:--//
|
||||
--changeset RolesGrantsAndPermissionsGenerator:${liquibaseTagPrefix}-rbac-${triggerType}-trigger endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
""",
|
||||
with("liquibaseTagPrefix", liquibaseTagPrefix),
|
||||
@ -77,17 +77,17 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
plPgSql.writeLn("declare");
|
||||
plPgSql.indented(() -> {
|
||||
referencedEntityAliases()
|
||||
.forEach((ea) -> plPgSql.writeLn(entityRefVar(NEW, ea) + " " + ea.getRawTableName() + ";"));
|
||||
.forEach((ea) -> plPgSql.writeLn(entityRefVar(NEW, ea) + " " + ea.getRawTableNameWithSchema() + ";"));
|
||||
});
|
||||
|
||||
plPgSql.writeLn();
|
||||
plPgSql.writeLn("begin");
|
||||
plPgSql.indented(() -> {
|
||||
plPgSql.writeLn("call enterTriggerForObjectUuid(NEW.uuid);");
|
||||
plPgSql.writeLn("call rbac.enterTriggerForObjectUuid(NEW.uuid);");
|
||||
plPgSql.writeLn();
|
||||
generateCreateRolesAndGrantsAfterInsert(plPgSql);
|
||||
plPgSql.ensureSingleEmptyLine();
|
||||
plPgSql.writeLn("call leaveTriggerForObjectUuid(NEW.uuid);");
|
||||
plPgSql.writeLn("call rbac.leaveTriggerForObjectUuid(NEW.uuid);");
|
||||
});
|
||||
plPgSql.writeLn("end; $$;");
|
||||
plPgSql.writeLn();
|
||||
@ -114,7 +114,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
begin
|
||||
|
||||
if ${updateConditions} then
|
||||
delete from rbacgrants g where g.grantedbytriggerof = OLD.uuid;
|
||||
delete from rbac.grants g where g.grantedbytriggerof = OLD.uuid;
|
||||
call buildRbacSystemFor${simpleEntityName}(NEW);
|
||||
end if;
|
||||
end; $$;
|
||||
@ -145,19 +145,19 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
plPgSql.indented(() -> {
|
||||
referencedEntityAliases()
|
||||
.forEach((ea) -> {
|
||||
plPgSql.writeLn(entityRefVar(OLD, ea) + " " + ea.getRawTableName() + ";");
|
||||
plPgSql.writeLn(entityRefVar(NEW, ea) + " " + ea.getRawTableName() + ";");
|
||||
plPgSql.writeLn(entityRefVar(OLD, ea) + " " + ea.getRawTableNameWithSchema() + ";");
|
||||
plPgSql.writeLn(entityRefVar(NEW, ea) + " " + ea.getRawTableNameWithSchema() + ";");
|
||||
});
|
||||
});
|
||||
|
||||
plPgSql.writeLn();
|
||||
plPgSql.writeLn("begin");
|
||||
plPgSql.indented(() -> {
|
||||
plPgSql.writeLn("call enterTriggerForObjectUuid(NEW.uuid);");
|
||||
plPgSql.writeLn("call rbac.enterTriggerForObjectUuid(NEW.uuid);");
|
||||
plPgSql.writeLn();
|
||||
generateUpdateRolesAndGrantsAfterUpdate(plPgSql);
|
||||
plPgSql.ensureSingleEmptyLine();
|
||||
plPgSql.writeLn("call leaveTriggerForObjectUuid(NEW.uuid);");
|
||||
plPgSql.writeLn("call rbac.leaveTriggerForObjectUuid(NEW.uuid);");
|
||||
});
|
||||
plPgSql.writeLn("end; $$;");
|
||||
plPgSql.writeLn();
|
||||
@ -309,10 +309,10 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
private String generateRevoke(RbacGrantDefinition grantDef) {
|
||||
return switch (grantDef.grantType()) {
|
||||
case ROLE_TO_USER -> throw new IllegalArgumentException("unexpected grant");
|
||||
case ROLE_TO_ROLE -> "call revokeRoleFromRole(${subRoleRef}, ${superRoleRef});"
|
||||
case ROLE_TO_ROLE -> "call rbac.revokeRoleFromRole(${subRoleRef}, ${superRoleRef});"
|
||||
.replace("${subRoleRef}", roleRef(OLD, grantDef.getSubRoleDef()))
|
||||
.replace("${superRoleRef}", roleRef(OLD, grantDef.getSuperRoleDef()));
|
||||
case PERM_TO_ROLE -> "call revokePermissionFromRole(${permRef}, ${superRoleRef});"
|
||||
case PERM_TO_ROLE -> "call rbac.revokePermissionFromRole(${permRef}, ${superRoleRef});"
|
||||
.replace("${permRef}", getPerm(OLD, grantDef.getPermDef()))
|
||||
.replace("${superRoleRef}", roleRef(OLD, grantDef.getSuperRoleDef()));
|
||||
};
|
||||
@ -321,13 +321,13 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
private String generateGrant(RbacGrantDefinition grantDef) {
|
||||
final var grantSql = switch (grantDef.grantType()) {
|
||||
case ROLE_TO_USER -> throw new IllegalArgumentException("unexpected grant");
|
||||
case ROLE_TO_ROLE -> "call grantRoleToRole(${subRoleRef}, ${superRoleRef}${assumed});"
|
||||
.replace("${assumed}", grantDef.isAssumed() ? "" : ", unassumed()")
|
||||
case ROLE_TO_ROLE -> "call rbac.grantRoleToRole(${subRoleRef}, ${superRoleRef}${assumed});"
|
||||
.replace("${assumed}", grantDef.isAssumed() ? "" : ", rbac.unassumed()")
|
||||
.replace("${subRoleRef}", roleRef(NEW, grantDef.getSubRoleDef()))
|
||||
.replace("${superRoleRef}", roleRef(NEW, grantDef.getSuperRoleDef()));
|
||||
case PERM_TO_ROLE ->
|
||||
grantDef.getPermDef().getPermission() == INSERT ? ""
|
||||
: "call grantPermissionToRole(${permRef}, ${superRoleRef});"
|
||||
: "call rbac.grantPermissionToRole(${permRef}, ${superRoleRef});"
|
||||
.replace("${permRef}", createPerm(NEW, grantDef.getPermDef()))
|
||||
.replace("${superRoleRef}", roleRef(NEW, grantDef.getSuperRoleDef()));
|
||||
};
|
||||
@ -335,15 +335,15 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
}
|
||||
|
||||
private String findPerm(final PostgresTriggerReference ref, final RbacPermissionDefinition permDef) {
|
||||
return permRef("findPermissionId", ref, permDef);
|
||||
return permRef("rbac.findPermissionId", ref, permDef);
|
||||
}
|
||||
|
||||
private String getPerm(final PostgresTriggerReference ref, final RbacPermissionDefinition permDef) {
|
||||
return permRef("getPermissionId", ref, permDef);
|
||||
return permRef("rbac.getPermissionId", ref, permDef);
|
||||
}
|
||||
|
||||
private String createPerm(final PostgresTriggerReference ref, final RbacPermissionDefinition permDef) {
|
||||
return permRef("createPermission", ref, permDef);
|
||||
return permRef("rbac.createPermission", ref, permDef);
|
||||
}
|
||||
|
||||
private String permRef(final String functionName, final PostgresTriggerReference ref, final RbacPermissionDefinition permDef) {
|
||||
@ -364,7 +364,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
System.out.println("null");
|
||||
}
|
||||
if (roleDef.getEntityAlias().isGlobal()) {
|
||||
return "globalAdmin()";
|
||||
return "rbac.globalAdmin()";
|
||||
}
|
||||
final String entityRefVar = entityRefVar(rootRefVar, roleDef.getEntityAlias());
|
||||
return roleDef.getEntityAlias().simpleName() + capitalize(roleDef.getRole().name())
|
||||
@ -389,7 +389,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
}
|
||||
|
||||
plPgSql.writeLn();
|
||||
plPgSql.writeLn("perform createRoleWithGrants(");
|
||||
plPgSql.writeLn("perform rbac.defineRoleWithGrants(");
|
||||
plPgSql.indented(() -> {
|
||||
plPgSql.writeLn("${simpleVarName)${roleSuffix}(NEW),"
|
||||
.replace("${simpleVarName)", simpleEntityVarName)
|
||||
@ -415,7 +415,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
.map(this::toPlPgSqlReference)
|
||||
.toList();
|
||||
plPgSql.indented(() ->
|
||||
plPgSql.writeLn("userUuids => array[" + joinArrayElements(arrayElements, 2) + "],\n"));
|
||||
plPgSql.writeLn("subjectUuids => array[" + joinArrayElements(arrayElements, 2) + "],\n"));
|
||||
rbacGrants.removeAll(grantsToUsers);
|
||||
}
|
||||
}
|
||||
@ -578,9 +578,9 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
plPgSql.writeLn();
|
||||
}
|
||||
|
||||
private String toPlPgSqlReference(final RbacView.RbacUserReference userRef) {
|
||||
private String toPlPgSqlReference(final RbacView.RbacSubjectReference userRef) {
|
||||
return switch (userRef.role) {
|
||||
case CREATOR -> "currentUserUuid()";
|
||||
case CREATOR -> "rbac.currentSubjectUuid()";
|
||||
default -> throw new IllegalArgumentException("unknown user role: " + userRef);
|
||||
};
|
||||
}
|
||||
@ -589,9 +589,9 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
final PostgresTriggerReference triggerRef,
|
||||
final RbacView.RbacRoleDefinition roleDef,
|
||||
final boolean assumed) {
|
||||
final var assumedArg = assumed ? "" : ", unassumed()";
|
||||
final var assumedArg = assumed ? "" : ", rbac.unassumed()";
|
||||
return toRoleRef(roleDef) +
|
||||
(roleDef.getEntityAlias().isGlobal() ? ( assumed ? "()" : "(unassumed())")
|
||||
(roleDef.getEntityAlias().isGlobal() ? ( assumed ? "()" : "(rbac.unassumed())")
|
||||
: rbacDef.isRootEntityAlias(roleDef.getEntityAlias()) ? ("(" + triggerRef.name() + ")")
|
||||
: "(" + toTriggerReference(triggerRef, roleDef.getEntityAlias()) + assumedArg + ")");
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
package net.hostsharing.hsadminng.rbac.generator;
|
||||
|
||||
// TODO: The whole code in this package is more like a quick hack to solve an urgent problem.
|
||||
// It should be re-written in PostgreSQL pl/pgsql,
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacgrant;
|
||||
package net.hostsharing.hsadminng.rbac.grant;
|
||||
|
||||
import lombok.*;
|
||||
import org.springframework.data.annotation.Immutable;
|
||||
@ -12,7 +12,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "rbacgrants_ev")
|
||||
@Table(schema = "rbac", name = "grants_ev")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacgrant;
|
||||
package net.hostsharing.hsadminng.rbac.grant;
|
||||
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacgrant;
|
||||
package net.hostsharing.hsadminng.rbac.grant;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||
@ -33,14 +33,14 @@ public class RbacGrantController implements RbacGrantsApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<RbacGrantResource> getGrantById(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID grantedRoleUuid,
|
||||
final UUID granteeUserUuid) {
|
||||
final UUID granteeSubjectUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var id = new RbacGrantId(granteeUserUuid, grantedRoleUuid);
|
||||
final var id = new RbacGrantId(granteeSubjectUuid, grantedRoleUuid);
|
||||
final var result = rbacGrantRepository.findById(id);
|
||||
if (result == null) {
|
||||
return ResponseEntity.notFound().build();
|
||||
@ -50,23 +50,23 @@ public class RbacGrantController implements RbacGrantsApi {
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<RbacGrantResource>> listUserGrants(
|
||||
final String currentUser,
|
||||
public ResponseEntity<List<RbacGrantResource>> listSubjectGrants(
|
||||
final String currentSubject,
|
||||
final String assumedRoles) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
return ResponseEntity.ok(mapper.mapList(rbacGrantRepository.findAll(), RbacGrantResource.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<RbacGrantResource> grantRoleToUser(
|
||||
final String currentUser,
|
||||
public ResponseEntity<RbacGrantResource> grantRoleToSubject(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final RbacGrantResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var granted = rbacGrantRepository.save(mapper.map(body, RbacGrantEntity.class));
|
||||
em.flush();
|
||||
@ -82,28 +82,28 @@ public class RbacGrantController implements RbacGrantsApi {
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> revokeRoleFromUser(
|
||||
final String currentUser,
|
||||
public ResponseEntity<Void> revokeRoleFromSubject(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID grantedRoleUuid,
|
||||
final UUID granteeUserUuid) {
|
||||
final UUID granteeSubjectUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
rbacGrantRepository.deleteByRbacGrantId(new RbacGrantId(granteeUserUuid, grantedRoleUuid));
|
||||
rbacGrantRepository.deleteByRbacGrantId(new RbacGrantId(granteeSubjectUuid, grantedRoleUuid));
|
||||
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
// TODO: implement an endpoint to create a Mermaid flowchart with all grants of a given user
|
||||
// TODO.feat: implement an endpoint to create a Mermaid flowchart with all grants of a given user
|
||||
// @GetMapping(
|
||||
// path = "/api/rbac/users/{userUuid}/grants",
|
||||
// path = "/api/rbac/subjects/{subjectUuid}/grants",
|
||||
// produces = {"text/vnd.mermaid"})
|
||||
// @Transactional(readOnly = true)
|
||||
// public ResponseEntity<String> allGrantsOfUserAsMermaid(
|
||||
// @RequestHeader(name = "current-user") String currentUser,
|
||||
// @RequestHeader(name = "current-subject") String currentSubject,
|
||||
// @RequestHeader(name = "assumed-roles", required = false) String assumedRoles) {
|
||||
// final var graph = RbacGrantsDiagramService.allGrantsToUser(currentUser);
|
||||
// final var graph = RbacGrantsDiagramService.allGrantsToUser(currentSubject);
|
||||
// return ResponseEntity.ok(graph);
|
||||
// }
|
||||
|
@ -1,14 +1,14 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacgrant;
|
||||
package net.hostsharing.hsadminng.rbac.grant;
|
||||
|
||||
import lombok.*;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleType;
|
||||
import net.hostsharing.hsadminng.rbac.role.RbacRoleType;
|
||||
import org.springframework.data.annotation.Immutable;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "rbacgrants_rv")
|
||||
@Table(schema = "rbac", name = "grants_rv")
|
||||
@IdClass(RbacGrantId.class)
|
||||
@Getter
|
||||
@Setter
|
||||
@ -33,11 +33,11 @@ public class RbacGrantEntity {
|
||||
private UUID grantedRoleUuid;
|
||||
|
||||
@Column(name = "username", updatable = false, insertable = false)
|
||||
private String granteeUserName;
|
||||
private String granteeSubjectName;
|
||||
|
||||
@Id
|
||||
@Column(name = "useruuid")
|
||||
private UUID granteeUserUuid;
|
||||
@Column(name = "subjectuuid")
|
||||
private UUID granteeSubjectUuid;
|
||||
|
||||
private boolean assumed;
|
||||
|
||||
@ -55,12 +55,12 @@ public class RbacGrantEntity {
|
||||
private RbacRoleType grantedRoleType;
|
||||
|
||||
RbacGrantId getRbacGrantId() {
|
||||
return new RbacGrantId(granteeUserUuid, grantedRoleUuid);
|
||||
return new RbacGrantId(granteeSubjectUuid, grantedRoleUuid);
|
||||
}
|
||||
|
||||
public String toDisplay() {
|
||||
return "{ grant role:" + grantedRoleIdName +
|
||||
" to user:" + granteeUserName +
|
||||
" to user:" + granteeSubjectName +
|
||||
" by role:" + grantedByRoleIdName +
|
||||
(assumed ? " and assume" : "") +
|
||||
" }";
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacgrant;
|
||||
package net.hostsharing.hsadminng.rbac.grant;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -14,6 +14,6 @@ import java.util.UUID;
|
||||
@AllArgsConstructor
|
||||
public class RbacGrantId implements Serializable {
|
||||
|
||||
private UUID granteeUserUuid;
|
||||
private UUID granteeSubjectUuid;
|
||||
private UUID grantedRoleUuid;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacgrant;
|
||||
package net.hostsharing.hsadminng.rbac.grant;
|
||||
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
@ -11,7 +11,7 @@ public interface RbacGrantRepository extends Repository<RbacGrantEntity, RbacGra
|
||||
@Query(value = """
|
||||
select g from RbacGrantEntity as g
|
||||
where g.grantedRoleUuid=:#{#rbacGrantId.grantedRoleUuid}
|
||||
and g.granteeUserUuid=:#{#rbacGrantId.granteeUserUuid}
|
||||
and g.granteeSubjectUuid=:#{#rbacGrantId.granteeSubjectUuid}
|
||||
""")
|
||||
RbacGrantEntity findById(RbacGrantId rbacGrantId);
|
||||
|
||||
@ -25,7 +25,7 @@ public interface RbacGrantRepository extends Repository<RbacGrantEntity, RbacGra
|
||||
@Query(value = """
|
||||
delete from RbacGrantEntity as g
|
||||
where g.grantedRoleUuid=:#{#rbacGrantId.grantedRoleUuid}
|
||||
and g.granteeUserUuid=:#{#rbacGrantId.granteeUserUuid}
|
||||
and g.granteeSubjectUuid=:#{#rbacGrantId.granteeSubjectUuid}
|
||||
""")
|
||||
void deleteByRbacGrantId(RbacGrantId rbacGrantId);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacgrant;
|
||||
package net.hostsharing.hsadminng.rbac.grant;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -16,7 +16,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import static java.util.stream.Collectors.groupingBy;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService.Include.*;
|
||||
import static net.hostsharing.hsadminng.rbac.grant.RbacGrantsDiagramService.Include.*;
|
||||
|
||||
// TODO: cleanup - this code was 'hacked' to quickly fix a specific problem, needs refactoring
|
||||
@Service
|
||||
@ -64,9 +64,9 @@ public class RbacGrantsDiagramService {
|
||||
|
||||
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>();
|
||||
for ( UUID subjectUuid: context.currentSubjectsUuids() ) {
|
||||
for ( UUID subjectUuid: context.fetchCurrentSubjectOrAssumedRolesUuids() ) {
|
||||
traverseGrantsTo(graph, subjectUuid, includes);
|
||||
}
|
||||
return toMermaidFlowchart(graph, includes);
|
||||
@ -78,7 +78,7 @@ public class RbacGrantsDiagramService {
|
||||
if (!includes.contains(PERMISSIONS) && g.getDescendantIdName().startsWith("perm:")) {
|
||||
return;
|
||||
}
|
||||
if ( !g.getDescendantIdName().startsWith("role:global")) {
|
||||
if ( !g.getDescendantIdName().startsWith("role:rbac.global")) {
|
||||
if (!includes.contains(TEST_ENTITIES) && g.getDescendantIdName().contains(":test_")) {
|
||||
return;
|
||||
}
|
||||
@ -94,7 +94,7 @@ public class RbacGrantsDiagramService {
|
||||
}
|
||||
|
||||
public String allGrantsFrom(final UUID targetObject, final String op, final EnumSet<Include> includes) {
|
||||
final var refUuid = (UUID) em.createNativeQuery("SELECT uuid FROM rbacpermission WHERE objectuuid=:targetObject AND op=:op")
|
||||
final var refUuid = (UUID) em.createNativeQuery("SELECT uuid FROM rbac.permission WHERE objectuuid=:targetObject AND op=:op")
|
||||
.setParameter("targetObject", targetObject)
|
||||
.setParameter("op", op)
|
||||
.getSingleResult();
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacobject;
|
||||
package net.hostsharing.hsadminng.rbac.object;
|
||||
|
||||
|
||||
import org.hibernate.Hibernate;
|
@ -1,46 +0,0 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacuser;
|
||||
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface RbacUserRepository extends Repository<RbacUserEntity, UUID> {
|
||||
|
||||
@Query("""
|
||||
select u from RbacUserEntity u
|
||||
where :userName is null or u.name like concat(cast(:userName as text), '%')
|
||||
order by u.name
|
||||
""")
|
||||
List<RbacUserEntity> findByOptionalNameLike(String userName);
|
||||
|
||||
// bypasses the restricted view, to be able to grant rights to arbitrary user
|
||||
@Query(value = "select * from rbacuser where name=:userName", nativeQuery = true)
|
||||
RbacUserEntity findByName(String userName);
|
||||
|
||||
RbacUserEntity findByUuid(UUID uuid);
|
||||
|
||||
@Query(value = "select * from grantedPermissions(:userUuid)", nativeQuery = true)
|
||||
List<RbacUserPermission> findPermissionsOfUserByUuid(UUID userUuid);
|
||||
|
||||
/*
|
||||
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.
|
||||
And SQL SELECT needs a currentUser which we don't yet have in the case of self registration.
|
||||
*/
|
||||
@Modifying
|
||||
@Query(value = "insert into RBacUser_RV (uuid, name) values( :#{#newUser.uuid}, :#{#newUser.name})", nativeQuery = true)
|
||||
void insert(final RbacUserEntity newUser);
|
||||
|
||||
default RbacUserEntity create(final RbacUserEntity rbacUserEntity) {
|
||||
if (rbacUserEntity.getUuid() == null) {
|
||||
rbacUserEntity.setUuid(UUID.randomUUID());
|
||||
}
|
||||
insert(rbacUserEntity);
|
||||
return rbacUserEntity;
|
||||
}
|
||||
|
||||
void deleteByUuid(UUID userUuid);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacrole;
|
||||
package net.hostsharing.hsadminng.rbac.role;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||
@ -26,10 +26,10 @@ public class RbacRoleController implements RbacRolesApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<RbacRoleResource>> listRoles(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final List<RbacRoleEntity> result = rbacRoleRepository.findAll();
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacrole;
|
||||
package net.hostsharing.hsadminng.rbac.role;
|
||||
|
||||
import lombok.*;
|
||||
import org.hibernate.annotations.Formula;
|
||||
@ -8,7 +8,7 @@ import jakarta.persistence.*;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "rbacrole_rv")
|
||||
@Table(schema = "rbac", name = "role_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacrole;
|
||||
package net.hostsharing.hsadminng.rbac.role;
|
||||
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacrole;
|
||||
package net.hostsharing.hsadminng.rbac.role;
|
||||
|
||||
public enum RbacRoleType {
|
||||
OWNER, ADMIN, AGENT, TENANT, GUEST, REFERRER
|
@ -1,10 +1,10 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacuser;
|
||||
package net.hostsharing.hsadminng.rbac.subject;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacUsersApi;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacUserPermissionResource;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacUserResource;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.api.RbacSubjectsApi;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectPermissionResource;
|
||||
import net.hostsharing.hsadminng.rbac.generated.api.v1.model.RbacSubjectResource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -15,7 +15,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@RestController
|
||||
public class RbacUserController implements RbacUsersApi {
|
||||
public class RbacSubjectController implements RbacSubjectsApi {
|
||||
|
||||
@Autowired
|
||||
private Context context;
|
||||
@ -24,81 +24,81 @@ public class RbacUserController implements RbacUsersApi {
|
||||
private Mapper mapper;
|
||||
|
||||
@Autowired
|
||||
private RbacUserRepository rbacUserRepository;
|
||||
private RbacSubjectRepository rbacSubjectRepository;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<RbacUserResource> createUser(
|
||||
final RbacUserResource body
|
||||
public ResponseEntity<RbacSubjectResource> createSubject(
|
||||
final RbacSubjectResource body
|
||||
) {
|
||||
context.define(null);
|
||||
|
||||
if (body.getUuid() == null) {
|
||||
body.setUuid(UUID.randomUUID());
|
||||
}
|
||||
final var saved = mapper.map(body, RbacUserEntity.class);
|
||||
rbacUserRepository.create(saved);
|
||||
final var saved = mapper.map(body, RbacSubjectEntity.class);
|
||||
rbacSubjectRepository.create(saved);
|
||||
final var uri =
|
||||
MvcUriComponentsBuilder.fromController(getClass())
|
||||
.path("/api/rbac.yaml/users/{id}")
|
||||
.buildAndExpand(saved.getUuid())
|
||||
.toUri();
|
||||
return ResponseEntity.created(uri).body(mapper.map(saved, RbacUserResource.class));
|
||||
return ResponseEntity.created(uri).body(mapper.map(saved, RbacSubjectResource.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> deleteUserByUuid(
|
||||
final String currentUser,
|
||||
public ResponseEntity<Void> deleteSubjectByUuid(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID userUuid
|
||||
final UUID subjectUuid
|
||||
) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
rbacUserRepository.deleteByUuid(userUuid);
|
||||
rbacSubjectRepository.deleteByUuid(subjectUuid);
|
||||
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<RbacUserResource> getUserById(
|
||||
final String currentUser,
|
||||
public ResponseEntity<RbacSubjectResource> getSubjectById(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID userUuid) {
|
||||
final UUID subjectUuid) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = rbacUserRepository.findByUuid(userUuid);
|
||||
final var result = rbacSubjectRepository.findByUuid(subjectUuid);
|
||||
if (result == null) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
return ResponseEntity.ok(mapper.map(result, RbacUserResource.class));
|
||||
return ResponseEntity.ok(mapper.map(result, RbacSubjectResource.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<RbacUserResource>> listUsers(
|
||||
final String currentUser,
|
||||
public ResponseEntity<List<RbacSubjectResource>> listSubjects(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
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(rbacSubjectRepository.findByOptionalNameLike(userName), RbacSubjectResource.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<RbacUserPermissionResource>> listUserPermissions(
|
||||
final String currentUser,
|
||||
public ResponseEntity<List<RbacSubjectPermissionResource>> listSubjectPermissions(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID userUuid
|
||||
final UUID subjectUuid
|
||||
) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
return ResponseEntity.ok(mapper.mapList(
|
||||
rbacUserRepository.findPermissionsOfUserByUuid(userUuid),
|
||||
RbacUserPermissionResource.class));
|
||||
rbacSubjectRepository.findPermissionsOfUserByUuid(subjectUuid),
|
||||
RbacSubjectPermissionResource.class));
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacuser;
|
||||
package net.hostsharing.hsadminng.rbac.subject;
|
||||
|
||||
import lombok.*;
|
||||
import org.springframework.data.annotation.Immutable;
|
||||
@ -13,14 +13,14 @@ import java.time.temporal.ChronoUnit;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "rbacuser_rv")
|
||||
@Table(schema = "rbac", name = "subject_rv")
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@Immutable
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class RbacUserEntity {
|
||||
public class RbacSubjectEntity {
|
||||
|
||||
private static final int MAX_VALIDITY_DAYS = 21;
|
||||
private static DateTimeFormatter DATE_FORMAT_WITH_FULLHOUR = DateTimeFormatter.ofPattern("MM-dd-yyyy HH");
|
@ -1,8 +1,8 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacuser;
|
||||
package net.hostsharing.hsadminng.rbac.subject;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface RbacUserPermission {
|
||||
public interface RbacSubjectPermission {
|
||||
|
||||
UUID getRoleUuid();
|
||||
String getRoleName();
|
@ -0,0 +1,46 @@
|
||||
package net.hostsharing.hsadminng.rbac.subject;
|
||||
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface RbacSubjectRepository extends Repository<RbacSubjectEntity, UUID> {
|
||||
|
||||
@Query("""
|
||||
select u from RbacSubjectEntity u
|
||||
where :userName is null or u.name like concat(cast(:userName as text), '%')
|
||||
order by u.name
|
||||
""")
|
||||
List<RbacSubjectEntity> findByOptionalNameLike(String userName);
|
||||
|
||||
// bypasses the restricted view, to be able to grant rights to arbitrary user
|
||||
@Query(value = "select * from rbac.subject where name=:userName", nativeQuery = true)
|
||||
RbacSubjectEntity findByName(String userName);
|
||||
|
||||
RbacSubjectEntity findByUuid(UUID uuid);
|
||||
|
||||
@Query(value = "select * from rbac.grantedPermissions(:subjectUuid)", nativeQuery = true)
|
||||
List<RbacSubjectPermission> findPermissionsOfUserByUuid(UUID subjectUuid);
|
||||
|
||||
/*
|
||||
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.
|
||||
And SQL SELECT needs a currentSubject which we don't yet have in the case of self registration.
|
||||
*/
|
||||
@Modifying
|
||||
@Query(value = "insert into rbac.subject_rv (uuid, name) values( :#{#newUser.uuid}, :#{#newUser.name})", nativeQuery = true)
|
||||
void insert(final RbacSubjectEntity newUser);
|
||||
|
||||
default RbacSubjectEntity create(final RbacSubjectEntity rbacSubjectEntity) {
|
||||
if (rbacSubjectEntity.getUuid() == null) {
|
||||
rbacSubjectEntity.setUuid(UUID.randomUUID());
|
||||
}
|
||||
insert(rbacSubjectEntity);
|
||||
return rbacSubjectEntity;
|
||||
}
|
||||
|
||||
void deleteByUuid(UUID subjectUuid);
|
||||
}
|
@ -32,11 +32,11 @@ public class TestCustomerController implements TestCustomersApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<TestCustomerResource>> listCustomers(
|
||||
String currentUser,
|
||||
String currentSubject,
|
||||
String assumedRoles,
|
||||
String prefix
|
||||
) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = testCustomerRepository.findCustomerByOptionalPrefixLike(prefix);
|
||||
|
||||
@ -46,11 +46,11 @@ public class TestCustomerController implements TestCustomersApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<TestCustomerResource> addCustomer(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final TestCustomerResource customer) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var saved = testCustomerRepository.save(mapper.map(customer, TestCustomerEntity.class));
|
||||
final var uri =
|
||||
|
@ -5,19 +5,19 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.RbacUserReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.GLOBAL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.RbacSubjectReference.UserRole.CREATOR;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(name = "test_customer_rv")
|
||||
@ -46,7 +46,7 @@ public class TestCustomerEntity implements BaseEntity<TestCustomerEntity> {
|
||||
.withIdentityView(SQL.projection("prefix"))
|
||||
.withRestrictedViewOrderBy(SQL.expression("reference"))
|
||||
.withUpdatableColumns("reference", "prefix", "adminUserName")
|
||||
.toRole("global", ADMIN).grantPermission(INSERT)
|
||||
.toRole("rbac.global", ADMIN).grantPermission(INSERT)
|
||||
|
||||
.createRole(OWNER, (with) -> {
|
||||
with.owningUser(CREATOR).unassumed();
|
||||
|
@ -4,22 +4,22 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.test.pac.TestPackageEntity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetchedByDependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(name = "test_domain_rv")
|
||||
|
@ -29,11 +29,11 @@ public class TestPackageController implements TestPackagesApi {
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseEntity<List<TestPackageResource>> listPackages(
|
||||
String currentUser,
|
||||
String currentSubject,
|
||||
String assumedRoles,
|
||||
String name
|
||||
) {
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = testPackageRepository.findAllByOptionalNameLike(name);
|
||||
return ResponseEntity.ok(mapper.mapList(result, TestPackageResource.class));
|
||||
@ -42,12 +42,12 @@ public class TestPackageController implements TestPackagesApi {
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<TestPackageResource> updatePackage(
|
||||
final String currentUser,
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID packageUuid,
|
||||
final TestPackageUpdateResource body) {
|
||||
|
||||
context.define(currentUser, assumedRoles);
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var current = testPackageRepository.findByUuid(packageUuid);
|
||||
OptionalFromJson.of(body.getDescription()).ifPresent(current::setDescription);
|
||||
|
@ -4,22 +4,22 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.object.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.test.cust.TestCustomerEntity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.*;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Column.dependsOnColumn;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.ColumnValue.usingDefaultCase;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Nullable.NOT_NULL;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Permission.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.*;
|
||||
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
|
||||
|
||||
@Entity
|
||||
@Table(name = "test_package_rv")
|
||||
|
@ -3,13 +3,13 @@ components:
|
||||
|
||||
parameters:
|
||||
|
||||
currentUser:
|
||||
name: current-user
|
||||
currentSubject:
|
||||
name: current-subject
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: Identifying name of the currently logged in user.
|
||||
description: Identifying name of the current subject (e.g. user).
|
||||
|
||||
assumedRoles:
|
||||
name: assumed-roles
|
||||
@ -17,4 +17,4 @@ components:
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
description: Semicolon-separated list of roles to assume. The current user needs to have the right to assume these roles.
|
||||
description: Semicolon-separated list of roles to assume. The current subject needs to have the right to assume these roles.
|
||||
|
@ -8,13 +8,13 @@ components:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
Unauthorized:
|
||||
description: The current user is unknown or not authorized.
|
||||
description: The current subject is unknown or not authorized.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
Forbidden:
|
||||
description: The current user or none of the assumed or roles is granted access to the resource.
|
||||
description: The current subject or none of the assumed or roles is granted access to the resource.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
|
@ -3,13 +3,13 @@ components:
|
||||
|
||||
parameters:
|
||||
|
||||
currentUser:
|
||||
name: current-user
|
||||
currentSubject:
|
||||
name: current-subject
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: Identifying name of the currently logged in user.
|
||||
description: Identifying name of the currently logged in subject.
|
||||
|
||||
assumedRoles:
|
||||
name: assumed-roles
|
||||
@ -17,4 +17,4 @@ components:
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
description: Semicolon-separated list of roles to assume. The current user needs to have the right to assume these roles.
|
||||
description: Semicolon-separated list of roles to assume. The current subject needs to have the right to assume these roles.
|
||||
|
@ -8,13 +8,13 @@ components:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
Unauthorized:
|
||||
description: The current user is unknown or not authorized.
|
||||
description: The current subject is unknown or not authorized.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
Forbidden:
|
||||
description: The current user or none of the assumed or roles is granted access to the resource.
|
||||
description: The current subject or none of the assumed or roles is granted access to the resource.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
|
@ -4,7 +4,7 @@ get:
|
||||
description: 'Fetch a single booking item its uuid, if visible for the current subject.'
|
||||
operationId: getBookingItemByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: bookingItemUuid
|
||||
in: path
|
||||
@ -32,7 +32,7 @@ patch:
|
||||
description: 'Updates a single booking item identified by its uuid, if permitted for the current subject.'
|
||||
operationId: patchBookingItem
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: bookingItemUuid
|
||||
in: path
|
||||
@ -63,7 +63,7 @@ delete:
|
||||
description: 'Delete a single booking item identified by its uuid, if permitted for the current subject.'
|
||||
operationId: deleteBookingIemByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: bookingItemUuid
|
||||
in: path
|
||||
|
@ -1,11 +1,11 @@
|
||||
get:
|
||||
summary: Returns a list of all booking items for a specified project.
|
||||
description: Returns the list of all booking items for a specified project which are visible to the current user or any of it's assumed roles.
|
||||
description: Returns the list of all booking items for a specified project which are visible to the current subject or any of it's assumed roles.
|
||||
tags:
|
||||
- hs-booking-items
|
||||
operationId: listBookingItemsByProjectUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: projectUuid
|
||||
in: query
|
||||
@ -34,7 +34,7 @@ post:
|
||||
- hs-booking-items
|
||||
operationId: addBookingItem
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
requestBody:
|
||||
description: A JSON object describing the new booking item.
|
||||
|
@ -4,7 +4,7 @@ get:
|
||||
description: 'Fetch a single booking project its uuid, if visible for the current subject.'
|
||||
operationId: getBookingProjectByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: bookingProjectUuid
|
||||
in: path
|
||||
@ -32,7 +32,7 @@ patch:
|
||||
description: 'Updates a single booking project identified by its uuid, if permitted for the current subject.'
|
||||
operationId: patchBookingProject
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: bookingProjectUuid
|
||||
in: path
|
||||
@ -63,7 +63,7 @@ delete:
|
||||
description: 'Delete a single booking project identified by its uuid, if permitted for the current subject.'
|
||||
operationId: deleteBookingIemByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: bookingProjectUuid
|
||||
in: path
|
||||
|
@ -1,11 +1,11 @@
|
||||
get:
|
||||
summary: Returns a list of all booking projects for a specified debitor.
|
||||
description: Returns the list of all booking projects for a specified debitor which are visible to the current user or any of it's assumed roles.
|
||||
description: Returns the list of all booking projects for a specified debitor which are visible to the current subject or any of it's assumed roles.
|
||||
tags:
|
||||
- hs-booking-projects
|
||||
operationId: listBookingProjectsByDebitorUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: debitorUuid
|
||||
in: query
|
||||
@ -34,7 +34,7 @@ post:
|
||||
- hs-booking-projects
|
||||
operationId: addBookingProject
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
requestBody:
|
||||
description: A JSON object describing the new booking project.
|
||||
|
@ -3,13 +3,13 @@ components:
|
||||
|
||||
parameters:
|
||||
|
||||
currentUser:
|
||||
name: current-user
|
||||
currentSubject:
|
||||
name: current-subject
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: Identifying name of the currently logged in user.
|
||||
description: Identifying name of the currently logged in subject.
|
||||
|
||||
assumedRoles:
|
||||
name: assumed-roles
|
||||
@ -17,4 +17,4 @@ components:
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
description: Semicolon-separated list of roles to assume. The current user needs to have the right to assume these roles.
|
||||
description: Semicolon-separated list of roles to assume. The current subject needs to have the right to assume these roles.
|
||||
|
@ -8,13 +8,13 @@ components:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
Unauthorized:
|
||||
description: The current user is unknown or not authorized.
|
||||
description: The current subject is unknown or not authorized.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
Forbidden:
|
||||
description: The current user or none of the assumed or roles is granted access to the resource.
|
||||
description: The current subject or none of the assumed or roles is granted access to the resource.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
|
@ -4,7 +4,7 @@ get:
|
||||
description: 'Fetch a single managed asset by its uuid, if visible for the current subject.'
|
||||
operationId: getAssetByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: assetUuid
|
||||
in: path
|
||||
@ -32,7 +32,7 @@ patch:
|
||||
description: 'Updates a single hosting asset identified by its uuid, if permitted for the current subject.'
|
||||
operationId: patchAsset
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: assetUuid
|
||||
in: path
|
||||
@ -63,7 +63,7 @@ delete:
|
||||
description: 'Delete a single hosting asset identified by its uuid, if permitted for the current subject.'
|
||||
operationId: deleteAssetUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: assetUuid
|
||||
in: path
|
||||
|
@ -1,11 +1,11 @@
|
||||
get:
|
||||
summary: Returns a filtered list of all hosting assets.
|
||||
description: Returns the list of all hosting assets which match the given filters and are visible to the current user or any of it's assumed roles.
|
||||
description: Returns the list of all hosting assets which match the given filters and are visible to the current subject or any of it's assumed roles.
|
||||
tags:
|
||||
- hs-hosting-assets
|
||||
operationId: listAssets
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: projectUuid
|
||||
in: query
|
||||
@ -47,7 +47,7 @@ post:
|
||||
- hs-hosting-assets
|
||||
operationId: addAsset
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
requestBody:
|
||||
description: A JSON object describing the new hosting asset.
|
||||
|
@ -4,7 +4,7 @@ get:
|
||||
description: 'Fetch a single bank account by its uuid, if visible for the current subject.'
|
||||
operationId: getBankAccountByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: bankAccountUUID
|
||||
in: path
|
||||
@ -31,7 +31,7 @@ delete:
|
||||
description: 'Delete a single bank account by its uuid, if permitted for the current subject.'
|
||||
operationId: deleteBankAccountByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: bankAccountUUID
|
||||
in: path
|
||||
|
@ -1,11 +1,11 @@
|
||||
get:
|
||||
summary: Returns a list of (optionally filtered) bankaccounts.
|
||||
description: Returns the list of (optionally filtered) bankaccounts which are visible to the current user or any of it's assumed roles.
|
||||
description: Returns the list of (optionally filtered) bankaccounts which are visible to the current subject or any of it's assumed roles.
|
||||
tags:
|
||||
- hs-office-bank-accounts
|
||||
operationId: listBankAccounts
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: holder
|
||||
in: query
|
||||
@ -33,7 +33,7 @@ post:
|
||||
- hs-office-bank-accounts
|
||||
operationId: addBankAccount
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
requestBody:
|
||||
content:
|
||||
|
@ -4,7 +4,7 @@ get:
|
||||
description: 'Fetch a single business contact by its uuid, if visible for the current subject.'
|
||||
operationId: getContactByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: contactUUID
|
||||
in: path
|
||||
@ -32,7 +32,7 @@ patch:
|
||||
description: 'Updates a single contact by its uuid, if permitted for the current subject.'
|
||||
operationId: patchContact
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: contactUUID
|
||||
in: path
|
||||
@ -63,7 +63,7 @@ delete:
|
||||
description: 'Delete a single business contact by its uuid, if permitted for the current subject.'
|
||||
operationId: deleteContactByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: contactUUID
|
||||
in: path
|
||||
|
@ -1,11 +1,11 @@
|
||||
get:
|
||||
summary: Returns a list of (optionally filtered) contacts.
|
||||
description: Returns the list of (optionally filtered) contacts which are visible to the current user or any of it's assumed roles.
|
||||
description: Returns the list of (optionally filtered) contacts which are visible to the current subject or any of it's assumed roles.
|
||||
tags:
|
||||
- hs-office-contacts
|
||||
operationId: listContacts
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: name
|
||||
in: query
|
||||
@ -33,7 +33,7 @@ post:
|
||||
- hs-office-contacts
|
||||
operationId: addContact
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
requestBody:
|
||||
content:
|
||||
|
@ -4,7 +4,7 @@ get:
|
||||
description: 'Fetch a single asset transaction by its uuid, if visible for the current subject.'
|
||||
operationId: getCoopAssetTransactionByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: assetTransactionUUID
|
||||
in: path
|
||||
|
@ -1,11 +1,11 @@
|
||||
get:
|
||||
summary: Returns a list of (optionally filtered) cooperative asset transactions.
|
||||
description: Returns the list of (optionally filtered) cooperative asset transactions which are visible to the current user or any of it's assumed roles.
|
||||
description: Returns the list of (optionally filtered) cooperative asset transactions which are visible to the current subject or any of it's assumed roles.
|
||||
tags:
|
||||
- hs-office-coopAssets
|
||||
operationId: listCoopAssets
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: membershipUuid
|
||||
in: query
|
||||
@ -48,7 +48,7 @@ post:
|
||||
- hs-office-coopAssets
|
||||
operationId: addCoopAssetsTransaction
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
requestBody:
|
||||
description: A JSON object describing the new cooperative assets transaction.
|
||||
|
@ -4,7 +4,7 @@ get:
|
||||
description: 'Fetch a single share transaction by its uuid, if visible for the current subject.'
|
||||
operationId: getCoopShareTransactionByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: shareTransactionUUID
|
||||
in: path
|
||||
|
@ -1,11 +1,11 @@
|
||||
get:
|
||||
summary: Returns a list of (optionally filtered) cooperative share transactions.
|
||||
description: Returns the list of (optionally filtered) cooperative share transactions which are visible to the current user or any of it's assumed roles.
|
||||
description: Returns the list of (optionally filtered) cooperative share transactions which are visible to the current subject or any of it's assumed roles.
|
||||
tags:
|
||||
- hs-office-coopShares
|
||||
operationId: listCoopShares
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: membershipUuid
|
||||
in: query
|
||||
@ -48,7 +48,7 @@ post:
|
||||
- hs-office-coopShares
|
||||
operationId: addCoopSharesTransaction
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
requestBody:
|
||||
description: A JSON object describing the new cooperative shares transaction.
|
||||
|
@ -4,7 +4,7 @@ get:
|
||||
description: 'Fetch a single debitor by its uuid, if visible for the current subject.'
|
||||
operationId: getDebitorByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: debitorUUID
|
||||
in: path
|
||||
@ -32,7 +32,7 @@ patch:
|
||||
description: 'Updates a single debitor by its uuid, if permitted for the current subject.'
|
||||
operationId: patchDebitor
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: debitorUUID
|
||||
in: path
|
||||
@ -63,7 +63,7 @@ delete:
|
||||
description: 'Delete a single debitor by its uuid, if permitted for the current subject.'
|
||||
operationId: deleteDebitorByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: debitorUUID
|
||||
in: path
|
||||
|
@ -1,11 +1,11 @@
|
||||
get:
|
||||
summary: Returns a list of (optionally filtered) debitors.
|
||||
description: Returns the list of (optionally filtered) debitors which are visible to the current user or any of it's assumed roles.
|
||||
description: Returns the list of (optionally filtered) debitors which are visible to the current subject or any of it's assumed roles.
|
||||
tags:
|
||||
- hs-office-debitors
|
||||
operationId: listDebitors
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: name
|
||||
in: query
|
||||
@ -39,7 +39,7 @@ post:
|
||||
- hs-office-debitors
|
||||
operationId: addDebitor
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
requestBody:
|
||||
content:
|
||||
|
@ -4,7 +4,7 @@ get:
|
||||
description: 'Fetch a single membership by its uuid, if visible for the current subject.'
|
||||
operationId: getMembershipByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: membershipUUID
|
||||
in: path
|
||||
@ -32,7 +32,7 @@ patch:
|
||||
description: 'Updates a single membership by its uuid, if permitted for the current subject.'
|
||||
operationId: patchMembership
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: membershipUUID
|
||||
in: path
|
||||
@ -63,7 +63,7 @@ delete:
|
||||
description: 'Delete a single membership by its uuid, if permitted for the current subject.'
|
||||
operationId: deleteMembershipByUuid
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: membershipUUID
|
||||
in: path
|
||||
|
@ -1,12 +1,12 @@
|
||||
get:
|
||||
summary: Returns a list of (optionally filtered) memberships.
|
||||
description: Returns the list of memberships which are visible to the current user or any of it's assumed roles.
|
||||
description: Returns the list of memberships which are visible to the current subject or any of it's assumed roles.
|
||||
The list can optionally be filtered by either the `partnerUuid` or the `memberNumber` - not both at the same time.
|
||||
tags:
|
||||
- hs-office-memberships
|
||||
operationId: listMemberships
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: partnerUuid
|
||||
in: query
|
||||
@ -41,7 +41,7 @@ post:
|
||||
- hs-office-memberships
|
||||
operationId: addMembership
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentUser'
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
requestBody:
|
||||
description: A JSON object describing the new membership.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user