introduce separate database-schemas base+rbac #103
@ -467,7 +467,7 @@ public class RbacView {
|
||||
return new RbacExampleRole(entityAlias, role);
|
||||
}
|
||||
|
||||
private RbacGrantDefinition grantRoleToUser(final RbacRoleDefinition roleDefinition, final RbacUserReference user) {
|
||||
private RbacGrantDefinition grantRoleToSubject(final RbacRoleDefinition roleDefinition, final RbacUserReference user) {
|
||||
return findOrCreateGrantDef(roleDefinition, user).toCreate();
|
||||
}
|
||||
|
||||
@ -771,7 +771,7 @@ public class RbacView {
|
||||
* The grant definition for further chained calls.
|
||||
*/
|
||||
public RbacGrantDefinition owningUser(final RbacUserReference.UserRole userRole) {
|
||||
return grantRoleToUser(this, findUserRef(userRole));
|
||||
return grantRoleToSubject(this, findUserRef(userRole));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -312,7 +312,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
case ROLE_TO_ROLE -> "call revokeRoleFromRole(${subRoleRef}, ${superRoleRef});"
|
||||
.replace("${subRoleRef}", roleRef(OLD, grantDef.getSubRoleDef()))
|
||||
.replace("${superRoleRef}", roleRef(OLD, grantDef.getSuperRoleDef()));
|
||||
case PERM_TO_ROLE -> "call revokePermissionFromRole(${permRef}, ${superRoleRef});"
|
||||
case PERM_TO_ROLE -> "call rbac.revokePermissionFromRole(${permRef}, ${superRoleRef});"
|
||||
.replace("${permRef}", getPerm(OLD, grantDef.getPermDef()))
|
||||
.replace("${superRoleRef}", roleRef(OLD, grantDef.getSuperRoleDef()));
|
||||
};
|
||||
@ -415,7 +415,7 @@ class RolesGrantsAndPermissionsGenerator {
|
||||
.map(this::toPlPgSqlReference)
|
||||
.toList();
|
||||
plPgSql.indented(() ->
|
||||
plPgSql.writeLn("userUuids => array[" + joinArrayElements(arrayElements, 2) + "],\n"));
|
||||
plPgSql.writeLn("subjectUuids => array[" + joinArrayElements(arrayElements, 2) + "],\n"));
|
||||
rbacGrants.removeAll(grantsToUsers);
|
||||
}
|
||||
}
|
||||
|
@ -36,11 +36,11 @@ public class RbacGrantController implements RbacGrantsApi {
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID grantedRoleUuid,
|
||||
final UUID granteeUserUuid) {
|
||||
final UUID granteeSubjectUuid) {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var id = new RbacGrantId(granteeUserUuid, grantedRoleUuid);
|
||||
final var id = new RbacGrantId(granteeSubjectUuid, grantedRoleUuid);
|
||||
final var result = rbacGrantRepository.findById(id);
|
||||
if (result == null) {
|
||||
return ResponseEntity.notFound().build();
|
||||
@ -61,7 +61,7 @@ public class RbacGrantController implements RbacGrantsApi {
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<RbacGrantResource> grantRoleToUser(
|
||||
public ResponseEntity<RbacGrantResource> grantRoleToSubject(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final RbacGrantResource body) {
|
||||
@ -82,22 +82,22 @@ public class RbacGrantController implements RbacGrantsApi {
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public ResponseEntity<Void> revokeRoleFromUser(
|
||||
public ResponseEntity<Void> revokeRoleFromSubject(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID grantedRoleUuid,
|
||||
final UUID granteeUserUuid) {
|
||||
final UUID granteeSubjectUuid) {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
rbacGrantRepository.deleteByRbacGrantId(new RbacGrantId(granteeUserUuid, grantedRoleUuid));
|
||||
rbacGrantRepository.deleteByRbacGrantId(new RbacGrantId(granteeSubjectUuid, grantedRoleUuid));
|
||||
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
// TODO: implement an endpoint to create a Mermaid flowchart with all grants of a given user
|
||||
// TODO.feat: implement an endpoint to create a Mermaid flowchart with all grants of a given user
|
||||
// @GetMapping(
|
||||
// path = "/api/rbac/users/{userUuid}/grants",
|
||||
// path = "/api/rbac/users/{subjectUuid}/grants",
|
||||
// produces = {"text/vnd.mermaid"})
|
||||
// @Transactional(readOnly = true)
|
||||
// public ResponseEntity<String> allGrantsOfUserAsMermaid(
|
||||
|
@ -36,8 +36,8 @@ public class RbacGrantEntity {
|
||||
private String granteeUserName;
|
||||
|
||||
@Id
|
||||
@Column(name = "useruuid")
|
||||
private UUID granteeUserUuid;
|
||||
@Column(name = "subjectuuid")
|
||||
private UUID granteeSubjectUuid;
|
||||
|
||||
private boolean assumed;
|
||||
|
||||
@ -55,7 +55,7 @@ public class RbacGrantEntity {
|
||||
private RbacRoleType grantedRoleType;
|
||||
|
||||
RbacGrantId getRbacGrantId() {
|
||||
return new RbacGrantId(granteeUserUuid, grantedRoleUuid);
|
||||
return new RbacGrantId(granteeSubjectUuid, grantedRoleUuid);
|
||||
}
|
||||
|
||||
public String toDisplay() {
|
||||
|
@ -14,6 +14,6 @@ import java.util.UUID;
|
||||
@AllArgsConstructor
|
||||
public class RbacGrantId implements Serializable {
|
||||
|
||||
private UUID granteeUserUuid;
|
||||
private UUID granteeSubjectUuid;
|
||||
private UUID grantedRoleUuid;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ public interface RbacGrantRepository extends Repository<RbacGrantEntity, RbacGra
|
||||
@Query(value = """
|
||||
select g from RbacGrantEntity as g
|
||||
where g.grantedRoleUuid=:#{#rbacGrantId.grantedRoleUuid}
|
||||
and g.granteeUserUuid=:#{#rbacGrantId.granteeUserUuid}
|
||||
and g.granteeSubjectUuid=:#{#rbacGrantId.granteeSubjectUuid}
|
||||
""")
|
||||
RbacGrantEntity findById(RbacGrantId rbacGrantId);
|
||||
|
||||
@ -25,7 +25,7 @@ public interface RbacGrantRepository extends Repository<RbacGrantEntity, RbacGra
|
||||
@Query(value = """
|
||||
delete from RbacGrantEntity as g
|
||||
where g.grantedRoleUuid=:#{#rbacGrantId.grantedRoleUuid}
|
||||
and g.granteeUserUuid=:#{#rbacGrantId.granteeUserUuid}
|
||||
and g.granteeSubjectUuid=:#{#rbacGrantId.granteeSubjectUuid}
|
||||
""")
|
||||
void deleteByRbacGrantId(RbacGrantId rbacGrantId);
|
||||
}
|
||||
|
@ -51,11 +51,11 @@ public class RbacUserController implements RbacUsersApi {
|
||||
public ResponseEntity<Void> deleteUserByUuid(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID userUuid
|
||||
final UUID subjectUuid
|
||||
) {
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
rbacUserRepository.deleteByUuid(userUuid);
|
||||
rbacUserRepository.deleteByUuid(subjectUuid);
|
||||
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
@ -65,11 +65,11 @@ public class RbacUserController implements RbacUsersApi {
|
||||
public ResponseEntity<RbacUserResource> getUserById(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID userUuid) {
|
||||
final UUID subjectUuid) {
|
||||
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var result = rbacUserRepository.findByUuid(userUuid);
|
||||
final var result = rbacUserRepository.findByUuid(subjectUuid);
|
||||
if (result == null) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
@ -93,12 +93,12 @@ public class RbacUserController implements RbacUsersApi {
|
||||
public ResponseEntity<List<RbacUserPermissionResource>> listUserPermissions(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final UUID userUuid
|
||||
final UUID subjectUuid
|
||||
) {
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
return ResponseEntity.ok(mapper.mapList(
|
||||
rbacUserRepository.findPermissionsOfUserByUuid(userUuid),
|
||||
rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid),
|
||||
RbacUserPermissionResource.class));
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,8 @@ public interface RbacUserRepository extends Repository<RbacUserEntity, UUID> {
|
||||
|
||||
RbacUserEntity findByUuid(UUID uuid);
|
||||
|
||||
@Query(value = "select * from grantedPermissions(:userUuid)", nativeQuery = true)
|
||||
List<RbacUserPermission> findPermissionsOfUserByUuid(UUID userUuid);
|
||||
@Query(value = "select * from grantedPermissions(:subjectUuid)", nativeQuery = true)
|
||||
List<RbacUserPermission> findPermissionsOfUserByUuid(UUID subjectUuid);
|
||||
|
||||
/*
|
||||
Can't use save/saveAndFlush from SpringData because the uuid is not generated on the entity level,
|
||||
@ -42,5 +42,5 @@ public interface RbacUserRepository extends Repository<RbacUserEntity, UUID> {
|
||||
return rbacUserEntity;
|
||||
}
|
||||
|
||||
void deleteByUuid(UUID userUuid);
|
||||
void deleteByUuid(UUID subjectUuid);
|
||||
}
|
||||
|
@ -20,9 +20,9 @@ components:
|
||||
format: uuid
|
||||
granteeUserName:
|
||||
type: string
|
||||
granteeUserUuid:
|
||||
granteeSubjectUuid:
|
||||
type: string
|
||||
format: uuid
|
||||
required:
|
||||
- grantedRoleUuid
|
||||
- granteeUserUuid
|
||||
- granteeSubjectUuid
|
||||
|
@ -12,7 +12,7 @@ get:
|
||||
type: string
|
||||
format: uuid
|
||||
description: UUID of the granted role.
|
||||
- name: granteeUserUuid
|
||||
- name: granteeSubjectUuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
@ -36,7 +36,7 @@ get:
|
||||
delete:
|
||||
tags:
|
||||
- rbac-grants
|
||||
operationId: revokeRoleFromUser
|
||||
operationId: revokeRoleFromSubject
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
@ -47,7 +47,7 @@ delete:
|
||||
type: string
|
||||
format: uuid
|
||||
description: UUID of the granted role.
|
||||
- name: granteeUserUuid
|
||||
- name: granteeSubjectUuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
|
@ -18,7 +18,7 @@ get:
|
||||
post:
|
||||
tags:
|
||||
- rbac-grants
|
||||
operationId: grantRoleToUser
|
||||
operationId: grantRoleToSubject
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
|
@ -6,7 +6,7 @@ get:
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: userUuid
|
||||
- name: subjectUuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
|
@ -6,7 +6,7 @@ get:
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: userUuid
|
||||
- name: subjectUuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
@ -33,7 +33,7 @@ delete:
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: userUuid
|
||||
- name: subjectUuid
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
|
@ -11,10 +11,10 @@ paths:
|
||||
/api/rbac/users:
|
||||
$ref: 'rbac-users.yaml'
|
||||
|
||||
/api/rbac/users/{userUuid}/permissions:
|
||||
/api/rbac/users/{subjectUuid}/permissions:
|
||||
$ref: 'rbac-users-with-id-permissions.yaml'
|
||||
|
||||
/api/rbac/users/{userUuid}:
|
||||
/api/rbac/users/{subjectUuid}:
|
||||
$ref: 'rbac-users-with-uuid.yaml'
|
||||
|
||||
/api/rbac/roles:
|
||||
@ -23,6 +23,6 @@ paths:
|
||||
/api/rbac/grants:
|
||||
$ref: 'rbac-grants.yaml'
|
||||
|
||||
/api/rbac/grants/{grantedRoleUuid}/{granteeUserUuid}:
|
||||
/api/rbac/grants/{grantedRoleUuid}/{granteeSubjectUuid}:
|
||||
$ref: 'rbac-grants-with-id.yaml'
|
||||
|
||||
|
@ -672,7 +672,7 @@ begin
|
||||
end if;
|
||||
end; $$;
|
||||
|
||||
create or replace procedure revokePermissionFromRole(permissionId UUID, superRole RbacRoleDescriptor)
|
||||
create or replace procedure rbac.revokePermissionFromRole(permissionId UUID, superRole RbacRoleDescriptor)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
superRoleId uuid;
|
||||
|
@ -20,21 +20,21 @@ begin
|
||||
return currentSubjectOrAssumedRolesUuids[1];
|
||||
end; $$;
|
||||
|
||||
create or replace procedure grantRoleToUserUnchecked(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid, doAssume boolean = true)
|
||||
create or replace procedure rbac.grantRoleToUserUnchecked(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid, doAssume boolean = true)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
perform rbac.assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'RbacRole');
|
||||
perform rbac.assertReferenceType('roleId (descendant)', grantedRoleUuid, 'RbacRole');
|
||||
perform rbac.assertReferenceType('userId (ascendant)', userUuid, 'rbac.subject');
|
||||
perform rbac.assertReferenceType('subjectUuid (ascendant)', subjectUuid, 'rbac.subject');
|
||||
|
||||
insert
|
||||
into RbacGrants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed)
|
||||
values (grantedByRoleUuid, userUuid, grantedRoleUuid, doAssume)
|
||||
values (grantedByRoleUuid, subjectUuid, grantedRoleUuid, doAssume)
|
||||
-- TODO: check if grantedByRoleUuid+doAssume are the same, otherwise raise exception?
|
||||
on conflict do nothing; -- allow granting multiple times
|
||||
end; $$;
|
||||
|
||||
create or replace procedure grantRoleToUser(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid, doAssume boolean = true)
|
||||
create or replace procedure rbac.grantRoleToSubject(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid, doAssume boolean = true)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
grantedByRoleIdName text;
|
||||
@ -42,11 +42,11 @@ declare
|
||||
begin
|
||||
perform rbac.assertReferenceType('grantingRoleUuid', grantedByRoleUuid, 'RbacRole');
|
||||
perform rbac.assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole');
|
||||
perform rbac.assertReferenceType('userUuid (ascendant)', userUuid, 'rbac.subject');
|
||||
perform rbac.assertReferenceType('subjectUuid (ascendant)', subjectUuid, 'rbac.subject');
|
||||
|
||||
assert grantedByRoleUuid is not null, 'grantedByRoleUuid must not be null';
|
||||
assert grantedRoleUuid is not null, 'grantedRoleUuid must not be null';
|
||||
assert userUuid is not null, 'userUuid must not be null';
|
||||
assert subjectUuid is not null, 'subjectUuid must not be null';
|
||||
|
||||
if NOT isGranted(rbac.currentSubjectOrAssumedRolesUuids(), grantedByRoleUuid) then
|
||||
select roleIdName from rbacRole_ev where uuid=grantedByRoleUuid into grantedByRoleIdName;
|
||||
@ -62,8 +62,8 @@ begin
|
||||
|
||||
insert
|
||||
into RbacGrants (grantedByRoleUuid, ascendantUuid, descendantUuid, assumed)
|
||||
values (grantedByRoleUuid, userUuid, grantedRoleUuid, doAssume);
|
||||
-- TODO.impl: What should happen on mupltiple grants? What if options (doAssume) are not the same?
|
||||
values (grantedByRoleUuid, subjectUuid, grantedRoleUuid, doAssume);
|
||||
-- TODO.impl: What should happen on multiple grants? What if options (doAssume) are not the same?
|
||||
-- Most powerful or latest grant wins? What about managed?
|
||||
-- on conflict do nothing; -- allow granting multiple times
|
||||
end; $$;
|
||||
@ -74,12 +74,12 @@ end; $$;
|
||||
--changeset rbac-user-grant-REVOKE-ROLE-FROM-USER:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create or replace procedure checkRevokeRoleFromUserPreconditions(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid)
|
||||
create or replace procedure rbac.checkRevokeRoleFromSubjectPreconditions(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
perform rbac.assertReferenceType('grantedByRoleUuid', grantedByRoleUuid, 'RbacRole');
|
||||
perform rbac.assertReferenceType('grantedRoleUuid (descendant)', grantedRoleUuid, 'RbacRole');
|
||||
perform rbac.assertReferenceType('userUuid (ascendant)', userUuid, 'rbac.subject');
|
||||
perform rbac.assertReferenceType('subjectUuid (ascendant)', subjectUuid, 'rbac.subject');
|
||||
|
||||
if NOT isGranted(rbac.currentSubjectOrAssumedRolesUuids(), grantedByRoleUuid) then
|
||||
raise exception '[403] Revoking role created by % is forbidden for %.', grantedByRoleUuid, currentSubjects();
|
||||
@ -94,20 +94,20 @@ begin
|
||||
raise exception '[403] Revoking role granted by % is forbidden for %.', grantedByRoleUuid, currentSubjects();
|
||||
end if;
|
||||
|
||||
if NOT isGranted(userUuid, grantedRoleUuid) then
|
||||
raise exception '[404] No such grant found granted by % for user % to role %.', grantedByRoleUuid, userUuid, grantedRoleUuid;
|
||||
if NOT isGranted(subjectUuid, grantedRoleUuid) then
|
||||
raise exception '[404] No such grant found granted by % for subject % to role %.', grantedByRoleUuid, subjectUuid, grantedRoleUuid;
|
||||
end if;
|
||||
end; $$;
|
||||
|
||||
create or replace procedure revokeRoleFromUser(grantedByRoleUuid uuid, grantedRoleUuid uuid, userUuid uuid)
|
||||
create or replace procedure rbac.revokeRoleFromSubject(grantedByRoleUuid uuid, grantedRoleUuid uuid, subjectUuid uuid)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
call checkRevokeRoleFromUserPreconditions(grantedByRoleUuid, grantedRoleUuid, userUuid);
|
||||
call rbac.checkRevokeRoleFromSubjectPreconditions(grantedByRoleUuid, grantedRoleUuid, subjectUuid);
|
||||
|
||||
raise INFO 'delete from RbacGrants where ascendantUuid = % and descendantUuid = %', userUuid, grantedRoleUuid;
|
||||
raise INFO 'delete from RbacGrants where ascendantUuid = % and descendantUuid = %', subjectUuid, grantedRoleUuid;
|
||||
delete from RbacGrants as g
|
||||
where g.ascendantUuid = userUuid and g.descendantUuid = grantedRoleUuid
|
||||
and g.grantedByRoleUuid = revokeRoleFromUser.grantedByRoleUuid;
|
||||
where g.ascendantUuid = subjectUuid and g.descendantUuid = grantedRoleUuid
|
||||
and g.grantedByRoleUuid = revokeRoleFromSubject.grantedByRoleUuid;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
@ -115,7 +115,7 @@ end; $$;
|
||||
--changeset rbac-user-grant-REVOKE-PERMISSION-FROM-ROLE:1 endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create or replace procedure revokePermissionFromRole(permissionUuid uuid, superRoleUuid uuid)
|
||||
create or replace procedure rbac.revokePermissionFromRole(permissionUuid uuid, superRoleUuid uuid)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
raise INFO 'delete from RbacGrants where ascendantUuid = % and descendantUuid = %', superRoleUuid, permissionUuid;
|
||||
|
@ -117,7 +117,7 @@ create or replace view rbacgrants_rv as
|
||||
-- @formatter:off
|
||||
select o.objectTable || '#' || findIdNameByObjectUuid(o.objectTable, o.uuid) || ':' || r.roletype as grantedByRoleIdName,
|
||||
g.objectTable || '#' || g.objectIdName || ':' || g.roletype as grantedRoleIdName, g.userName, g.assumed,
|
||||
g.grantedByRoleUuid, g.descendantUuid as grantedRoleUuid, g.ascendantUuid as userUuid,
|
||||
g.grantedByRoleUuid, g.descendantUuid as grantedRoleUuid, g.ascendantUuid as subjectUuid,
|
||||
g.objectTable, g.objectUuid, g.objectIdName, g.roleType as grantedRoleType
|
||||
from (
|
||||
select g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid, g.assumed,
|
||||
@ -150,10 +150,10 @@ create or replace function insertRbacGrant()
|
||||
declare
|
||||
newGrant RbacGrants_RV;
|
||||
begin
|
||||
call grantRoleToUser(rbac.assumedRoleUuid(), new.grantedRoleUuid, new.userUuid, new.assumed);
|
||||
call rbac.grantRoleToSubject(rbac.assumedRoleUuid(), new.grantedRoleUuid, new.subjectUuid, new.assumed);
|
||||
select grv.*
|
||||
from RbacGrants_RV grv
|
||||
where grv.userUuid=new.userUuid and grv.grantedRoleUuid=new.grantedRoleUuid
|
||||
where grv.subjectUuid=new.subjectUuid and grv.grantedRoleUuid=new.grantedRoleUuid
|
||||
into newGrant;
|
||||
return newGrant;
|
||||
end; $$;
|
||||
@ -176,13 +176,13 @@ execute function insertRbacGrant();
|
||||
/**
|
||||
Instead of delete trigger function for RbacGrants_RV.
|
||||
|
||||
Checks if the current subject (user / assumed role) has the permission to revoke the grant.
|
||||
Checks if the current subject or assumed role have the permission to revoke the grant.
|
||||
*/
|
||||
create or replace function deleteRbacGrant()
|
||||
returns trigger
|
||||
language plpgsql as $$
|
||||
begin
|
||||
call revokeRoleFromUser(old.grantedByRoleUuid, old.grantedRoleUuid, old.userUuid);
|
||||
call rbac.revokeRoleFromSubject(old.grantedByRoleUuid, old.grantedRoleUuid, old.subjectUuid);
|
||||
return old;
|
||||
end; $$;
|
||||
|
||||
@ -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(targetUserUuid uuid)
|
||||
create or replace function 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 $$
|
||||
@ -353,8 +353,8 @@ begin
|
||||
-- @formatter:off
|
||||
currentSubjectUuid := rbac.currentSubjectUuid();
|
||||
|
||||
if hasGlobalRoleGranted(targetUserUuid) and not hasGlobalRoleGranted(currentSubjectUuid) then
|
||||
raise exception '[403] permissions of user "%" are not accessible to user "%"', targetUserUuid, basis.currentSubject();
|
||||
if hasGlobalRoleGranted(targetSubjectUuid) and not hasGlobalRoleGranted(currentSubjectUuid) then
|
||||
raise exception '[403] permissions of user "%" are not accessible to user "%"', targetSubjectUuid, basis.currentSubject();
|
||||
end if;
|
||||
|
||||
return query select
|
||||
@ -369,24 +369,24 @@ begin
|
||||
po.objecttable as permissionObjectTable,
|
||||
findIdNameByObjectUuid(po.objectTable, po.uuid) as permissionObjectIdName,
|
||||
po.uuid as permissionObjectUuid
|
||||
from queryPermissionsGrantedToSubjectId( targetUserUuid) as p
|
||||
from queryPermissionsGrantedToSubjectId( targetSubjectUuid) as p
|
||||
join rbacgrants as g on g.descendantUuid = p.uuid
|
||||
join rbac.object as po on po.uuid = p.objectUuid
|
||||
join rbacrole_rv as r on r.uuid = g.ascendantUuid
|
||||
join rbac.object as ro on ro.uuid = r.objectUuid
|
||||
where isGranted(targetUserUuid, r.uuid)
|
||||
where isGranted(targetSubjectUuid, r.uuid)
|
||||
) xp;
|
||||
-- @formatter:on
|
||||
end; $$;
|
||||
|
||||
create or replace function grantedPermissions(targetUserUuid uuid)
|
||||
create or replace function 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(targetUserUuid)
|
||||
select * from grantedPermissionsRaw(targetSubjectUuid)
|
||||
union all
|
||||
select roleUuid, roleName, permissionUuid, 'SELECT'::RbacOp, opTableName, objectTable, objectIdName, objectUuid
|
||||
from grantedPermissionsRaw(targetUserUuid)
|
||||
from grantedPermissionsRaw(targetSubjectUuid)
|
||||
where op <> 'SELECT'::RbacOp;
|
||||
$$;
|
||||
--//
|
||||
|
@ -12,7 +12,7 @@ create or replace function createRoleWithGrants(
|
||||
permissions RbacOp[] = array[]::RbacOp[],
|
||||
incomingSuperRoles RbacRoleDescriptor[] = array[]::RbacRoleDescriptor[],
|
||||
outgoingSubRoles RbacRoleDescriptor[] = array[]::RbacRoleDescriptor[],
|
||||
userUuids uuid[] = array[]::uuid[],
|
||||
subjectUuids uuid[] = array[]::uuid[],
|
||||
grantedByRole RbacRoleDescriptor = null
|
||||
)
|
||||
returns uuid
|
||||
@ -26,7 +26,7 @@ declare
|
||||
superRoleDesc RbacRoleDescriptor;
|
||||
subRoleUuid uuid;
|
||||
superRoleUuid uuid;
|
||||
userUuid uuid;
|
||||
subjectUuid uuid;
|
||||
userGrantsByRoleUuid uuid;
|
||||
begin
|
||||
roleUuid := coalesce(findRoleId(roleDescriptor), createRole(roleDescriptor));
|
||||
@ -49,16 +49,16 @@ begin
|
||||
call grantRoleToRole(subRoleUuid, roleUuid, subRoleDesc.assumed);
|
||||
end loop;
|
||||
|
||||
if cardinality(userUuids) > 0 then
|
||||
if cardinality(subjectUuids) > 0 then
|
||||
-- direct grants to users need a grantedByRole which can revoke the grant
|
||||
if grantedByRole is null then
|
||||
userGrantsByRoleUuid := roleUuid; -- TODO.impl: or do we want to require an explicit userGrantsByRoleUuid?
|
||||
else
|
||||
userGrantsByRoleUuid := getRoleId(grantedByRole);
|
||||
end if;
|
||||
foreach userUuid in array userUuids
|
||||
foreach subjectUuid in array subjectUuids
|
||||
loop
|
||||
call grantRoleToUserUnchecked(userGrantsByRoleUuid, roleUuid, userUuid);
|
||||
call rbac.grantRoleToUserUnchecked(userGrantsByRoleUuid, roleUuid, subjectUuid);
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
|
@ -158,8 +158,8 @@ do language plpgsql $$
|
||||
call basis.defineContext('creating fake test-realm admin users', null, null, null);
|
||||
|
||||
admins = findRoleId(globalAdmin());
|
||||
call grantRoleToUserUnchecked(admins, admins, rbac.create_subject('superuser-alex@hostsharing.net'));
|
||||
call grantRoleToUserUnchecked(admins, admins, rbac.create_subject('superuser-fran@hostsharing.net'));
|
||||
call rbac.grantRoleToUserUnchecked(admins, admins, rbac.create_subject('superuser-alex@hostsharing.net'));
|
||||
hsh-michaelhoennig marked this conversation as resolved
Outdated
|
||||
call rbac.grantRoleToUserUnchecked(admins, admins, rbac.create_subject('superuser-fran@hostsharing.net'));
|
||||
perform rbac.create_subject('selfregistered-user-drew@hostsharing.org');
|
||||
perform rbac.create_subject('selfregistered-test-user@hostsharing.org');
|
||||
end;
|
||||
|
@ -38,7 +38,7 @@ begin
|
||||
testCustomerOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalADMIN(unassumed())],
|
||||
userUuids => array[rbac.currentSubjectUuid()]
|
||||
subjectUuids => array[rbac.currentSubjectUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
|
@ -40,7 +40,7 @@ begin
|
||||
|
||||
select * into newCust
|
||||
from test_customer where reference=custReference;
|
||||
call grantRoleToUser(
|
||||
call rbac.grantRoleToSubject(
|
||||
getRoleId(testCustomerOwner(newCust)),
|
||||
getRoleId(testCustomerAdmin(newCust)),
|
||||
custAdminUuid,
|
||||
|
@ -29,7 +29,7 @@ begin
|
||||
values (cust.uuid, pacName, 'Here you can add your own description of package ' || pacName || '.')
|
||||
returning * into pac;
|
||||
|
||||
call grantRoleToUser(
|
||||
call rbac.grantRoleToSubject(
|
||||
getRoleId(testCustomerAdmin(cust)),
|
||||
findRoleId(testPackageAdmin(pac)),
|
||||
rbac.create_subject('pac-admin-' || pacName || '@' || cust.prefix || '.example.com'),
|
||||
|
@ -38,7 +38,7 @@ begin
|
||||
hsOfficeContactOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalADMIN()],
|
||||
userUuids => array[rbac.currentSubjectUuid()]
|
||||
subjectUuids => array[rbac.currentSubjectUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
|
@ -38,7 +38,7 @@ begin
|
||||
hsOfficePersonOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalADMIN()],
|
||||
userUuids => array[rbac.currentSubjectUuid()]
|
||||
subjectUuids => array[rbac.currentSubjectUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
|
@ -51,7 +51,7 @@ begin
|
||||
hsOfficeRelationOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalADMIN()],
|
||||
userUuids => array[rbac.currentSubjectUuid()]
|
||||
subjectUuids => array[rbac.currentSubjectUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
|
@ -110,22 +110,22 @@ begin
|
||||
|
||||
if NEW.partnerRelUuid <> OLD.partnerRelUuid then
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'DELETE'), hsOfficeRelationOWNER(oldPartnerRel));
|
||||
call rbac.revokePermissionFromRole(getPermissionId(OLD.uuid, 'DELETE'), hsOfficeRelationOWNER(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'DELETE'), hsOfficeRelationOWNER(newPartnerRel));
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'UPDATE'), hsOfficeRelationADMIN(oldPartnerRel));
|
||||
call rbac.revokePermissionFromRole(getPermissionId(OLD.uuid, 'UPDATE'), hsOfficeRelationADMIN(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'UPDATE'), hsOfficeRelationADMIN(newPartnerRel));
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(OLD.uuid, 'SELECT'), hsOfficeRelationTENANT(oldPartnerRel));
|
||||
call rbac.revokePermissionFromRole(getPermissionId(OLD.uuid, 'SELECT'), hsOfficeRelationTENANT(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(NEW.uuid, 'SELECT'), hsOfficeRelationTENANT(newPartnerRel));
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'DELETE'), hsOfficeRelationOWNER(oldPartnerRel));
|
||||
call rbac.revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'DELETE'), hsOfficeRelationOWNER(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'DELETE'), hsOfficeRelationOWNER(newPartnerRel));
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(oldPartnerRel));
|
||||
call rbac.revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'UPDATE'), hsOfficeRelationAGENT(newPartnerRel));
|
||||
|
||||
call revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAGENT(oldPartnerRel));
|
||||
call rbac.revokePermissionFromRole(getPermissionId(oldPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAGENT(oldPartnerRel));
|
||||
call grantPermissionToRole(createPermission(newPartnerDetails.uuid, 'SELECT'), hsOfficeRelationAGENT(newPartnerRel));
|
||||
|
||||
end if;
|
||||
|
@ -38,7 +38,7 @@ begin
|
||||
hsOfficeBankAccountOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalADMIN()],
|
||||
userUuids => array[rbac.currentSubjectUuid()]
|
||||
subjectUuids => array[rbac.currentSubjectUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
|
@ -51,7 +51,7 @@ begin
|
||||
hsOfficeSepaMandateOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[globalADMIN()],
|
||||
userUuids => array[rbac.currentSubjectUuid()]
|
||||
subjectUuids => array[rbac.currentSubjectUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
|
@ -45,7 +45,7 @@ begin
|
||||
|
||||
perform createRoleWithGrants(
|
||||
hsOfficeMembershipOWNER(NEW),
|
||||
userUuids => array[rbac.currentSubjectUuid()]
|
||||
subjectUuids => array[rbac.currentSubjectUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
|
@ -53,7 +53,7 @@ begin
|
||||
globalADMIN(unassumed()),
|
||||
hsBookingItemADMIN(newBookingItem),
|
||||
hsHostingAssetADMIN(newParentAsset)],
|
||||
userUuids => array[rbac.currentSubjectUuid()]
|
||||
subjectUuids => array[rbac.currentSubjectUuid()]
|
||||
);
|
||||
|
||||
perform createRoleWithGrants(
|
||||
|
@ -21,14 +21,14 @@ declare
|
||||
defaultPrefix varchar;
|
||||
managedServerUuid uuid;
|
||||
managedWebspaceUuid uuid;
|
||||
webUnixUserUuid uuid;
|
||||
mboxUnixUserUuid uuid;
|
||||
webUnixSubjectUuid uuid;
|
||||
mboxUnixSubjectUuid uuid;
|
||||
domainSetupUuid uuid;
|
||||
domainMBoxSetupUuid uuid;
|
||||
mariaDbInstanceUuid uuid;
|
||||
mariaDbUserUuid uuid;
|
||||
mariaDbSubjectUuid uuid;
|
||||
pgSqlInstanceUuid uuid;
|
||||
PgSqlUserUuid uuid;
|
||||
PgSqlSubjectUuid uuid;
|
||||
begin
|
||||
call basis.defineContext('creating hosting-asset test-data', null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
|
||||
|
||||
@ -68,14 +68,14 @@ begin
|
||||
|
||||
select uuid_generate_v4() into managedServerUuid;
|
||||
select uuid_generate_v4() into managedWebspaceUuid;
|
||||
select uuid_generate_v4() into webUnixUserUuid;
|
||||
select uuid_generate_v4() into mboxUnixUserUuid;
|
||||
select uuid_generate_v4() into webUnixSubjectUuid;
|
||||
select uuid_generate_v4() into mboxUnixSubjectUuid;
|
||||
select uuid_generate_v4() into domainSetupUuid;
|
||||
select uuid_generate_v4() into domainMBoxSetupUuid;
|
||||
select uuid_generate_v4() into mariaDbInstanceUuid;
|
||||
select uuid_generate_v4() into mariaDbUserUuid;
|
||||
select uuid_generate_v4() into mariaDbSubjectUuid;
|
||||
select uuid_generate_v4() into pgSqlInstanceUuid;
|
||||
select uuid_generate_v4() into pgSqlUserUuid;
|
||||
select uuid_generate_v4() into pgSqlSubjectUuid;
|
||||
debitorNumberSuffix := relatedDebitor.debitorNumberSuffix;
|
||||
defaultPrefix := relatedDebitor.defaultPrefix;
|
||||
|
||||
@ -86,17 +86,17 @@ begin
|
||||
(uuid_generate_v4(), cloudServerBI.uuid, 'CLOUD_SERVER', null, null, 'vm20' || debitorNumberSuffix, 'another CloudServer', '{}'::jsonb),
|
||||
(managedWebspaceUuid, managedWebspaceBI.uuid, 'MANAGED_WEBSPACE', managedServerUuid, null, defaultPrefix || '01', 'some Webspace', '{}'::jsonb),
|
||||
(mariaDbInstanceUuid, null, 'MARIADB_INSTANCE', managedServerUuid, null, 'vm10' || debitorNumberSuffix || '.MariaDB.default', 'some default MariaDB instance','{}'::jsonb),
|
||||
(mariaDbUserUuid, null, 'MARIADB_USER', managedWebspaceUuid, mariaDbInstanceUuid, defaultPrefix || '01_web', 'some default MariaDB user', '{ "password": "<TODO:replace-by-encrypted-mariadb-password"}'::jsonb ),
|
||||
(uuid_generate_v4(), null, 'MARIADB_DATABASE', mariaDbUserUuid, mariaDbInstanceUuid, defaultPrefix || '01_web', 'some default MariaDB database','{ "encryption": "utf8", "collation": "utf8"}'::jsonb ),
|
||||
(mariaDbSubjectUuid, null, 'MARIADB_USER', managedWebspaceUuid, mariaDbInstanceUuid, defaultPrefix || '01_web', 'some default MariaDB user', '{ "password": "<TODO:replace-by-encrypted-mariadb-password"}'::jsonb ),
|
||||
(uuid_generate_v4(), null, 'MARIADB_DATABASE', mariaDbSubjectUuid, mariaDbInstanceUuid, defaultPrefix || '01_web', 'some default MariaDB database','{ "encryption": "utf8", "collation": "utf8"}'::jsonb ),
|
||||
(pgSqlInstanceUuid, null, 'PGSQL_INSTANCE', managedServerUuid, null, 'vm10' || debitorNumberSuffix || '.Postgresql.default', 'some default Postgresql instance','{}'::jsonb),
|
||||
(PgSqlUserUuid, null, 'PGSQL_USER', managedWebspaceUuid, pgSqlInstanceUuid, defaultPrefix || '01_web', 'some default Postgresql user', '{ "password": "<TODO:replace-by-encrypted-postgresql-password"}'::jsonb ),
|
||||
(uuid_generate_v4(), null, 'PGSQL_DATABASE', pgSqlUserUuid, pgSqlInstanceUuid, defaultPrefix || '01_web', 'some default Postgresql database','{ "encryption": "utf8", "collation": "utf8"}'::jsonb ),
|
||||
(PgSqlSubjectUuid, null, 'PGSQL_USER', managedWebspaceUuid, pgSqlInstanceUuid, defaultPrefix || '01_web', 'some default Postgresql user', '{ "password": "<TODO:replace-by-encrypted-postgresql-password"}'::jsonb ),
|
||||
(uuid_generate_v4(), null, 'PGSQL_DATABASE', pgSqlSubjectUuid, pgSqlInstanceUuid, defaultPrefix || '01_web', 'some default Postgresql database','{ "encryption": "utf8", "collation": "utf8"}'::jsonb ),
|
||||
(uuid_generate_v4(), null, 'EMAIL_ALIAS', managedWebspaceUuid, null, defaultPrefix || '01-web', 'some E-Mail-Alias', '{ "target": [ "office@example.org", "archive@example.com" ] }'::jsonb),
|
||||
(webUnixUserUuid, null, 'UNIX_USER', managedWebspaceUuid, null, defaultPrefix || '01-web', 'some UnixUser for Website', '{ "SSD-soft-quota": "128", "SSD-hard-quota": "256", "HDD-soft-quota": "512", "HDD-hard-quota": "1024"}'::jsonb),
|
||||
(mboxUnixUserUuid, null, 'UNIX_USER', managedWebspaceUuid, null, defaultPrefix || '01-mbox', 'some UnixUser for E-Mail', '{ "SSD-soft-quota": "128", "SSD-hard-quota": "256", "HDD-soft-quota": "512", "HDD-hard-quota": "1024"}'::jsonb),
|
||||
(webUnixSubjectUuid, null, 'UNIX_USER', managedWebspaceUuid, null, defaultPrefix || '01-web', 'some UnixUser for Website', '{ "SSD-soft-quota": "128", "SSD-hard-quota": "256", "HDD-soft-quota": "512", "HDD-hard-quota": "1024"}'::jsonb),
|
||||
(mboxUnixSubjectUuid, null, 'UNIX_USER', managedWebspaceUuid, null, defaultPrefix || '01-mbox', 'some UnixUser for E-Mail', '{ "SSD-soft-quota": "128", "SSD-hard-quota": "256", "HDD-soft-quota": "512", "HDD-hard-quota": "1024"}'::jsonb),
|
||||
(domainSetupUuid, null, 'DOMAIN_SETUP', null, null, defaultPrefix || '.example.org', 'some Domain-Setup', '{}'::jsonb),
|
||||
(uuid_generate_v4(), null, 'DOMAIN_DNS_SETUP', domainSetupUuid, null, defaultPrefix || '.example.org|DNS', 'some Domain-DNS-Setup', '{}'::jsonb),
|
||||
(uuid_generate_v4(), null, 'DOMAIN_HTTP_SETUP', domainSetupUuid, webUnixUserUuid, defaultPrefix || '.example.org|HTTP', 'some Domain-HTTP-Setup', '{ "option-htdocsfallback": true, "use-fcgiphpbin": "/usr/lib/cgi-bin/php", "validsubdomainnames": "*"}'::jsonb),
|
||||
(uuid_generate_v4(), null, 'DOMAIN_HTTP_SETUP', domainSetupUuid, webUnixSubjectUuid, defaultPrefix || '.example.org|HTTP', 'some Domain-HTTP-Setup', '{ "option-htdocsfallback": true, "use-fcgiphpbin": "/usr/lib/cgi-bin/php", "validsubdomainnames": "*"}'::jsonb),
|
||||
(uuid_generate_v4(), null, 'DOMAIN_SMTP_SETUP', domainSetupUuid, managedWebspaceUuid, defaultPrefix || '.example.org|SMTP', 'some Domain-SMTP-Setup', '{}'::jsonb),
|
||||
(domainMBoxSetupUuid, null, 'DOMAIN_MBOX_SETUP', domainSetupUuid, managedWebspaceUuid, defaultPrefix || '.example.org|MBOX', 'some Domain-MBOX-Setup', '{}'::jsonb),
|
||||
(uuid_generate_v4(), null, 'EMAIL_ADDRESS', domainMBoxSetupUuid, null, 'test@' || defaultPrefix || '.example.org', 'some E-Mail-Address', '{}'::jsonb);
|
||||
|
@ -176,9 +176,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new bookingItem can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,9 +111,9 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new bookingProject can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,9 +247,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new asset can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -143,9 +143,9 @@ class HsOfficeBankAccountControllerAcceptanceTest extends ContextBasedTestWithCl
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new bankaccount can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,9 +122,9 @@ class HsOfficeContactControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new contact can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,9 +315,9 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new debitor can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -367,9 +367,9 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new debitor can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -204,10 +204,10 @@ class HsOfficeMembershipControllerAcceptanceTest extends ContextBasedTestWithCle
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new membership can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(membershipRepo.findByUuid(newUserUuid)).isPresent();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
assertThat(membershipRepo.findByUuid(newSubjectUuid)).isPresent();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,9 +141,9 @@ class HsOfficePartnerControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new partner can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -99,9 +99,9 @@ class HsOfficePersonControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new person can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,9 +161,9 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new relation can be accessed under the generated UUID
|
||||
final var newUserUuid = toCleanup(HsOfficeRelationRealEntity.class, UUID.fromString(
|
||||
final var newSubjectUuid = toCleanup(HsOfficeRelationRealEntity.class, UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1)));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -138,9 +138,9 @@ class HsOfficeSepaMandateControllerAcceptanceTest extends ContextBasedTestWithCl
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new sepaMandate can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newSubjectUuid).isNotNull();
|
||||
}
|
||||
|
||||
// TODO.test: move validation tests to a ...WebMvcTest
|
||||
|
@ -238,7 +238,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
}
|
||||
|
||||
@Nested
|
||||
class GrantRoleToUser {
|
||||
class GrantRoleToSubject {
|
||||
|
||||
@Test
|
||||
void packageAdmin_canGrantOwnPackageAdminRole_toArbitraryUser() {
|
||||
@ -295,7 +295,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
}
|
||||
|
||||
@Nested
|
||||
class RevokeRoleFromUser {
|
||||
class RevokeRoleFromSubject {
|
||||
|
||||
@Test
|
||||
@Transactional(propagation = Propagation.NEVER)
|
||||
@ -389,7 +389,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
{
|
||||
"assumed": true,
|
||||
"grantedRoleUuid": "%s",
|
||||
"granteeUserUuid": "%s"
|
||||
"granteeSubjectUuid": "%s"
|
||||
}
|
||||
""".formatted(
|
||||
grantedRole.getUuid(),
|
||||
@ -425,7 +425,7 @@ class RbacGrantControllerAcceptanceTest extends ContextBasedTest {
|
||||
{
|
||||
"assumed": true,
|
||||
"grantedRoleUuid": "%s",
|
||||
"granteeUserUuid": "%s"
|
||||
"granteeSubjectUuid": "%s"
|
||||
}
|
||||
""".formatted(
|
||||
grantedRole.getUuid(),
|
||||
|
@ -13,16 +13,16 @@ class RbacGrantEntityUnitTest {
|
||||
void getRbacGrantId() {
|
||||
// given
|
||||
final var grantedRoleUuid = UUID.randomUUID();
|
||||
final var granteeUserUuid = UUID.randomUUID();
|
||||
final var granteeSubjectUuid = UUID.randomUUID();
|
||||
final var entity = new RbacGrantEntity();
|
||||
entity.setGrantedRoleUuid(grantedRoleUuid);
|
||||
entity.setGranteeUserUuid(granteeUserUuid);
|
||||
entity.setGranteeSubjectUuid(granteeSubjectUuid);
|
||||
|
||||
// when
|
||||
final var grantId = entity.getRbacGrantId();
|
||||
|
||||
// then
|
||||
assertThat(grantId).isEqualTo(new RbacGrantId(granteeUserUuid, grantedRoleUuid));
|
||||
assertThat(grantId).isEqualTo(new RbacGrantId(granteeSubjectUuid, grantedRoleUuid));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -103,18 +103,18 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
}
|
||||
|
||||
@Nested
|
||||
class GrantRoleToUser {
|
||||
class GrantRoleToSubject {
|
||||
|
||||
@Test
|
||||
public void customerAdmin_canGrantOwnPackageAdminRole_toArbitraryUser() {
|
||||
// given
|
||||
context("customer-admin@xxx.example.com", "test_customer#xxx:ADMIN");
|
||||
final var givenArbitraryUserUuid = rbacUserRepository.findByName("pac-admin-zzz00@zzz.example.com").getUuid();
|
||||
final var givenArbitrarySubjectUuid = rbacUserRepository.findByName("pac-admin-zzz00@zzz.example.com").getUuid();
|
||||
final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName("test_package#xxx00:ADMIN").getUuid();
|
||||
|
||||
// when
|
||||
final var grant = RbacGrantEntity.builder()
|
||||
.granteeUserUuid(givenArbitraryUserUuid).grantedRoleUuid(givenOwnPackageRoleUuid)
|
||||
.granteeSubjectUuid(givenArbitrarySubjectUuid).grantedRoleUuid(givenOwnPackageRoleUuid)
|
||||
.assumed(true)
|
||||
.build();
|
||||
final var attempt = attempt(em, () ->
|
||||
@ -148,7 +148,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
// now we try to use these uuids as a less privileged user
|
||||
context("pac-admin-xxx00@xxx.example.com", "test_package#xxx00:ADMIN");
|
||||
final var grant = RbacGrantEntity.builder()
|
||||
.granteeUserUuid(given.arbitraryUser.getUuid())
|
||||
.granteeSubjectUuid(given.arbitraryUser.getUuid())
|
||||
.grantedRoleUuid(given.packageOwnerRoleUuid)
|
||||
.assumed(true)
|
||||
.build();
|
||||
@ -170,7 +170,7 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
}
|
||||
|
||||
@Nested
|
||||
class RevokeRoleFromUser {
|
||||
class revokeRoleFromSubject {
|
||||
|
||||
@Test
|
||||
public void customerAdmin_canRevokeSelfGrantedPackageAdminRole() {
|
||||
@ -236,11 +236,11 @@ class RbacGrantRepositoryIntegrationTest extends ContextBasedTest {
|
||||
|
||||
private RbacGrantEntity create(GrantBuilder with) {
|
||||
context(with.byUserName, with.assumedRole);
|
||||
final var givenArbitraryUserUuid = rbacUserRepository.findByName(with.granteeUserName).getUuid();
|
||||
final var givenArbitrarySubjectUuid = rbacUserRepository.findByName(with.granteeUserName).getUuid();
|
||||
final var givenOwnPackageRoleUuid = rbacRoleRepository.findByRoleName(with.grantedRole).getUuid();
|
||||
|
||||
final var grant = RbacGrantEntity.builder()
|
||||
.granteeUserUuid(givenArbitraryUserUuid).grantedRoleUuid(givenOwnPackageRoleUuid)
|
||||
.granteeSubjectUuid(givenArbitrarySubjectUuid).grantedRoleUuid(givenOwnPackageRoleUuid)
|
||||
.assumed(true)
|
||||
.build();
|
||||
final var grantAttempt = attempt(em, () ->
|
||||
|
@ -63,10 +63,10 @@ class RbacUserControllerAcceptanceTest {
|
||||
// @formatter:on
|
||||
|
||||
// finally, the user can view its own record
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
context.define("new-user@example.com");
|
||||
assertThat(rbacUserRepository.findByUuid(newUserUuid))
|
||||
assertThat(rbacUserRepository.findByUuid(newSubjectUuid))
|
||||
.extracting(RbacUserEntity::getName).isEqualTo("new-user@example.com");
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
||||
context("superuser-alex@hostsharing.net");
|
||||
|
||||
// when
|
||||
final var result = rbacUserRepository.findPermissionsOfUserByUuid(userUUID("superuser-fran@hostsharing.net"))
|
||||
final var result = rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid("superuser-fran@hostsharing.net"))
|
||||
.stream().filter(p -> p.getObjectTable().contains("test_"))
|
||||
.sorted(comparing(RbacUserPermission::toString)).toList();
|
||||
|
||||
@ -246,7 +246,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
||||
context("customer-admin@xxx.example.com");
|
||||
|
||||
// when
|
||||
final var result = rbacUserRepository.findPermissionsOfUserByUuid(userUUID("customer-admin@xxx.example.com"));
|
||||
final var result = rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid("customer-admin@xxx.example.com"));
|
||||
|
||||
// then
|
||||
allTheseRbacPermissionsAreReturned(
|
||||
@ -286,17 +286,17 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
||||
public void customerAdmin_withoutAssumedRole_isNotAllowedToViewGlobalAdminsPermissions() {
|
||||
// given
|
||||
context("customer-admin@xxx.example.com");
|
||||
final UUID userUuid = userUUID("superuser-alex@hostsharing.net");
|
||||
final UUID subjectUuid = subjectUuid("superuser-alex@hostsharing.net");
|
||||
|
||||
// when
|
||||
final var result = attempt(em, () ->
|
||||
rbacUserRepository.findPermissionsOfUserByUuid(userUuid)
|
||||
rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid)
|
||||
);
|
||||
|
||||
// then
|
||||
result.assertExceptionWithRootCauseMessage(
|
||||
JpaSystemException.class,
|
||||
"[403] permissions of user \"" + userUuid
|
||||
"[403] permissions of user \"" + subjectUuid
|
||||
+ "\" are not accessible to user \"customer-admin@xxx.example.com\"");
|
||||
}
|
||||
|
||||
@ -306,7 +306,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
||||
context("customer-admin@xxx.example.com");
|
||||
|
||||
// when
|
||||
final var result = rbacUserRepository.findPermissionsOfUserByUuid(userUUID("pac-admin-xxx00@xxx.example.com"));
|
||||
final var result = rbacUserRepository.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(userUUID("pac-admin-yyy00@yyy.example.com"));
|
||||
final var result = rbacUserRepository.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(userUUID("pac-admin-xxx00@xxx.example.com"));
|
||||
final var result = rbacUserRepository.findPermissionsOfUserByUuid(subjectUuid("pac-admin-xxx00@xxx.example.com"));
|
||||
|
||||
// then
|
||||
allTheseRbacPermissionsAreReturned(
|
||||
@ -385,7 +385,7 @@ class RbacUserRepositoryIntegrationTest extends ContextBasedTest {
|
||||
}
|
||||
}
|
||||
|
||||
UUID userUUID(final String userName) {
|
||||
UUID subjectUuid(final String userName) {
|
||||
return rbacUserRepository.findByName(userName).getUuid();
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ import org.springframework.data.repository.Repository;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.transaction.Transactional;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -146,10 +146,10 @@ class TestCustomerControllerAcceptanceTest {
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new customer can be viewed by its own admin
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newSubjectUuid = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
context.define("superuser-fran@hostsharing.net", "test_customer#uuu:ADMIN");
|
||||
assertThat(testCustomerRepository.findByUuid(newUserUuid))
|
||||
assertThat(testCustomerRepository.findByUuid(newSubjectUuid))
|
||||
.hasValueSatisfying(c -> assertThat(c.getPrefix()).isEqualTo("uuu"));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user
müsste das nicht grantRoleToSubjectUnchecked heißen