From d4b767af0da5b4087ea31725e551d379a908e4fc Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Fri, 13 Sep 2024 17:23:35 +0200 Subject: [PATCH] renaming user to subject in API --- doc/rbac.md | 38 ++++---- sql/rbac-tests.sql | 14 +-- sql/rbac-view-option-experiments.sql | 8 +- .../asset/HsHostingAssetRbacEntity.java | 2 +- .../HsOfficeBankAccountEntity.java | 2 +- .../contact/HsOfficeContactRbacEntity.java | 2 +- .../membership/HsOfficeMembershipEntity.java | 2 +- .../office/person/HsOfficePersonEntity.java | 2 +- .../relation/HsOfficeRelationRbacEntity.java | 2 +- .../HsOfficeSepaMandateEntity.java | 2 +- .../hsadminng/rbac/rbacdef/RbacView.java | 22 ++--- .../RolesGrantsAndPermissionsGenerator.java | 2 +- .../rbac/rbacgrant/RbacGrantController.java | 4 +- .../rbac/rbacgrant/RbacGrantEntity.java | 4 +- .../rbac/rbacuser/RbacUserRepository.java | 46 --------- .../RbacSubjectController.java} | 42 ++++---- .../RbacSubjectEntity.java} | 6 +- .../RbacSubjectPermission.java} | 4 +- .../rbac/subject/RbacSubjectRepository.java | 46 +++++++++ .../rbac/test/cust/TestCustomerEntity.java | 2 +- src/main/resources/api-definition/auth.yaml | 4 +- .../api-definition/error-responses.yaml | 4 +- .../api-definition/hs-booking/auth.yaml | 4 +- .../hs-booking/error-responses.yaml | 4 +- .../hs-booking/hs-booking-items.yaml | 2 +- .../hs-booking/hs-booking-projects.yaml | 2 +- .../api-definition/hs-hosting/auth.yaml | 4 +- .../hs-hosting/error-responses.yaml | 4 +- .../hs-hosting/hs-hosting-assets.yaml | 2 +- .../hs-office/hs-office-bankaccounts.yaml | 2 +- .../hs-office/hs-office-contacts.yaml | 2 +- .../hs-office/hs-office-coopassets.yaml | 2 +- .../hs-office/hs-office-coopshares.yaml | 2 +- .../hs-office/hs-office-debitors.yaml | 2 +- .../hs-office/hs-office-memberships.yaml | 2 +- .../hs-office/hs-office-partners.yaml | 2 +- .../hs-office/hs-office-persons.yaml | 2 +- .../hs-office/hs-office-relations.yaml | 2 +- .../hs-office/hs-office-sepamandates.yaml | 2 +- .../rbac/rbac-grant-schemas.yaml | 2 +- .../rbac/rbac-grants-with-id.yaml | 4 +- .../api-definition/rbac/rbac-grants.yaml | 2 +- ...schemas.yaml => rbac-subject-schemas.yaml} | 4 +- ...=> rbac-subjects-with-id-permissions.yaml} | 8 +- ...uuid.yaml => rbac-subjects-with-uuid.yaml} | 14 +-- .../{rbac-users.yaml => rbac-subjects.yaml} | 18 ++-- .../resources/api-definition/rbac/rbac.yaml | 12 +-- .../api-definition/test/test-customers.yaml | 2 +- .../db/changelog/1-rbac/1055-rbac-views.sql | 48 +++++----- .../hsadminng/arch/ArchitectureTest.java | 2 +- .../hsadminng/hs/migration/CsvDataImport.java | 2 +- .../RbacGrantControllerAcceptanceTest.java | 66 ++++++------- .../RbacGrantRepositoryIntegrationTest.java | 34 +++---- .../RbacRoleControllerAcceptanceTest.java | 4 +- .../hsadminng/rbac/rbacuser/TestRbacUser.java | 14 --- .../RbacSubjectControllerAcceptanceTest.java} | 86 ++++++++--------- .../RbacSubjectControllerRestTest.java} | 20 ++-- .../RbacSubjectEntityUnitTest.java} | 6 +- ...RbacSubjectRepositoryIntegrationTest.java} | 96 +++++++++---------- .../rbac/subject/TestRbacSubject.java | 14 +++ 60 files changed, 376 insertions(+), 384 deletions(-) delete mode 100644 src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserRepository.java rename src/main/java/net/hostsharing/hsadminng/rbac/{rbacuser/RbacUserController.java => subject/RbacSubjectController.java} (64%) rename src/main/java/net/hostsharing/hsadminng/rbac/{rbacuser/RbacUserEntity.java => subject/RbacSubjectEntity.java} (92%) rename src/main/java/net/hostsharing/hsadminng/rbac/{rbacuser/RbacUserPermission.java => subject/RbacSubjectPermission.java} (73%) create mode 100644 src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectRepository.java rename src/main/resources/api-definition/rbac/{rbac-user-schemas.yaml => rbac-subject-schemas.yaml} (93%) rename src/main/resources/api-definition/rbac/{rbac-users-with-id-permissions.yaml => rbac-subjects-with-id-permissions.yaml} (79%) rename src/main/resources/api-definition/rbac/{rbac-users-with-uuid.yaml => rbac-subjects-with-uuid.yaml} (78%) rename src/main/resources/api-definition/rbac/{rbac-users.yaml => rbac-subjects.yaml} (66%) delete mode 100644 src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/TestRbacUser.java rename src/test/java/net/hostsharing/hsadminng/rbac/{rbacuser/RbacUserControllerAcceptanceTest.java => subject/RbacSubjectControllerAcceptanceTest.java} (82%) rename src/test/java/net/hostsharing/hsadminng/rbac/{rbacuser/RbacUserControllerRestTest.java => subject/RbacSubjectControllerRestTest.java} (83%) rename src/test/java/net/hostsharing/hsadminng/rbac/{rbacuser/RbacUserEntityUnitTest.java => subject/RbacSubjectEntityUnitTest.java} (91%) rename src/test/java/net/hostsharing/hsadminng/rbac/{rbacuser/RbacUserRepositoryIntegrationTest.java => subject/RbacSubjectRepositoryIntegrationTest.java} (82%) create mode 100644 src/test/java/net/hostsharing/hsadminng/rbac/subject/TestRbacSubject.java diff --git a/doc/rbac.md b/doc/rbac.md index e7cb12d3..f859e2e1 100644 --- a/doc/rbac.md +++ b/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 <> -- 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 @@ -365,7 +365,7 @@ 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.currentSubject` which contains the name of the user as stored in the -*RbacUser*s table. Example: +*RbacSubject*s table. Example: SET LOCAL hsadminng.currentSubject = 'mike@hostsharing.net'; @@ -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. diff --git a/sql/rbac-tests.sql b/sql/rbac-tests.sql index 351d1509..e04b2177 100644 --- a/sql/rbac-tests.sql +++ b/sql/rbac-tests.sql @@ -9,21 +9,21 @@ select isGranted(findRoleId('test_package#aaa00:OWNER'), findRoleId('administrat -- call grantRoleToRole(findRoleId('administrators'), findRoleId('test_package#aaa00:OWNER')); select count(*) -FROM queryAllPermissionsOfSubjectIdForObjectUuids(findRbacUser('superuser-fran@hostsharing.net'), +FROM queryAllPermissionsOfSubjectIdForObjectUuids(findRbacSubject('superuser-fran@hostsharing.net'), ARRAY(select uuid from customer where reference < 1100000)); select count(*) -FROM queryAllPermissionsOfSubjectId(findRbacUser('superuser-fran@hostsharing.net')); +FROM queryAllPermissionsOfSubjectId(findRbacSubject('superuser-fran@hostsharing.net')); select * -FROM queryAllPermissionsOfSubjectId(findRbacUser('alex@example.com')); +FROM queryAllPermissionsOfSubjectId(findRbacSubject('alex@example.com')); select * -FROM queryAllPermissionsOfSubjectId(findRbacUser('rosa@example.com')); +FROM queryAllPermissionsOfSubjectId(findRbacSubject('rosa@example.com')); select * -FROM queryAllRbacUsersWithPermissionsFor(findEffectivePermissionId('customer', +FROM queryAllRbacSubjectsWithPermissionsFor(findEffectivePermissionId('customer', (SELECT uuid FROM RbacObject WHERE objectTable = 'customer' LIMIT 1), 'add-package')); select * -FROM queryAllRbacUsersWithPermissionsFor(findEffectivePermissionId('package', +FROM queryAllRbacSubjectsWithPermissionsFor(findEffectivePermissionId('package', (SELECT uuid FROM RbacObject WHERE objectTable = 'package' LIMIT 1), 'DELETE')); @@ -33,7 +33,7 @@ $$ userId uuid; result bool; BEGIN - userId = findRbacUser('superuser-alex@hostsharing.net'); + userId = findRbacSubject('superuser-alex@hostsharing.net'); result = (SELECT * FROM isPermissionGrantedToSubject(findPermissionId('package', 94928, 'add-package'), userId)); IF (result) THEN RAISE EXCEPTION 'expected permission NOT to be granted, but it is'; diff --git a/sql/rbac-view-option-experiments.sql b/sql/rbac-view-option-experiments.sql index d058ac49..be38d3a4 100644 --- a/sql/rbac-view-option-experiments.sql +++ b/sql/rbac-view-option-experiments.sql @@ -38,7 +38,7 @@ CREATE OR REPLACE RULE "_RETURN" AS SELECT * FROM customer WHERE isPermissionGrantedToSubject(findEffectivePermissionId('test_customer', id, 'SELECT'), rbac.currentSubjectUuid()); SELECT * from cust_view LIMIT 10; -select queryAllPermissionsOfSubjectId(findRbacUser('superuser-alex@hostsharing.net')); +select 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; @@ -80,10 +80,10 @@ SELECT * from cust_view where reference=1144150; select rr.uuid, rr.type from RbacGrants g join RbacReference RR on g.ascendantUuid = RR.uuid where g.descendantUuid in ( - select uuid from queryAllPermissionsOfSubjectId(findRbacUser('alex@example.com')) + select uuid from queryAllPermissionsOfSubjectId(findRbacSubject('alex@example.com')) where objectTable='test_customer'); -call grantRoleToUser(findRoleId('test_customer#aaa:ADMIN'), findRbacUser('aaaaouq@example.com')); +call grantRoleToUser(findRoleId('test_customer#aaa:ADMIN'), findRbacSubject('aaaaouq@example.com')); -select queryAllPermissionsOfSubjectId(findRbacUser('aaaaouq@example.com')); +select queryAllPermissionsOfSubjectId(findRbacSubject('aaaaouq@example.com')); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRbacEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRbacEntity.java index be568944..bd432dfa 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRbacEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRbacEntity.java @@ -22,7 +22,7 @@ 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.RbacSubjectReference.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; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntity.java index 94fe2b16..e58361b7 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/bankaccount/HsOfficeBankAccountEntity.java @@ -14,7 +14,7 @@ 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.RbacSubjectReference.UserRole.CREATOR; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*; import static net.hostsharing.hsadminng.stringify.Stringify.stringify; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacEntity.java index c4e934cc..0716f1e7 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/contact/HsOfficeContactRbacEntity.java @@ -11,7 +11,7 @@ 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.RbacSubjectReference.UserRole.CREATOR; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java index 9d05f5f9..447d92ba 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/membership/HsOfficeMembershipEntity.java @@ -45,7 +45,7 @@ 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.RbacSubjectReference.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; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java index dd21a5c3..ccf44d55 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/person/HsOfficePersonEntity.java @@ -16,7 +16,7 @@ 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.RbacSubjectReference.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.stringify.Stringify.stringify; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacEntity.java index f081404e..bd4274aa 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/relation/HsOfficeRelationRbacEntity.java @@ -24,7 +24,7 @@ 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.RbacSubjectReference.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; diff --git a/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntity.java index a57ee32a..27f5b221 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/office/sepamandate/HsOfficeSepaMandateEntity.java @@ -26,7 +26,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingD 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.RbacSubjectReference.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; diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacView.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacView.java index 32f5d7af..f282563a 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacView.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RbacView.java @@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingD 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.RbacSubjectReference.UserRole.CREATOR; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.Part.AUTO_FETCH; import static org.apache.commons.collections4.SetUtils.hashSet; import static org.apache.commons.lang3.StringUtils.uncapitalize; @@ -41,7 +41,7 @@ public class RbacView { private final EntityAlias rootEntityAlias; - private final Set userDefs = new LinkedHashSet<>(); + private final Set userDefs = new LinkedHashSet<>(); private final Set roleDefs = new LinkedHashSet<>(); private final Set permDefs = new LinkedHashSet<>(); private final Map entityAliases = new HashMap<>() { @@ -97,7 +97,7 @@ public class RbacView { RbacView(final String alias, final Class entityClass) { rootEntityAlias = new EntityAlias(alias, entityClass); entityAliases.put(alias, rootEntityAlias); - new RbacUserReference(CREATOR); + new RbacSubjectReference(CREATOR); entityAliases.put("global", new EntityAlias("global")); } @@ -467,7 +467,7 @@ public class RbacView { return new RbacExampleRole(entityAlias, role); } - private RbacGrantDefinition grantRoleToSubject(final RbacRoleDefinition roleDefinition, final RbacUserReference user) { + private RbacGrantDefinition grantRoleToSubject(final RbacRoleDefinition roleDefinition, final RbacSubjectReference user) { return findOrCreateGrantDef(roleDefinition, user).toCreate(); } @@ -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,7 +770,7 @@ public class RbacView { * @return * The grant definition for further chained calls. */ - public RbacGrantDefinition owningUser(final RbacUserReference.UserRole 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() diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java index 7b3d9d06..c8d1796d 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacdef/RolesGrantsAndPermissionsGenerator.java @@ -578,7 +578,7 @@ class RolesGrantsAndPermissionsGenerator { plPgSql.writeLn(); } - private String toPlPgSqlReference(final RbacView.RbacUserReference userRef) { + private String toPlPgSqlReference(final RbacView.RbacSubjectReference userRef) { return switch (userRef.role) { case CREATOR -> "currentSubjectUuid()"; default -> throw new IllegalArgumentException("unknown user role: " + userRef); diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantController.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantController.java index a002254d..fce1f33b 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantController.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantController.java @@ -50,7 +50,7 @@ public class RbacGrantController implements RbacGrantsApi { @Override @Transactional(readOnly = true) - public ResponseEntity> listUserGrants( + public ResponseEntity> listSubjectGrants( final String currentSubject, final String assumedRoles) { @@ -97,7 +97,7 @@ public class RbacGrantController implements RbacGrantsApi { // TODO.feat: implement an endpoint to create a Mermaid flowchart with all grants of a given user // @GetMapping( -// path = "/api/rbac/users/{subjectUuid}/grants", +// path = "/api/rbac/subjects/{subjectUuid}/grants", // produces = {"text/vnd.mermaid"}) // @Transactional(readOnly = true) // public ResponseEntity allGrantsOfUserAsMermaid( diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantEntity.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantEntity.java index 88541762..bb422f62 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantEntity.java @@ -33,7 +33,7 @@ public class RbacGrantEntity { private UUID grantedRoleUuid; @Column(name = "username", updatable = false, insertable = false) - private String granteeUserName; + private String granteeSubjectName; @Id @Column(name = "subjectuuid") @@ -60,7 +60,7 @@ public class RbacGrantEntity { public String toDisplay() { return "{ grant role:" + grantedRoleIdName + - " to user:" + granteeUserName + + " to user:" + granteeSubjectName + " by role:" + grantedByRoleIdName + (assumed ? " and assume" : "") + " }"; diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserRepository.java b/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserRepository.java deleted file mode 100644 index 88d854c2..00000000 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserRepository.java +++ /dev/null @@ -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 { - - @Query(""" - select u from RbacUserEntity u - where :userName is null or u.name like concat(cast(:userName as text), '%') - order by u.name - """) - List 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) - RbacUserEntity findByName(String userName); - - RbacUserEntity findByUuid(UUID uuid); - - @Query(value = "select * from grantedPermissions(:subjectUuid)", nativeQuery = true) - List 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 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 subjectUuid); -} diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserController.java b/src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectController.java similarity index 64% rename from src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserController.java rename to src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectController.java index 10add2fb..52c0649b 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserController.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectController.java @@ -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,73 +24,73 @@ public class RbacUserController implements RbacUsersApi { private Mapper mapper; @Autowired - private RbacUserRepository rbacUserRepository; + private RbacSubjectRepository rbacSubjectRepository; @Override @Transactional - public ResponseEntity createUser( - final RbacUserResource body + public ResponseEntity 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 deleteUserByUuid( + public ResponseEntity deleteSubjectByUuid( final String currentSubject, final String assumedRoles, final UUID subjectUuid ) { context.define(currentSubject, assumedRoles); - rbacUserRepository.deleteByUuid(subjectUuid); + rbacSubjectRepository.deleteByUuid(subjectUuid); return ResponseEntity.noContent().build(); } @Override @Transactional(readOnly = true) - public ResponseEntity getUserById( + public ResponseEntity getSubjectById( final String currentSubject, final String assumedRoles, final UUID subjectUuid) { context.define(currentSubject, assumedRoles); - final var result = rbacUserRepository.findByUuid(subjectUuid); + 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> listUsers( + public ResponseEntity> listSubjects( final String currentSubject, final String assumedRoles, final String userName ) { 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> listUserPermissions( + public ResponseEntity> listSubjectPermissions( final String currentSubject, final String assumedRoles, final UUID subjectUuid @@ -98,7 +98,7 @@ public class RbacUserController implements RbacUsersApi { context.define(currentSubject, assumedRoles); return ResponseEntity.ok(mapper.mapList( - rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid), - RbacUserPermissionResource.class)); + rbacSubjectRepository.findPermissionsOfUserByUuid(subjectUuid), + RbacSubjectPermissionResource.class)); } } diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntity.java b/src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectEntity.java similarity index 92% rename from src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntity.java rename to src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectEntity.java index 8da64357..3ff2c81d 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectEntity.java @@ -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"); diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserPermission.java b/src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectPermission.java similarity index 73% rename from src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserPermission.java rename to src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectPermission.java index f29503c3..9a82ad2d 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserPermission.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectPermission.java @@ -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(); diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectRepository.java b/src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectRepository.java new file mode 100644 index 00000000..16a13962 --- /dev/null +++ b/src/main/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectRepository.java @@ -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 { + + @Query(""" + select u from RbacSubjectEntity u + where :userName is null or u.name like concat(cast(:userName as text), '%') + order by u.name + """) + List 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 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); +} diff --git a/src/main/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerEntity.java b/src/main/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerEntity.java index 72df9c48..8bed127c 100644 --- a/src/main/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/rbac/test/cust/TestCustomerEntity.java @@ -15,7 +15,7 @@ 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.RbacSubjectReference.UserRole.CREATOR; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.*; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor; diff --git a/src/main/resources/api-definition/auth.yaml b/src/main/resources/api-definition/auth.yaml index e46f0f38..138c5eaa 100644 --- a/src/main/resources/api-definition/auth.yaml +++ b/src/main/resources/api-definition/auth.yaml @@ -9,7 +9,7 @@ components: 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. diff --git a/src/main/resources/api-definition/error-responses.yaml b/src/main/resources/api-definition/error-responses.yaml index 83ca3dfb..d7999f91 100644 --- a/src/main/resources/api-definition/error-responses.yaml +++ b/src/main/resources/api-definition/error-responses.yaml @@ -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: diff --git a/src/main/resources/api-definition/hs-booking/auth.yaml b/src/main/resources/api-definition/hs-booking/auth.yaml index e46f0f38..0aa48bf5 100644 --- a/src/main/resources/api-definition/hs-booking/auth.yaml +++ b/src/main/resources/api-definition/hs-booking/auth.yaml @@ -9,7 +9,7 @@ components: 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. diff --git a/src/main/resources/api-definition/hs-booking/error-responses.yaml b/src/main/resources/api-definition/hs-booking/error-responses.yaml index 83ca3dfb..d7999f91 100644 --- a/src/main/resources/api-definition/hs-booking/error-responses.yaml +++ b/src/main/resources/api-definition/hs-booking/error-responses.yaml @@ -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: diff --git a/src/main/resources/api-definition/hs-booking/hs-booking-items.yaml b/src/main/resources/api-definition/hs-booking/hs-booking-items.yaml index fca2209a..e18e4926 100644 --- a/src/main/resources/api-definition/hs-booking/hs-booking-items.yaml +++ b/src/main/resources/api-definition/hs-booking/hs-booking-items.yaml @@ -1,6 +1,6 @@ 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 diff --git a/src/main/resources/api-definition/hs-booking/hs-booking-projects.yaml b/src/main/resources/api-definition/hs-booking/hs-booking-projects.yaml index e5081a6f..3b567346 100644 --- a/src/main/resources/api-definition/hs-booking/hs-booking-projects.yaml +++ b/src/main/resources/api-definition/hs-booking/hs-booking-projects.yaml @@ -1,6 +1,6 @@ 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 diff --git a/src/main/resources/api-definition/hs-hosting/auth.yaml b/src/main/resources/api-definition/hs-hosting/auth.yaml index e46f0f38..0aa48bf5 100644 --- a/src/main/resources/api-definition/hs-hosting/auth.yaml +++ b/src/main/resources/api-definition/hs-hosting/auth.yaml @@ -9,7 +9,7 @@ components: 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. diff --git a/src/main/resources/api-definition/hs-hosting/error-responses.yaml b/src/main/resources/api-definition/hs-hosting/error-responses.yaml index 83ca3dfb..d7999f91 100644 --- a/src/main/resources/api-definition/hs-hosting/error-responses.yaml +++ b/src/main/resources/api-definition/hs-hosting/error-responses.yaml @@ -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: diff --git a/src/main/resources/api-definition/hs-hosting/hs-hosting-assets.yaml b/src/main/resources/api-definition/hs-hosting/hs-hosting-assets.yaml index 6396d2a7..8aae49a8 100644 --- a/src/main/resources/api-definition/hs-hosting/hs-hosting-assets.yaml +++ b/src/main/resources/api-definition/hs-hosting/hs-hosting-assets.yaml @@ -1,6 +1,6 @@ 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 diff --git a/src/main/resources/api-definition/hs-office/hs-office-bankaccounts.yaml b/src/main/resources/api-definition/hs-office/hs-office-bankaccounts.yaml index 2207fd9c..316fc250 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-bankaccounts.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-bankaccounts.yaml @@ -1,6 +1,6 @@ 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 diff --git a/src/main/resources/api-definition/hs-office/hs-office-contacts.yaml b/src/main/resources/api-definition/hs-office/hs-office-contacts.yaml index 03a6ff70..cc3f56af 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-contacts.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-contacts.yaml @@ -1,6 +1,6 @@ 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 diff --git a/src/main/resources/api-definition/hs-office/hs-office-coopassets.yaml b/src/main/resources/api-definition/hs-office/hs-office-coopassets.yaml index 24ffd3d1..bff3e1d5 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-coopassets.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-coopassets.yaml @@ -1,6 +1,6 @@ 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 diff --git a/src/main/resources/api-definition/hs-office/hs-office-coopshares.yaml b/src/main/resources/api-definition/hs-office/hs-office-coopshares.yaml index a886ab82..215df97e 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-coopshares.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-coopshares.yaml @@ -1,6 +1,6 @@ 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 diff --git a/src/main/resources/api-definition/hs-office/hs-office-debitors.yaml b/src/main/resources/api-definition/hs-office/hs-office-debitors.yaml index e0327d2f..16554531 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-debitors.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-debitors.yaml @@ -1,6 +1,6 @@ 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 diff --git a/src/main/resources/api-definition/hs-office/hs-office-memberships.yaml b/src/main/resources/api-definition/hs-office/hs-office-memberships.yaml index e394faf0..8436134b 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-memberships.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-memberships.yaml @@ -1,6 +1,6 @@ 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 diff --git a/src/main/resources/api-definition/hs-office/hs-office-partners.yaml b/src/main/resources/api-definition/hs-office/hs-office-partners.yaml index 1936a7cb..9e97a91d 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-partners.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-partners.yaml @@ -1,6 +1,6 @@ get: summary: Returns a list of (optionally filtered) business partners. - description: Returns the list of (optionally filtered) business partners which are visible to the current user or any of it's assumed roles. + description: Returns the list of (optionally filtered) business partners which are visible to the current subject or any of it's assumed roles. tags: - hs-office-partners operationId: listPartners diff --git a/src/main/resources/api-definition/hs-office/hs-office-persons.yaml b/src/main/resources/api-definition/hs-office/hs-office-persons.yaml index 71471c83..e761957c 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-persons.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-persons.yaml @@ -1,6 +1,6 @@ get: summary: Returns a list of (optionally filtered) persons. - description: Returns the list of (optionally filtered) persons which are visible to the current user or any of it's assumed roles. + description: Returns the list of (optionally filtered) persons which are visible to the current subject or any of it's assumed roles. tags: - hs-office-persons operationId: listPersons diff --git a/src/main/resources/api-definition/hs-office/hs-office-relations.yaml b/src/main/resources/api-definition/hs-office/hs-office-relations.yaml index 0bcb9145..ce7a865b 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-relations.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-relations.yaml @@ -1,6 +1,6 @@ get: summary: Returns a list of (optionally filtered) person relations for a given person. - description: Returns the list of (optionally filtered) person relations of a given person and which are visible to the current user or any of it's assumed roles. + description: Returns the list of (optionally filtered) person relations of a given person and which are visible to the current subject or any of it's assumed roles. tags: - hs-office-relations operationId: listRelations diff --git a/src/main/resources/api-definition/hs-office/hs-office-sepamandates.yaml b/src/main/resources/api-definition/hs-office/hs-office-sepamandates.yaml index 76f28092..3050ab79 100644 --- a/src/main/resources/api-definition/hs-office/hs-office-sepamandates.yaml +++ b/src/main/resources/api-definition/hs-office/hs-office-sepamandates.yaml @@ -1,6 +1,6 @@ get: summary: Returns a list of (optionally filtered) SEPA Mandates. - description: Returns the list of (optionally filtered) SEPA Mandates which are visible to the current user or any of it's assumed roles. + description: Returns the list of (optionally filtered) SEPA Mandates which are visible to the current subject or any of it's assumed roles. tags: - hs-office-sepaMandates operationId: listSepaMandatesByIBAN diff --git a/src/main/resources/api-definition/rbac/rbac-grant-schemas.yaml b/src/main/resources/api-definition/rbac/rbac-grant-schemas.yaml index 4f64f575..90700354 100644 --- a/src/main/resources/api-definition/rbac/rbac-grant-schemas.yaml +++ b/src/main/resources/api-definition/rbac/rbac-grant-schemas.yaml @@ -18,7 +18,7 @@ components: grantedRoleUuid: type: string format: uuid - granteeUserName: + granteeSubjectName: type: string granteeSubjectUuid: type: string diff --git a/src/main/resources/api-definition/rbac/rbac-grants-with-id.yaml b/src/main/resources/api-definition/rbac/rbac-grants-with-id.yaml index be0b1e08..ddda4510 100644 --- a/src/main/resources/api-definition/rbac/rbac-grants-with-id.yaml +++ b/src/main/resources/api-definition/rbac/rbac-grants-with-id.yaml @@ -18,7 +18,7 @@ get: schema: type: string format: uuid - description: UUID of the user to whom the role was granted. + description: UUID of the subject to who the role was granted. responses: "200": description: OK @@ -53,7 +53,7 @@ delete: schema: type: string format: uuid - description: UUID of the user to whom the role was granted. + description: UUID of the subject to which the role was granted. responses: "204": description: No Content diff --git a/src/main/resources/api-definition/rbac/rbac-grants.yaml b/src/main/resources/api-definition/rbac/rbac-grants.yaml index 4fbfd43c..7c5392cd 100644 --- a/src/main/resources/api-definition/rbac/rbac-grants.yaml +++ b/src/main/resources/api-definition/rbac/rbac-grants.yaml @@ -1,7 +1,7 @@ get: tags: - rbac-grants - operationId: listUserGrants + operationId: listSubjectGrants parameters: - $ref: 'auth.yaml#/components/parameters/currentSubject' - $ref: 'auth.yaml#/components/parameters/assumedRoles' diff --git a/src/main/resources/api-definition/rbac/rbac-user-schemas.yaml b/src/main/resources/api-definition/rbac/rbac-subject-schemas.yaml similarity index 93% rename from src/main/resources/api-definition/rbac/rbac-user-schemas.yaml rename to src/main/resources/api-definition/rbac/rbac-subject-schemas.yaml index c7ca49c0..9cb8ec0f 100644 --- a/src/main/resources/api-definition/rbac/rbac-user-schemas.yaml +++ b/src/main/resources/api-definition/rbac/rbac-subject-schemas.yaml @@ -3,7 +3,7 @@ components: schemas: - RbacUser: + RbacSubject: type: object properties: uuid: @@ -11,7 +11,7 @@ components: format: uuid name: type: string - RbacUserPermission: + RbacSubjectPermission: type: object properties: objectUuid: diff --git a/src/main/resources/api-definition/rbac/rbac-users-with-id-permissions.yaml b/src/main/resources/api-definition/rbac/rbac-subjects-with-id-permissions.yaml similarity index 79% rename from src/main/resources/api-definition/rbac/rbac-users-with-id-permissions.yaml rename to src/main/resources/api-definition/rbac/rbac-subjects-with-id-permissions.yaml index dd3594ca..a92407db 100644 --- a/src/main/resources/api-definition/rbac/rbac-users-with-id-permissions.yaml +++ b/src/main/resources/api-definition/rbac/rbac-subjects-with-id-permissions.yaml @@ -1,8 +1,8 @@ get: tags: - - rbac-users - description: 'List all visible permissions granted to the given user; reduced ' - operationId: listUserPermissions + - rbac-subjects + description: 'List all visible permissions granted to the given subject; reduced ' + operationId: listSubjectPermissions parameters: - $ref: 'auth.yaml#/components/parameters/currentSubject' - $ref: 'auth.yaml#/components/parameters/assumedRoles' @@ -20,7 +20,7 @@ get: schema: type: array items: - $ref: 'rbac-user-schemas.yaml#/components/schemas/RbacUserPermission' + $ref: 'rbac-subject-schemas.yaml#/components/schemas/RbacSubjectPermission' "401": $ref: 'error-responses.yaml#/components/responses/Unauthorized' diff --git a/src/main/resources/api-definition/rbac/rbac-users-with-uuid.yaml b/src/main/resources/api-definition/rbac/rbac-subjects-with-uuid.yaml similarity index 78% rename from src/main/resources/api-definition/rbac/rbac-users-with-uuid.yaml rename to src/main/resources/api-definition/rbac/rbac-subjects-with-uuid.yaml index fa6de05f..67e0ac6d 100644 --- a/src/main/resources/api-definition/rbac/rbac-users-with-uuid.yaml +++ b/src/main/resources/api-definition/rbac/rbac-subjects-with-uuid.yaml @@ -1,8 +1,8 @@ get: tags: - - rbac-users - description: 'Fetch a single user by its id, if visible for the current subject.' - operationId: getUserById + - rbac-subjects + description: 'Fetch a single subject by its id, if visible for the current subject.' + operationId: getSubjectById parameters: - $ref: 'auth.yaml#/components/parameters/currentSubject' - $ref: 'auth.yaml#/components/parameters/assumedRoles' @@ -18,7 +18,7 @@ get: content: 'application/json': schema: - $ref: 'rbac-user-schemas.yaml#/components/schemas/RbacUser' + $ref: 'rbac-subject-schemas.yaml#/components/schemas/RbacSubject' "401": $ref: 'error-responses.yaml#/components/responses/Unauthorized' @@ -28,8 +28,8 @@ get: delete: tags: - - rbac-users - operationId: deleteUserByUuid + - rbac-subjects + operationId: deleteSubjectByUuid parameters: - $ref: 'auth.yaml#/components/parameters/currentSubject' - $ref: 'auth.yaml#/components/parameters/assumedRoles' @@ -39,7 +39,7 @@ delete: schema: type: string format: uuid - description: UUID of the user to delete. + description: UUID of the subject to delete. responses: "204": description: No Content diff --git a/src/main/resources/api-definition/rbac/rbac-users.yaml b/src/main/resources/api-definition/rbac/rbac-subjects.yaml similarity index 66% rename from src/main/resources/api-definition/rbac/rbac-users.yaml rename to src/main/resources/api-definition/rbac/rbac-subjects.yaml index e447f25d..0877163e 100644 --- a/src/main/resources/api-definition/rbac/rbac-users.yaml +++ b/src/main/resources/api-definition/rbac/rbac-subjects.yaml @@ -1,8 +1,8 @@ get: tags: - - rbac-users - description: List accessible RBAC users with optional filter by name. - operationId: listUsers + - rbac-subjects + description: List accessible RBAC subjects with optional filter by name. + operationId: listSubjects parameters: - $ref: 'auth.yaml#/components/parameters/currentSubject' - $ref: 'auth.yaml#/components/parameters/assumedRoles' @@ -19,7 +19,7 @@ get: schema: type: array items: - $ref: 'rbac-user-schemas.yaml#/components/schemas/RbacUser' + $ref: 'rbac-subject-schemas.yaml#/components/schemas/RbacSubject' '401': $ref: 'error-responses.yaml#/components/responses/Unauthorized' '403': @@ -27,22 +27,22 @@ get: post: tags: - - rbac-users - description: Create a new RBAC user. - operationId: createUser + - rbac-subjects + description: Create a new RBAC subject (e.g. user). + operationId: createSubject requestBody: required: true content: application/json: schema: - $ref: 'rbac-user-schemas.yaml#/components/schemas/RbacUser' + $ref: 'rbac-subject-schemas.yaml#/components/schemas/RbacSubject' responses: '201': description: Created content: 'application/json': schema: - $ref: 'rbac-user-schemas.yaml#/components/schemas/RbacUser' + $ref: 'rbac-subject-schemas.yaml#/components/schemas/RbacSubject' '409': $ref: 'error-responses.yaml#/components/responses/Conflict' diff --git a/src/main/resources/api-definition/rbac/rbac.yaml b/src/main/resources/api-definition/rbac/rbac.yaml index a02e3cd9..463692d0 100644 --- a/src/main/resources/api-definition/rbac/rbac.yaml +++ b/src/main/resources/api-definition/rbac/rbac.yaml @@ -8,14 +8,14 @@ servers: paths: - /api/rbac/users: - $ref: 'rbac-users.yaml' + /api/rbac/subjects: + $ref: 'rbac-subjects.yaml' - /api/rbac/users/{subjectUuid}/permissions: - $ref: 'rbac-users-with-id-permissions.yaml' + /api/rbac/subjects/{subjectUuid}/permissions: + $ref: 'rbac-subjects-with-id-permissions.yaml' - /api/rbac/users/{subjectUuid}: - $ref: 'rbac-users-with-uuid.yaml' + /api/rbac/subjects/{subjectUuid}: + $ref: 'rbac-subjects-with-uuid.yaml' /api/rbac/roles: $ref: 'rbac-roles.yaml' diff --git a/src/main/resources/api-definition/test/test-customers.yaml b/src/main/resources/api-definition/test/test-customers.yaml index 25800099..8e81426a 100644 --- a/src/main/resources/api-definition/test/test-customers.yaml +++ b/src/main/resources/api-definition/test/test-customers.yaml @@ -1,6 +1,6 @@ get: summary: Returns a list of (optionally filtered) customers. - description: Returns the list of (optionally filtered) customers which are visible to the current user or any of it's assumed roles. + description: Returns the list of (optionally filtered) customers which are visible to the current subject or any of it's assumed roles. tags: - testCustomers operationId: listCustomers diff --git a/src/main/resources/db/changelog/1-rbac/1055-rbac-views.sql b/src/main/resources/db/changelog/1-rbac/1055-rbac-views.sql index 0efd2c45..974bf7e8 100644 --- a/src/main/resources/db/changelog/1-rbac/1055-rbac-views.sql +++ b/src/main/resources/db/changelog/1-rbac/1055-rbac-views.sql @@ -204,8 +204,8 @@ execute function rbac.delete_grant_tf(); Creates a view to the users table with additional columns for easier human readability. */ -drop view if exists RbacUser_ev; -create or replace view RbacUser_ev as +drop view if exists rbac.subject_ev; +create or replace view rbac.subject_ev as select distinct * -- @formatter:off from ( @@ -229,8 +229,8 @@ select distinct * Creates a view to the users table with row-level limitation based on the grants of the current user or assumed roles. */ -drop view if exists RbacUser_rv; -create or replace view RbacUser_rv as +drop view if exists rbac.subject_rv; +create or replace view rbac.subject_rv as select distinct * -- @formatter:off from ( @@ -247,7 +247,7 @@ create or replace view RbacUser_rv as ) as unordered -- @formatter:on order by unordered.name; -grant all privileges on RbacUser_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}; +grant all privileges on rbac.subject_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}; --// -- ============================================================================ @@ -255,9 +255,9 @@ grant all privileges on RbacUser_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME} -- ---------------------------------------------------------------------------- /** - Instead of insert trigger function for RbacUser_rv. + Instead of insert trigger function for rbac.subject_rv. */ -create or replace function insertRbacUser() +create or replace function rbac.insert_subject_tf() returns trigger language plpgsql as $$ declare @@ -277,13 +277,13 @@ end; $$; /* - Creates an instead of insert trigger for the RbacUser_rv view. + Creates an instead of insert trigger for the rbac.subject_rv view. */ -create trigger insertRbacUser_Trigger +create trigger insert_subject_tg instead of insert - on RbacUser_rv + on rbac.subject_rv for each row -execute function insertRbacUser(); +execute function rbac.insert_subject_tf(); --// -- ============================================================================ @@ -291,11 +291,11 @@ execute function insertRbacUser(); -- ---------------------------------------------------------------------------- /** - Instead of delete trigger function for RbacUser_RV. + Instead of delete trigger function for rbac.subject_rv. Checks if the current subject (user / assumed role) has the permission to delete the user. */ -create or replace function deleteRbacUser() +create or replace function delete_subject_tf() returns trigger language plpgsql as $$ begin @@ -307,13 +307,13 @@ begin end; $$; /* - Creates an instead of delete trigger for the RbacUser_rv view. + Creates an instead of delete trigger for the rbac.subject_rv view. */ -create trigger deleteRbacUser_Trigger +create trigger delete_subject_tg instead of delete - on RbacUser_rv + on rbac.subject_rv for each row -execute function deleteRbacUser(); +execute function delete_subject_tf(); --/ -- ============================================================================ @@ -324,8 +324,8 @@ execute function deleteRbacUser(); based on the grants of the current user or assumed roles. */ -- @formatter:off -drop view if exists RbacOwnGrantedPermissions_rv; -create or replace view RbacOwnGrantedPermissions_rv as +drop view if exists rbac.own_granted_permissions_rv; +create or replace view rbac.own_granted_permissions_rv as select r.uuid as roleuuid, p.uuid as permissionUuid, (r.objecttable || ':' || r.objectidname || ':' || r.roletype) as roleName, p.op, o.objecttable, r.objectidname, o.uuid as objectuuid @@ -333,7 +333,7 @@ select r.uuid as roleuuid, p.uuid as permissionUuid, join rbacgrants g on g.ascendantuuid = r.uuid join rbacpermission p on p.uuid = g.descendantuuid join rbac.object o on o.uuid = p.objectuuid; -grant all privileges on RbacOwnGrantedPermissions_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}; +grant all privileges on rbac.own_granted_permissions_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME}; -- @formatter:om -- ============================================================================ @@ -343,7 +343,7 @@ grant all privileges on RbacOwnGrantedPermissions_rv to ${HSADMINNG_POSTGRES_RES Returns all permissions granted to the given user, which are also visible to the current user or assumed roles. */ -create or replace function grantedPermissionsRaw(targetSubjectUuid uuid) +create or replace function rbac.grantedPermissionsRaw(targetSubjectUuid uuid) returns table(roleUuid uuid, roleName text, permissionUuid uuid, op RbacOp, opTableName varchar(60), objectTable varchar(60), objectIdName varchar, objectUuid uuid) returns null on null input language plpgsql as $$ @@ -379,14 +379,14 @@ begin -- @formatter:on end; $$; -create or replace function grantedPermissions(targetSubjectUuid uuid) +create or replace function rbac.grantedPermissions(targetSubjectUuid uuid) returns table(roleUuid uuid, roleName text, permissionUuid uuid, op RbacOp, opTableName varchar(60), objectTable varchar(60), objectIdName varchar, objectUuid uuid) returns null on null input language sql as $$ - select * from grantedPermissionsRaw(targetSubjectUuid) + select * from rbac.grantedPermissionsRaw(targetSubjectUuid) union all select roleUuid, roleName, permissionUuid, 'SELECT'::RbacOp, opTableName, objectTable, objectIdName, objectUuid - from grantedPermissionsRaw(targetSubjectUuid) + from rbac.grantedPermissionsRaw(targetSubjectUuid) where op <> 'SELECT'::RbacOp; $$; --// diff --git a/src/test/java/net/hostsharing/hsadminng/arch/ArchitectureTest.java b/src/test/java/net/hostsharing/hsadminng/arch/ArchitectureTest.java index 85a1d462..ee19f534 100644 --- a/src/test/java/net/hostsharing/hsadminng/arch/ArchitectureTest.java +++ b/src/test/java/net/hostsharing/hsadminng/arch/ArchitectureTest.java @@ -68,7 +68,7 @@ public class ArchitectureTest { "..mapper", "..ping", "..rbac", - "..rbac.rbacuser", + "..rbac.rbacSubject", "..rbac.rbacgrant", "..rbac.rbacrole", "..rbac.rbacobject", diff --git a/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java b/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java index 553cc045..60bb12dd 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/migration/CsvDataImport.java @@ -298,7 +298,7 @@ public class CsvDataImport extends ContextBasedTest { protected void deleteFromCommonTables() { jpaAttempt.transacted(() -> { context(rbacSuperuser); - em.createNativeQuery("delete from rbacuser_rv where name not like 'superuser-%'").executeUpdate(); + em.createNativeQuery("delete from rbac.subject_rv where name not like 'superuser-%'").executeUpdate(); em.createNativeQuery("delete from basis.tx_journal where true").executeUpdate(); em.createNativeQuery("delete from basis.tx_context where true").executeUpdate(); }).assertSuccessful(); diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantControllerAcceptanceTest.java index 402aee38..fca0ab74 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantControllerAcceptanceTest.java @@ -7,8 +7,8 @@ import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.rbac.context.ContextBasedTest; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleEntity; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository; -import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity; -import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository; +import net.hostsharing.hsadminng.rbac.subject.RbacSubjectEntity; +import net.hostsharing.hsadminng.rbac.subject.RbacSubjectRepository; import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import org.apache.commons.lang3.RandomStringUtils; import org.junit.jupiter.api.Nested; @@ -43,7 +43,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { EntityManager em; @Autowired - RbacUserRepository rbacUserRepository; + RbacSubjectRepository rbacSubjectRepository; @Autowired RbacRoleRepository rbacRoleRepository; @@ -73,7 +73,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { // TODO: should there be a grantedByRole or just a grantedByTrigger? hasEntry("grantedByRoleIdName", "test_customer#xxx:OWNER"), hasEntry("grantedRoleIdName", "test_customer#xxx:ADMIN"), - hasEntry("granteeUserName", "customer-admin@xxx.example.com") + hasEntry("granteeSubjectName", "customer-admin@xxx.example.com") ) )) .body("", hasItem( @@ -81,28 +81,28 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { // TODO: should there be a grantedByRole or just a grantedByTrigger? hasEntry("grantedByRoleIdName", "test_customer#yyy:OWNER"), hasEntry("grantedRoleIdName", "test_customer#yyy:ADMIN"), - hasEntry("granteeUserName", "customer-admin@yyy.example.com") + hasEntry("granteeSubjectName", "customer-admin@yyy.example.com") ) )) .body("", hasItem( allOf( hasEntry("grantedByRoleIdName", "global#global:ADMIN"), hasEntry("grantedRoleIdName", "global#global:ADMIN"), - hasEntry("granteeUserName", "superuser-fran@hostsharing.net") + hasEntry("granteeSubjectName", "superuser-fran@hostsharing.net") ) )) .body("", hasItem( allOf( hasEntry("grantedByRoleIdName", "test_customer#xxx:ADMIN"), hasEntry("grantedRoleIdName", "test_package#xxx00:ADMIN"), - hasEntry("granteeUserName", "pac-admin-xxx00@xxx.example.com") + hasEntry("granteeSubjectName", "pac-admin-xxx00@xxx.example.com") ) )) .body("", hasItem( allOf( hasEntry("grantedByRoleIdName", "test_customer#zzz:ADMIN"), hasEntry("grantedRoleIdName", "test_package#zzz02:ADMIN"), - hasEntry("granteeUserName", "pac-admin-zzz02@zzz.example.com") + hasEntry("granteeSubjectName", "pac-admin-zzz02@zzz.example.com") ) )) .body("size()", greaterThanOrEqualTo(14)); @@ -125,7 +125,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { allOf( hasEntry("grantedByRoleIdName", "test_customer#yyy:ADMIN"), hasEntry("grantedRoleIdName", "test_package#yyy00:ADMIN"), - hasEntry("granteeUserName", "pac-admin-yyy00@yyy.example.com") + hasEntry("granteeSubjectName", "pac-admin-yyy00@yyy.example.com") ) )) .body("size()", is(1)); @@ -147,12 +147,12 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { allOf( hasEntry("grantedByRoleIdName", "test_customer#yyy:ADMIN"), hasEntry("grantedRoleIdName", "test_package#yyy00:ADMIN"), - hasEntry("granteeUserName", "pac-admin-yyy00@yyy.example.com") + hasEntry("granteeSubjectName", "pac-admin-yyy00@yyy.example.com") ) )) .body("[0].grantedByRoleIdName", is("test_customer#yyy:ADMIN")) .body("[0].grantedRoleIdName", is("test_package#yyy00:ADMIN")) - .body("[0].granteeUserName", is("pac-admin-yyy00@yyy.example.com")); + .body("[0].granteeSubjectName", is("pac-admin-yyy00@yyy.example.com")); // @formatter:on } } @@ -164,7 +164,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { void customerAdmin_withAssumedPacketAdminRole_canReadPacketAdminsGrantById() { // given final var givencurrentSubjectAsPackageAdmin = new Subject("customer-admin@xxx.example.com"); - final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com"); + final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com"); final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN"); // when @@ -176,14 +176,14 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { .statusCode(200) .body("grantedByRoleIdName", is("test_customer#xxx:ADMIN")) .body("grantedRoleIdName", is("test_package#xxx00:ADMIN")) - .body("granteeUserName", is("pac-admin-xxx00@xxx.example.com")); + .body("granteeSubjectName", is("pac-admin-xxx00@xxx.example.com")); } @Test void packageAdmin_withoutAssumedRole_canReadItsOwnGrantById() { // given final var givencurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com"); - final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com"); + final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com"); final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN"); // when @@ -195,7 +195,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { .statusCode(200) .body("grantedByRoleIdName", is("test_customer#xxx:ADMIN")) .body("grantedRoleIdName", is("test_package#xxx00:ADMIN")) - .body("granteeUserName", is("pac-admin-xxx00@xxx.example.com")); + .body("granteeSubjectName", is("pac-admin-xxx00@xxx.example.com")); } @Test @@ -204,7 +204,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { final var givencurrentSubjectAsPackageAdmin = new Subject( "pac-admin-xxx00@xxx.example.com", "test_package#xxx00:ADMIN"); - final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com"); + final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com"); final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN"); // when @@ -216,7 +216,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { .statusCode(200) .body("grantedByRoleIdName", is("test_customer#xxx:ADMIN")) .body("grantedRoleIdName", is("test_package#xxx00:ADMIN")) - .body("granteeUserName", is("pac-admin-xxx00@xxx.example.com")); + .body("granteeSubjectName", is("pac-admin-xxx00@xxx.example.com")); } @Test @@ -226,7 +226,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { final var givencurrentSubjectAsPackageAdmin = new Subject( "pac-admin-xxx00@xxx.example.com", "test_package#xxx00:TENANT"); - final var givenGranteeUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com"); + final var givenGranteeUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com"); final var givenGrantedRole = getRbacRoleByName("test_package#xxx00:ADMIN"); final var grant = givencurrentSubjectAsPackageAdmin.getGrantById() .forGrantedRole(givenGrantedRole).toGranteeUser(givenGranteeUser); @@ -244,7 +244,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { void packageAdmin_canGrantOwnPackageAdminRole_toArbitraryUser() { // given - final var givenNewUser = createRBacUser(); + final var givenNewUser = createRbacSubject(); final var givenRoleToGrant = "test_package#xxx00:ADMIN"; final var givencurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant); final var givenOwnPackageAdminRole = @@ -261,7 +261,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { .body("grantedByRoleIdName", is("test_package#xxx00:ADMIN")) .body("assumed", is(true)) .body("grantedRoleIdName", is("test_package#xxx00:ADMIN")) - .body("granteeUserName", is(givenNewUser.getName())); + .body("granteeSubjectName", is(givenNewUser.getName())); assertThat(findAllGrantsOf(givencurrentSubjectAsPackageAdmin)) .extracting(RbacGrantEntity::toDisplay) .contains("{ grant role:" + givenOwnPackageAdminRole.getRoleName() + @@ -273,7 +273,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { void packageAdmin_canNotGrantAlienPackageAdminRole_toArbitraryUser() { // given - final var givenNewUser = createRBacUser(); + final var givenNewUser = createRbacSubject(); final var givenRoleToGrant = "test_package#xxx00:ADMIN"; final var givencurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant); final var givenAlienPackageAdminRole = getRbacRoleByName("test_package#yyy00:ADMIN"); @@ -289,7 +289,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { .body("message", containsString("Access to granted role")) .body("message", containsString("forbidden for test_package#xxx00:ADMIN")); assertThat(findAllGrantsOf(givencurrentSubjectAsPackageAdmin)) - .extracting(RbacGrantEntity::getGranteeUserName) + .extracting(RbacGrantEntity::getGranteeSubjectName) .doesNotContain(givenNewUser.getName()); } } @@ -302,7 +302,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { void packageAdmin_canRevokePackageAdminRole_grantedByPackageAdmin_fromArbitraryUser() { // given - final var givenArbitraryUser = createRBacUser(); + final var givenArbitraryUser = createRbacSubject(); final var givenRoleToGrant = "test_package#xxx00:ADMIN"; final var givenCurrentSubjectAsPackageAdmin = new Subject("pac-admin-xxx00@xxx.example.com", givenRoleToGrant); final var givenOwnPackageAdminRole = getRbacRoleByName("test_package#xxx00:ADMIN"); @@ -326,7 +326,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { // then revokeResponse.assertThat().statusCode(204); assertThat(findAllGrantsOf(givenCurrentSubjectAsPackageAdmin)) - .extracting(RbacGrantEntity::getGranteeUserName) + .extracting(RbacGrantEntity::getGranteeSubjectName) .doesNotContain(givenArbitraryUser.getName()); } } @@ -366,7 +366,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { private Subject grantingSubject = Subject.this; private final RbacRoleEntity grantedRole; private boolean assumed; - private RbacUserEntity granteeUser; + private RbacSubjectEntity granteeUser; public GrantFixture(final RbacRoleEntity roleToGrant) { this.grantedRole = roleToGrant; @@ -377,7 +377,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { return this; } - ValidatableResponse toUser(final RbacUserEntity granteeUser) { + ValidatableResponse toUser(final RbacSubjectEntity granteeUser) { this.granteeUser = granteeUser; return RestAssured // @formatter:ff @@ -407,13 +407,13 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { private Subject currentSubject = Subject.this; private final RbacRoleEntity grantedRole; private boolean assumed; - private RbacUserEntity granteeUser; + private RbacSubjectEntity granteeUser; public RevokeFixture(final RbacRoleEntity roleToGrant) { this.grantedRole = roleToGrant; } - ValidatableResponse fromUser(final RbacUserEntity granteeUser) { + ValidatableResponse fromUser(final RbacSubjectEntity granteeUser) { this.granteeUser = granteeUser; return RestAssured // @formatter:ff @@ -450,7 +450,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { return this; } - ValidatableResponse toGranteeUser(final RbacUserEntity granteeUser) { + ValidatableResponse toGranteeUser(final RbacSubjectEntity granteeUser) { return RestAssured // @formatter:ff .given() @@ -480,18 +480,18 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest { }).returnedValue(); } - RbacUserEntity createRBacUser() { + RbacSubjectEntity createRbacSubject() { return jpaAttempt.transacted(() -> { final String newUserName = "test-user-" + RandomStringUtils.randomAlphabetic(8) + "@example.com"; context(null); - return rbacUserRepository.create(new RbacUserEntity(UUID.randomUUID(), newUserName)); + return rbacSubjectRepository.create(new RbacSubjectEntity(UUID.randomUUID(), newUserName)); }).returnedValue(); } - RbacUserEntity findRbacUserByName(final String userName) { + RbacSubjectEntity findRbacSubjectByName(final String userName) { return jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net", null); - return rbacUserRepository.findByName(userName); + return rbacSubjectRepository.findByName(userName); }).assertNotNull().returnedValue(); } diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantRepositoryIntegrationTest.java index 59ca05df..7b5e42f2 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/rbacgrant/RbacGrantRepositoryIntegrationTest.java @@ -3,8 +3,8 @@ package net.hostsharing.hsadminng.rbac.rbacgrant; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.rbac.context.ContextBasedTest; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository; -import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserEntity; -import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository; +import net.hostsharing.hsadminng.rbac.subject.RbacSubjectEntity; +import net.hostsharing.hsadminng.rbac.subject.RbacSubjectRepository; import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -42,7 +42,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest { RawRbacGrantRepository rawRbacGrantRepository; @Autowired - RbacUserRepository rbacUserRepository; + RbacSubjectRepository rbacSubjectRepository; @Autowired RbacRoleRepository rbacRoleRepository; @@ -109,7 +109,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest { public void customerAdmin_canGrantOwnPackageAdminRole_toArbitraryUser() { // given context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN"); - final var givenArbitrarySubjectUuid = rbacUserRepository.findByName("pac-admin-zzz00@zzz.example.com").getUuid(); + final var givenArbitrarySubjectUuid = rbacSubjectRepository.findByName("pac-admin-zzz00@zzz.example.com").getUuid(); final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName("test_package#xxx00:ADMIN").getUuid(); // when @@ -133,7 +133,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest { @Transactional(propagation = Propagation.NEVER) public void packageAdmin_canNotGrantPackageOwnerRole() { // given - record Given(RbacUserEntity arbitraryUser, UUID packageOwnerRoleUuid) {} + record Given(RbacSubjectEntity arbitraryUser, UUID packageOwnerRoleUuid) {} final var given = jpaAttempt.transacted(() -> { // to find the uuids of we need to have access rights to these context("customer-admin@xxx.example.com", null); @@ -188,7 +188,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest { context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN"); assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull(); assertThat(rbacGrantRepository.findAll()) - .extracting(RbacGrantEntity::getGranteeUserName) + .extracting(RbacGrantEntity::getGranteeSubjectName) .doesNotContain("pac-admin-zzz00@zzz.example.com"); } @@ -209,7 +209,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest { assertThat(revokeAttempt.caughtExceptionsRootCause()).isNull(); context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN"); assertThat(rbacGrantRepository.findAll()) - .extracting(RbacGrantEntity::getGranteeUserName) + .extracting(RbacGrantEntity::getGranteeSubjectName) .doesNotContain("pac-admin-zzz00@zzz.example.com"); } @@ -236,7 +236,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest { private RbacGrantEntity create(GrantBuilder with) { context(with.byUserName, with.assumedRole); - final var givenArbitrarySubjectUuid = rbacUserRepository.findByName(with.granteeUserName).getUuid(); + final var givenArbitrarySubjectUuid = rbacSubjectRepository.findByName(with.granteeSubjectName).getUuid(); final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName(with.grantedRole).getUuid(); final var grant = RbacGrantEntity.builder() @@ -251,7 +251,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest { assertThat(rawRbacGrantRepository.findAll()) .extracting(RawRbacGrantEntity::toDisplay) .contains("{ grant role:%s to user:%s by %s and assume }".formatted( - with.grantedRole, with.granteeUserName, with.assumedRole + with.grantedRole, with.granteeSubjectName, with.assumedRole )); return grant; @@ -266,7 +266,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest { String byUserName; String assumedRole = ""; String grantedRole; - String granteeUserName; + String granteeSubjectName; GrantBuilder byUser(final String userName) { byUserName = userName; @@ -284,28 +284,28 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest { } GrantBuilder toUser(final String toUser) { - this.granteeUserName = toUser; + this.granteeSubjectName = toUser; return this; } } } - private RbacUserEntity createNewUserTransacted() { + private RbacSubjectEntity createNewUserTransacted() { return jpaAttempt.transacted(() -> { final var newUserName = "test-user-" + System.currentTimeMillis() + "@example.com"; context(null); - return rbacUserRepository.create(new RbacUserEntity(null, newUserName)); + return rbacSubjectRepository.create(new RbacSubjectEntity(null, newUserName)); }).assumeSuccessful().returnedValue(); } - private RbacUserEntity createNewUser() { - return rbacUserRepository.create( - new RbacUserEntity(null, "test-user-" + System.currentTimeMillis() + "@example.com")); + private RbacSubjectEntity createNewUser() { + return rbacSubjectRepository.create( + new RbacSubjectEntity(null, "test-user-" + System.currentTimeMillis() + "@example.com")); } void exactlyTheseRbacGrantsAreReturned(final List actualResult, final String... expectedGrant) { assertThat(actualResult) - .filteredOn(g -> !g.getGranteeUserName().startsWith("test-user-")) // ignore test-users created by other tests + .filteredOn(g -> !g.getGranteeSubjectName().startsWith("test-user-")) // ignore test-users created by other tests .extracting(RbacGrantEntity::toDisplay) .containsExactlyInAnyOrder(expectedGrant); } diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerAcceptanceTest.java index 2b710bfb..5492d6d1 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/rbacrole/RbacRoleControllerAcceptanceTest.java @@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.rbac.rbacrole; import io.restassured.RestAssured; import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.context.Context; -import net.hostsharing.hsadminng.rbac.rbacuser.RbacUserRepository; +import net.hostsharing.hsadminng.rbac.subject.RbacSubjectRepository; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -24,7 +24,7 @@ class RbacRoleControllerAcceptanceTest { Context context; @Autowired - RbacUserRepository rbacUserRepository; + RbacSubjectRepository rbacSubjectRepository; @Autowired RbacRoleRepository rbacRoleRepository; diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/TestRbacUser.java b/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/TestRbacUser.java deleted file mode 100644 index bd096c9e..00000000 --- a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/TestRbacUser.java +++ /dev/null @@ -1,14 +0,0 @@ -package net.hostsharing.hsadminng.rbac.rbacuser; - - -import static java.util.UUID.randomUUID; - -public class TestRbacUser { - - static final RbacUserEntity userxxx = rbacRole("customer-admin@xxx.example.com"); - static final RbacUserEntity userBbb = rbacRole("customer-admin@bbb.example.com"); - - static public RbacUserEntity rbacRole(final String userName) { - return new RbacUserEntity(randomUUID(), userName); - } -} diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerAcceptanceTest.java similarity index 82% rename from src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerAcceptanceTest.java rename to src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerAcceptanceTest.java index e4c4cdaa..e62d39c4 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerAcceptanceTest.java @@ -1,4 +1,4 @@ -package net.hostsharing.hsadminng.rbac.rbacuser; +package net.hostsharing.hsadminng.rbac.subject; import io.restassured.RestAssured; import io.restassured.http.ContentType; @@ -22,7 +22,7 @@ import static org.hamcrest.Matchers.*; classes = { HsadminNgApplication.class, JpaAttempt.class } ) @Transactional -class RbacUserControllerAcceptanceTest { +class RbacSubjectControllerAcceptanceTest { @LocalServerPort private Integer port; @@ -34,10 +34,10 @@ class RbacUserControllerAcceptanceTest { Context context; @Autowired - RbacUserRepository rbacUserRepository; + RbacSubjectRepository rbacSubjectRepository; @Nested - class CreateRbacUser { + class CreateRbacSubject { @Test void anybody_canCreateANewUser() { @@ -53,7 +53,7 @@ class RbacUserControllerAcceptanceTest { """) .port(port) .when() - .post("http://localhost/api/rbac/users") + .post("http://localhost/api/rbac/subjects") .then().assertThat() .statusCode(201) .contentType(ContentType.JSON) @@ -66,17 +66,17 @@ class RbacUserControllerAcceptanceTest { final var newSubjectUuid = UUID.fromString( location.substring(location.lastIndexOf('/') + 1)); context.define("new-user@example.com"); - assertThat(rbacUserRepository.findByUuid(newSubjectUuid)) - .extracting(RbacUserEntity::getName).isEqualTo("new-user@example.com"); + assertThat(rbacSubjectRepository.findByUuid(newSubjectUuid)) + .extracting(RbacSubjectEntity::getName).isEqualTo("new-user@example.com"); } } @Nested - class GetRbacUser { + class GetRbacSubject { @Test void globalAdmin_withoutAssumedRole_canGetArbitraryUser() { - final var givenUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com"); + final var givenUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com"); // @formatter:off RestAssured @@ -84,7 +84,7 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "superuser-alex@hostsharing.net") .port(port) .when() - .get("http://localhost/api/rbac/users/" + givenUser.getUuid()) + .get("http://localhost/api/rbac/subjects/" + givenUser.getUuid()) .then().log().body().assertThat() .statusCode(200) .contentType("application/json") @@ -94,7 +94,7 @@ class RbacUserControllerAcceptanceTest { @Test void globalAdmin_withAssumedCustomerAdminRole_canGetUserWithinInItsRealm() { - final var givenUser = findRbacUserByName("pac-admin-yyy00@yyy.example.com"); + final var givenUser = findRbacSubjectByName("pac-admin-yyy00@yyy.example.com"); // @formatter:off RestAssured @@ -103,7 +103,7 @@ class RbacUserControllerAcceptanceTest { .header("assumed-roles", "test_customer#yyy:ADMIN") .port(port) .when() - .get("http://localhost/api/rbac/users/" + givenUser.getUuid()) + .get("http://localhost/api/rbac/subjects/" + givenUser.getUuid()) .then().log().body().assertThat() .statusCode(200) .contentType("application/json") @@ -113,7 +113,7 @@ class RbacUserControllerAcceptanceTest { @Test void customerAdmin_withoutAssumedRole_canGetUserWithinInItsRealm() { - final var givenUser = findRbacUserByName("pac-admin-yyy00@yyy.example.com"); + final var givenUser = findRbacSubjectByName("pac-admin-yyy00@yyy.example.com"); // @formatter:off RestAssured @@ -121,7 +121,7 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "customer-admin@yyy.example.com") .port(port) .when() - .get("http://localhost/api/rbac/users/" + givenUser.getUuid()) + .get("http://localhost/api/rbac/subjects/" + givenUser.getUuid()) .then().log().body().assertThat() .statusCode(200) .contentType("application/json") @@ -131,7 +131,7 @@ class RbacUserControllerAcceptanceTest { @Test void customerAdmin_withoutAssumedRole_canNotGetUserOutsideOfItsRealm() { - final var givenUser = findRbacUserByName("pac-admin-yyy00@yyy.example.com"); + final var givenUser = findRbacSubjectByName("pac-admin-yyy00@yyy.example.com"); // @formatter:off RestAssured @@ -139,7 +139,7 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "customer-admin@xxx.example.com") .port(port) .when() - .get("http://localhost/api/rbac/users/" + givenUser.getUuid()) + .get("http://localhost/api/rbac/subjects/" + givenUser.getUuid()) .then().log().body().assertThat() .statusCode(404); // @formatter:on @@ -147,7 +147,7 @@ class RbacUserControllerAcceptanceTest { } @Nested - class ListRbacUsers { + class ListRbacSubjects { @Test void globalAdmin_withoutAssumedRole_canViewAllUsers() { @@ -158,7 +158,7 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "superuser-alex@hostsharing.net") .port(port) .when() - .get("http://localhost/api/rbac/users") + .get("http://localhost/api/rbac/subjects") .then().log().body().assertThat() .statusCode(200) .contentType("application/json") @@ -183,7 +183,7 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "superuser-alex@hostsharing.net") .port(port) .when() - .get("http://localhost/api/rbac/users?name=pac-admin-zzz0") + .get("http://localhost/api/rbac/subjects?name=pac-admin-zzz0") .then().log().body().assertThat() .statusCode(200) .contentType("application/json") @@ -204,7 +204,7 @@ class RbacUserControllerAcceptanceTest { .header("assumed-roles", "test_customer#yyy:ADMIN") .port(port) .when() - .get("http://localhost/api/rbac/users") + .get("http://localhost/api/rbac/subjects") .then().assertThat() .statusCode(200) .contentType("application/json") @@ -225,7 +225,7 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "customer-admin@yyy.example.com") .port(port) .when() - .get("http://localhost/api/rbac/users") + .get("http://localhost/api/rbac/subjects") .then().assertThat() .statusCode(200) .contentType("application/json") @@ -246,7 +246,7 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "pac-admin-xxx01@xxx.example.com") .port(port) .when() - .get("http://localhost/api/rbac/users") + .get("http://localhost/api/rbac/subjects") .then().assertThat() .statusCode(200) .contentType("application/json") @@ -257,11 +257,11 @@ class RbacUserControllerAcceptanceTest { } @Nested - class ListRbacUserPermissions { + class ListRbacSubjectPermissions { @Test void globalAdmin_withoutAssumedRole_canViewArbitraryUsersPermissions() { - final var givenUser = findRbacUserByName("pac-admin-yyy00@yyy.example.com"); + final var givenUser = findRbacSubjectByName("pac-admin-yyy00@yyy.example.com"); // @formatter:off RestAssured @@ -269,7 +269,7 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "superuser-alex@hostsharing.net") .port(port) .when() - .get("http://localhost/api/rbac/users/" + givenUser.getUuid() + "/permissions") + .get("http://localhost/api/rbac/subjects/" + givenUser.getUuid() + "/permissions") .then().log().body().assertThat() .statusCode(200) .contentType("application/json") @@ -290,7 +290,7 @@ class RbacUserControllerAcceptanceTest { @Test void globalAdmin_withAssumedCustomerAdminRole_canViewArbitraryUsersPermissions() { - final var givenUser = findRbacUserByName("pac-admin-yyy00@yyy.example.com"); + final var givenUser = findRbacSubjectByName("pac-admin-yyy00@yyy.example.com"); // @formatter:off RestAssured @@ -299,7 +299,7 @@ class RbacUserControllerAcceptanceTest { .header("assumed-roles", "test_customer#yyy:ADMIN") .port(port) .when() - .get("http://localhost/api/rbac/users/" + givenUser.getUuid() + "/permissions") + .get("http://localhost/api/rbac/subjects/" + givenUser.getUuid() + "/permissions") .then().log().body().assertThat() .statusCode(200) .contentType("application/json") @@ -320,7 +320,7 @@ class RbacUserControllerAcceptanceTest { @Test void packageAdmin_withoutAssumedRole_canViewPermissionsOfUsersInItsRealm() { - final var givenUser = findRbacUserByName("pac-admin-yyy00@yyy.example.com"); + final var givenUser = findRbacSubjectByName("pac-admin-yyy00@yyy.example.com"); // @formatter:off RestAssured @@ -328,7 +328,7 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "pac-admin-yyy00@yyy.example.com") .port(port) .when() - .get("http://localhost/api/rbac/users/" + givenUser.getUuid() + "/permissions") + .get("http://localhost/api/rbac/subjects/" + givenUser.getUuid() + "/permissions") .then().log().body().assertThat() .statusCode(200) .contentType("application/json") @@ -349,7 +349,7 @@ class RbacUserControllerAcceptanceTest { @Test void packageAdmin_canViewPermissionsOfUsersOutsideOfItsRealm() { - final var givenUser = findRbacUserByName("pac-admin-xxx00@xxx.example.com"); + final var givenUser = findRbacSubjectByName("pac-admin-xxx00@xxx.example.com"); // @formatter:off RestAssured @@ -357,7 +357,7 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "pac-admin-yyy00@yyy.example.com") .port(port) .when() - .get("http://localhost/api/rbac/users/" + givenUser.getUuid() + "/permissions") + .get("http://localhost/api/rbac/subjects/" + givenUser.getUuid() + "/permissions") .then().log().body().assertThat() .statusCode(200) .contentType("application/json") @@ -367,7 +367,7 @@ class RbacUserControllerAcceptanceTest { } @Nested - class DeleteRbacUser { + class DeleteRbacSubject { @Test void anybody_canDeleteTheirOwnUser() { @@ -381,13 +381,13 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", givenUser.getName()) .port(port) .when() - .delete("http://localhost/api/rbac/users/" + givenUser.getUuid()) + .delete("http://localhost/api/rbac/subjects/" + givenUser.getUuid()) .then().log().all().assertThat() .statusCode(204); // @formatter:on // finally, the user is actually deleted - assertThat(rbacUserRepository.findByName(givenUser.getName())).isNull(); + assertThat(rbacSubjectRepository.findByName(givenUser.getName())).isNull(); } @Test @@ -402,14 +402,14 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "customer-admin@xxx.example.com") .port(port) .when() - .delete("http://localhost/api/rbac/users/" + givenUser.getUuid()) + .delete("http://localhost/api/rbac/subjects/" + givenUser.getUuid()) .then().log().all().assertThat() // that user cannot even see other users, thus the system won't even try to delete .statusCode(204); // @formatter:on // finally, the user is still there - assertThat(rbacUserRepository.findByName(givenUser.getName())).isNotNull(); + assertThat(rbacSubjectRepository.findByName(givenUser.getName())).isNotNull(); } @Test @@ -424,30 +424,30 @@ class RbacUserControllerAcceptanceTest { .header("current-subject", "superuser-alex@hostsharing.net") .port(port) .when() - .delete("http://localhost/api/rbac/users/" + givenUser.getUuid()) + .delete("http://localhost/api/rbac/subjects/" + givenUser.getUuid()) .then().log().all().assertThat() .statusCode(204); // @formatter:on // finally, the user is actually deleted - assertThat(rbacUserRepository.findByName(givenUser.getName())).isNull(); + assertThat(rbacSubjectRepository.findByName(givenUser.getName())).isNull(); } } - RbacUserEntity findRbacUserByName(final String userName) { + RbacSubjectEntity findRbacSubjectByName(final String userName) { return jpaAttempt.transacted(() -> { context.define("superuser-alex@hostsharing.net"); - return rbacUserRepository.findByName(userName); + return rbacSubjectRepository.findByName(userName); }).returnedValue(); } - RbacUserEntity givenANewUser() { + RbacSubjectEntity givenANewUser() { final var givenUserName = "test-user-" + System.currentTimeMillis() + "@example.com"; final var givenUser = jpaAttempt.transacted(() -> { context.define(null); - return rbacUserRepository.create(new RbacUserEntity(UUID.randomUUID(), givenUserName)); + return rbacSubjectRepository.create(new RbacSubjectEntity(UUID.randomUUID(), givenUserName)); }).assumeSuccessful().returnedValue(); - assertThat(rbacUserRepository.findByName(givenUser.getName())).isNotNull(); + assertThat(rbacSubjectRepository.findByName(givenUser.getName())).isNotNull(); return givenUser; } diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerRestTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerRestTest.java similarity index 83% rename from src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerRestTest.java rename to src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerRestTest.java index 6e59f38a..d23a8394 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserControllerRestTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectControllerRestTest.java @@ -1,4 +1,4 @@ -package net.hostsharing.hsadminng.rbac.rbacuser; +package net.hostsharing.hsadminng.rbac.subject; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.mapper.Mapper; @@ -30,10 +30,10 @@ import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@WebMvcTest(RbacUserController.class) +@WebMvcTest(RbacSubjectController.class) @Import(Mapper.class) @RunWith(SpringRunner.class) -class RbacUserControllerRestTest { +class RbacSubjectControllerRestTest { @Autowired MockMvc mockMvc; @@ -42,7 +42,7 @@ class RbacUserControllerRestTest { Context contextMock; @MockBean - RbacUserRepository rbacUserRepository; + RbacSubjectRepository rbacSubjectRepository; @Mock EntityManager em; @@ -59,13 +59,13 @@ class RbacUserControllerRestTest { } @Test - void createUserUsesGivenUuid() throws Exception { + void createSubjectUsesGivenUuid() throws Exception { // given final var givenUuid = UUID.randomUUID(); // when mockMvc.perform(MockMvcRequestBuilders - .post("/api/rbac/users") + .post("/api/rbac/subjects") .contentType(MediaType.APPLICATION_JSON) .content(""" { @@ -79,14 +79,14 @@ class RbacUserControllerRestTest { .andExpect(jsonPath("uuid", is(givenUuid.toString()))); // then - verify(rbacUserRepository).create(argThat(entity -> entity.getUuid().equals(givenUuid))); + verify(rbacSubjectRepository).create(argThat(entity -> entity.getUuid().equals(givenUuid))); } @Test - void createUserGeneratesRandomUuidIfNotGiven() throws Exception { + void createSubjectGeneratesRandomUuidIfNotGiven() throws Exception { // when mockMvc.perform(MockMvcRequestBuilders - .post("/api/rbac/users") + .post("/api/rbac/subjects") .contentType(MediaType.APPLICATION_JSON) .content("{}") .accept(MediaType.APPLICATION_JSON)) @@ -96,6 +96,6 @@ class RbacUserControllerRestTest { .andExpect(jsonPath("uuid", isUuidValid())); // then - verify(rbacUserRepository).create(argThat(entity -> entity.getUuid() != null)); + verify(rbacSubjectRepository).create(argThat(entity -> entity.getUuid() != null)); } } diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectEntityUnitTest.java similarity index 91% rename from src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntityUnitTest.java rename to src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectEntityUnitTest.java index b1cff68e..44dde522 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectEntityUnitTest.java @@ -1,4 +1,4 @@ -package net.hostsharing.hsadminng.rbac.rbacuser; +package net.hostsharing.hsadminng.rbac.subject; import org.junit.jupiter.api.Test; @@ -9,9 +9,9 @@ import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -class RbacUserEntityUnitTest { +class RbacSubjectEntityUnitTest { - RbacUserEntity givenUser = new RbacUserEntity(UUID.randomUUID(), "test@example.org"); + RbacSubjectEntity givenUser = new RbacSubjectEntity(UUID.randomUUID(), "test@example.org"); @Test void generatedAccessCodeMatchesDefinedPattern() { diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectRepositoryIntegrationTest.java similarity index 82% rename from src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserRepositoryIntegrationTest.java rename to src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectRepositoryIntegrationTest.java index d19c7454..841acfdf 100644 --- a/src/test/java/net/hostsharing/hsadminng/rbac/rbacuser/RbacUserRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/rbac/subject/RbacSubjectRepositoryIntegrationTest.java @@ -1,4 +1,4 @@ -package net.hostsharing.hsadminng.rbac.rbacuser; +package net.hostsharing.hsadminng.rbac.subject; import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.rbac.context.ContextBasedTest; @@ -26,10 +26,10 @@ import static org.assertj.core.api.Assertions.assertThat; @DataJpaTest @Import( { Context.class, JpaAttempt.class }) -class RbacUserRepositoryIntegrationTest extends ContextBasedTest { +class RbacSubjectRepositoryIntegrationTest extends ContextBasedTest { @Autowired - RbacUserRepository rbacUserRepository; + RbacSubjectRepository rbacSubjectRepository; @Autowired JpaAttempt jpaAttempt; @@ -41,7 +41,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { HttpServletRequest request; @Nested - class CreateUser { + class CreateSubject { @Test @Transactional(propagation = Propagation.NEVER) @@ -54,35 +54,35 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { // when: final var result = jpaAttempt.transacted(() -> { context(null); - return rbacUserRepository.create(new RbacUserEntity(givenUuid, newUserName)); + return rbacSubjectRepository.create(new RbacSubjectEntity(givenUuid, newUserName)); }); // then: assertThat(result.wasSuccessful()).isTrue(); assertThat(result.returnedValue()).isNotNull() - .extracting(RbacUserEntity::getUuid).isEqualTo(givenUuid); - assertThat(rbacUserRepository.findByName(result.returnedValue().getName())).isNotNull(); + .extracting(RbacSubjectEntity::getUuid).isEqualTo(givenUuid); + assertThat(rbacSubjectRepository.findByName(result.returnedValue().getName())).isNotNull(); } } @Nested - class DeleteUser { + class DeleteSubject { @Test @Transactional(propagation = Propagation.NEVER) public void anyoneCanDeleteTheirOwnUser() { // given - final RbacUserEntity givenUser = givenANewUser(); + final RbacSubjectEntity givenUser = givenANewSubject(); // when final var result = jpaAttempt.transacted(() -> { context(givenUser.getName()); - rbacUserRepository.deleteByUuid(givenUser.getUuid()); + rbacSubjectRepository.deleteByUuid(givenUser.getUuid()); }); // then the user is deleted result.assertSuccessful(); - assertThat(rbacUserRepository.findByName(givenUser.getName())).isNull(); + assertThat(rbacSubjectRepository.findByName(givenUser.getName())).isNull(); } } @@ -102,27 +102,27 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { ); @Test - public void globalAdmin_withoutAssumedRole_canViewAllRbacUsers() { + public void globalAdmin_withoutAssumedRole_canViewAllRbacSubjects() { // given context("superuser-alex@hostsharing.net"); // when - final var result = rbacUserRepository.findByOptionalNameLike(null); + final var result = rbacSubjectRepository.findByOptionalNameLike(null); // then - allTheseRbacUsersAreReturned(result, ALL_TEST_DATA_USERS); + allTheseRbacSubjectsAreReturned(result, ALL_TEST_DATA_USERS); } @Test - public void globalAdmin_withAssumedglobalAdminRole_canViewAllRbacUsers() { + public void globalAdmin_withAssumedglobalAdminRole_canViewAllRbacSubjects() { given: context("superuser-alex@hostsharing.net", "global#global:ADMIN"); // when - final var result = rbacUserRepository.findByOptionalNameLike(null); + final var result = rbacSubjectRepository.findByOptionalNameLike(null); then: - allTheseRbacUsersAreReturned(result, ALL_TEST_DATA_USERS); + allTheseRbacSubjectsAreReturned(result, ALL_TEST_DATA_USERS); } @Test @@ -131,10 +131,10 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { context("superuser-alex@hostsharing.net", "test_customer#xxx:ADMIN"); // when - final var result = rbacUserRepository.findByOptionalNameLike(null); + final var result = rbacSubjectRepository.findByOptionalNameLike(null); then: - exactlyTheseRbacUsersAreReturned( + exactlyTheseRbacSubjectsAreReturned( result, "customer-admin@xxx.example.com", "pac-admin-xxx00@xxx.example.com", "pac-admin-xxx01@xxx.example.com", "pac-admin-xxx02@xxx.example.com" @@ -147,10 +147,10 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { context("customer-admin@xxx.example.com"); // when: - final var result = rbacUserRepository.findByOptionalNameLike(null); + final var result = rbacSubjectRepository.findByOptionalNameLike(null); // then: - exactlyTheseRbacUsersAreReturned( + exactlyTheseRbacSubjectsAreReturned( result, "customer-admin@xxx.example.com", "pac-admin-xxx00@xxx.example.com", "pac-admin-xxx01@xxx.example.com", "pac-admin-xxx02@xxx.example.com" @@ -161,24 +161,24 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { public void customerAdmin_withAssumedOwnedPackageAdminRole_canViewOnlyUsersHavingRolesInThatPackage() { context("customer-admin@xxx.example.com", "test_package#xxx00:ADMIN"); - final var result = rbacUserRepository.findByOptionalNameLike(null); + final var result = rbacSubjectRepository.findByOptionalNameLike(null); - exactlyTheseRbacUsersAreReturned(result, "pac-admin-xxx00@xxx.example.com"); + exactlyTheseRbacSubjectsAreReturned(result, "pac-admin-xxx00@xxx.example.com"); } @Test public void packageAdmin_withoutAssumedRole_canViewOnlyUsersHavingRolesInThatPackage() { context("pac-admin-xxx00@xxx.example.com"); - final var result = rbacUserRepository.findByOptionalNameLike(null); + final var result = rbacSubjectRepository.findByOptionalNameLike(null); - exactlyTheseRbacUsersAreReturned(result, "pac-admin-xxx00@xxx.example.com"); + exactlyTheseRbacSubjectsAreReturned(result, "pac-admin-xxx00@xxx.example.com"); } } @Nested - class ListUserPermissions { + class ListSubjectPermissions { private static final String[] ALL_USER_PERMISSIONS = Array.of( // @formatter:off @@ -232,9 +232,9 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { context("superuser-alex@hostsharing.net"); // when - final var result = rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid("superuser-fran@hostsharing.net")) + final var result = rbacSubjectRepository.findPermissionsOfUserByUuid(subjectUuid("superuser-fran@hostsharing.net")) .stream().filter(p -> p.getObjectTable().contains("test_")) - .sorted(comparing(RbacUserPermission::toString)).toList(); + .sorted(comparing(RbacSubjectPermission::toString)).toList(); // then allTheseRbacPermissionsAreReturned(result, ALL_USER_PERMISSIONS); @@ -246,7 +246,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { context("customer-admin@xxx.example.com"); // when - final var result = rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid("customer-admin@xxx.example.com")); + final var result = rbacSubjectRepository.findPermissionsOfUserByUuid(subjectUuid("customer-admin@xxx.example.com")); // then allTheseRbacPermissionsAreReturned( @@ -290,7 +290,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { // when final var result = attempt(em, () -> - rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid) + rbacSubjectRepository.findPermissionsOfUserByUuid(subjectUuid) ); // then @@ -306,7 +306,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { context("customer-admin@xxx.example.com"); // when - final var result = rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid("pac-admin-xxx00@xxx.example.com")); + final var result = rbacSubjectRepository.findPermissionsOfUserByUuid(subjectUuid("pac-admin-xxx00@xxx.example.com")); // then allTheseRbacPermissionsAreReturned( @@ -342,7 +342,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { context("customer-admin@xxx.example.com"); // when - final var result = rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid("pac-admin-yyy00@yyy.example.com")); + final var result = rbacSubjectRepository.findPermissionsOfUserByUuid(subjectUuid("pac-admin-yyy00@yyy.example.com")); // then noRbacPermissionsAreReturned(result); @@ -354,7 +354,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { context("pac-admin-xxx00@xxx.example.com"); // when - final var result = rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid("pac-admin-xxx00@xxx.example.com")); + final var result = rbacSubjectRepository.findPermissionsOfUserByUuid(subjectUuid("pac-admin-xxx00@xxx.example.com")); // then allTheseRbacPermissionsAreReturned( @@ -386,50 +386,42 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { } UUID subjectUuid(final String userName) { - return rbacUserRepository.findByName(userName).getUuid(); + return rbacSubjectRepository.findByName(userName).getUuid(); } - RbacUserEntity givenANewUser() { + RbacSubjectEntity givenANewSubject() { final var givenUserName = "test-user-" + System.currentTimeMillis() + "@example.com"; final var givenUser = jpaAttempt.transacted(() -> { context(null); - return rbacUserRepository.create(new RbacUserEntity(UUID.randomUUID(), givenUserName)); + return rbacSubjectRepository.create(new RbacSubjectEntity(UUID.randomUUID(), givenUserName)); }).assumeSuccessful().returnedValue(); - assertThat(rbacUserRepository.findByName(givenUser.getName())).isNotNull(); + assertThat(rbacSubjectRepository.findByName(givenUser.getName())).isNotNull(); return givenUser; } - void exactlyTheseRbacUsersAreReturned(final List actualResult, final String... expectedUserNames) { + void exactlyTheseRbacSubjectsAreReturned(final List actualResult, final String... expectedUserNames) { assertThat(actualResult) - .extracting(RbacUserEntity::getName) + .extracting(RbacSubjectEntity::getName) .filteredOn(n -> !n.startsWith("test-user")) .containsExactlyInAnyOrder(expectedUserNames); } - void allTheseRbacUsersAreReturned(final List actualResult, final String... expectedUserNames) { + void allTheseRbacSubjectsAreReturned(final List actualResult, final String... expectedUserNames) { assertThat(actualResult) - .extracting(RbacUserEntity::getName) + .extracting(RbacSubjectEntity::getName) .filteredOn(n -> !n.startsWith("test-user")) .contains(expectedUserNames); } void noRbacPermissionsAreReturned( - final List actualResult) { + final List actualResult) { assertThat(actualResult) .extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp()) .containsExactlyInAnyOrder(); } - void exactlyTheseRbacPermissionsAreReturned( - final List actualResult, - final String... expectedRoleNames) { - assertThat(actualResult) - .extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp()) - .containsExactlyInAnyOrder(expectedRoleNames); - } - void allTheseRbacPermissionsAreReturned( - final List actualResult, + final List actualResult, final String... expectedRoleNames) { assertThat(actualResult) .extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp() @@ -438,7 +430,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest { } void noneOfTheseRbacPermissionsAreReturned( - final List actualResult, + final List actualResult, final String... unexpectedRoleNames) { assertThat(actualResult) .extracting(p -> p.getRoleName() + " -> " + p.getObjectTable() + "#" + p.getObjectIdName() + ": " + p.getOp()) diff --git a/src/test/java/net/hostsharing/hsadminng/rbac/subject/TestRbacSubject.java b/src/test/java/net/hostsharing/hsadminng/rbac/subject/TestRbacSubject.java new file mode 100644 index 00000000..05388f0c --- /dev/null +++ b/src/test/java/net/hostsharing/hsadminng/rbac/subject/TestRbacSubject.java @@ -0,0 +1,14 @@ +package net.hostsharing.hsadminng.rbac.subject; + + +import static java.util.UUID.randomUUID; + +public class TestRbacSubject { + + static final RbacSubjectEntity userxxx = rbacRole("customer-admin@xxx.example.com"); + static final RbacSubjectEntity userBbb = rbacRole("customer-admin@bbb.example.com"); + + static public RbacSubjectEntity rbacRole(final String userName) { + return new RbacSubjectEntity(randomUUID(), userName); + } +}