improved rbacroles_ev view and raw access for testing purposes

This commit is contained in:
Michael Hoennig 2022-09-10 14:49:01 +02:00
parent 2c5ad094f1
commit 3eec8a4138
11 changed files with 189 additions and 21 deletions

View File

@ -25,6 +25,8 @@ configurations {
extendsFrom annotationProcessor
}
testCompile {
extendsFrom testAnnotationProcessor
// Only JUNit 5 (Jupiter) should be used at compile time.
// For runtime it's still needed by testcontainers, though.
exclude group: 'junit', module: 'junit'
@ -60,12 +62,14 @@ dependencies {
implementation 'org.modelmapper:modelmapper:3.1.0'
compileOnly 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.testcontainers:testcontainers'

View File

@ -185,7 +185,6 @@ begin
objectIdName := pureIdentifier(objectIdName);
sql := format('select * from %sUuidByIdName(%L);', objectTable, objectIdName);
begin
raise notice 'sql: %', sql;
execute sql into uuid;
exception
when others then
@ -205,7 +204,6 @@ begin
objectTable := pureIdentifier(objectTable);
sql := format('select * from %sIdNameByUuid(%L::uuid);', objectTable, objectUuid);
begin
raise notice 'sql: %', sql;
execute sql into idName;
exception
when others then

View File

@ -106,7 +106,6 @@ begin
createTriggerSQL = 'CREATE TRIGGER ' || targetTable || '_journal' ||
' AFTER INSERT OR UPDATE OR DELETE ON ' || targetTable ||
' FOR EACH ROW EXECUTE PROCEDURE tx_journal_trigger()';
raise notice 'sql: %', createTriggerSQL;
execute createTriggerSQL;
end; $$;
--//

View File

@ -364,8 +364,8 @@ create table RbacGrants
(
uuid uuid primary key default uuid_generate_v4(),
grantedByRoleUuid uuid references RbacRole (uuid) on delete cascade,
ascendantUuid uuid references RbacReference (uuid) on delete cascade,
descendantUuid uuid references RbacReference (uuid) on delete cascade,
ascendantUuid uuid references RbacReference (uuid) on delete cascade not null,
descendantUuid uuid references RbacReference (uuid) on delete cascade not null,
assumed boolean not null default true, -- auto assumed (true) vs. needs assumeRoles (false)
unique (ascendantUuid, descendantUuid)
);

View File

@ -55,22 +55,45 @@ grant all privileges on rbacrole_rv to restricted;
drop view if exists rbacgrants_ev;
create or replace view rbacgrants_ev 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.objectTable, g.objectUuid, g.objectIdName, g.roleType as grantedRoleType
select x.grantUuid as uuid,
go.objectTable || '#' || findIdNameByObjectUuid(go.objectTable, go.uuid) || '.' || r.roletype as grantedByRoleIdName,
x.ascendingIdName as ascendantIdName,
x.descendingIdName as descendantIdName,
x.grantedByRoleUuid,
x.ascendantUuid as ascendantUuid,
x.descendantUuid as descenantUuid,
x.assumed
from (
select g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid, g.assumed,
u.name as userName, o.objecttable, r.objectuuid, r.roletype,
findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
select g.uuid as grantUuid,
g.grantedbyroleuuid, g.ascendantuuid, g.descendantuuid, g.assumed,
coalesce(
'user ' || au.name,
'role ' || aro.objectTable || '#' || findIdNameByObjectUuid(aro.objectTable, aro.uuid) || '.' || ar.roletype
) as ascendingIdName,
aro.objectTable, aro.uuid,
coalesce(
'role ' || dro.objectTable || '#' || findIdNameByObjectUuid(dro.objectTable, dro.uuid) || '.' || dr.roletype,
'perm ' || dp.op || ' on ' || dpo.objecttable || '#' || findIdNameByObjectUuid(dpo.objectTable, dpo.uuid)
) as descendingIdName,
dro.objectTable, dro.uuid
from rbacgrants as g
join rbacrole as r on r.uuid = g.descendantUuid
join rbacobject o on o.uuid = r.objectuuid
right outer join rbacuser u on u.uuid = g.ascendantuuid
) as g
join RbacRole as r on r.uuid = grantedByRoleUuid
join RbacObject as o on o.uuid = r.objectUuid
order by grantedRoleIdName;
left outer join rbacrole as ar on ar.uuid = g.ascendantUuid
left outer join rbacobject as aro on aro.uuid = ar.objectuuid
left outer join rbacuser as au on au.uuid = g.ascendantUuid
left outer join rbacrole as dr on dr.uuid = g.descendantUuid
left outer join rbacobject as dro on dro.uuid = dr.objectuuid
left outer join rbacpermission dp on dp.uuid = g.descendantUuid
left outer join rbacobject as dpo on dpo.uuid = dp.objectUuid
) as x
left outer join rbacrole as r on r.uuid = grantedByRoleUuid
left outer join rbacuser u on u.uuid = x.ascendantuuid
left outer join rbacobject go on go.uuid = r.objectuuid
order by x.ascendingIdName, x.descendingIdName;
-- @formatter:on
--//
@ -96,7 +119,7 @@ select o.objectTable || '#' || findIdNameByObjectUuid(o.objectTable, o.uuid) ||
from rbacgrants as g
join rbacrole as r on r.uuid = g.descendantUuid
join rbacobject o on o.uuid = r.objectuuid
join rbacuser u on u.uuid = g.ascendantuuid
left outer join rbacuser u on u.uuid = g.ascendantuuid
where isGranted(currentSubjectsUuids(), r.uuid)
) as g
join RbacRole as r on r.uuid = grantedByRoleUuid

View File

@ -0,0 +1,14 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.stream.Collectors;
public class RawRbacGrantDisplayExtractor {
@NotNull
public static List<String> grantDisplaysOf(final List<RawRbacGrantEntity> roles) {
return roles.stream().map(RawRbacGrantEntity::toDisplay).collect(Collectors.toList());
}
}

View File

@ -0,0 +1,55 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
import lombok.*;
import org.springframework.data.annotation.Immutable;
import javax.persistence.*;
import java.util.UUID;
@Entity
@Table(name = "rbacgrants_ev")
@Getter
@Setter
@Builder
@ToString
@Immutable
@NoArgsConstructor
@AllArgsConstructor
public class RawRbacGrantEntity {
@Id
private UUID uuid;
@Column(name = "grantedbyroleidname", updatable = false, insertable = false)
private String grantedByRoleIdName;
@Column(name = "grantedbyroleuuid", updatable = false, insertable = false)
private UUID grantedByRoleUuid;
@Column(name = "ascendantidname", updatable = false, insertable = false)
private String ascendantIdName;
@Column(name = "ascendantuuid", updatable = false, insertable = false)
private UUID ascendingUuid;
@Column(name = "descendantidname", updatable = false, insertable = false)
private String descendantIdName;
@Column(name = "descenantuuid", updatable = false, insertable = false)
private UUID descendantUuid;
@Column(name = "assumed", updatable = false, insertable = false)
private boolean assumed;
public String toDisplay() {
// @formatter:off
return "{ grant " + descendantIdName +
" to " + ascendantIdName +
" by " + ( grantedByRoleUuid == null
? "system"
: grantedByRoleIdName ) +
( assumed ? " and assume" : "") +
" }";
// @formatter:on
}
}

View File

@ -0,0 +1,11 @@
package net.hostsharing.hsadminng.rbac.rbacgrant;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.UUID;
public interface RawRbacGrantRepository extends Repository<RawRbacGrantEntity, UUID> {
List<RawRbacGrantEntity> findAll();
}

View File

@ -0,0 +1,38 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
import lombok.*;
import org.hibernate.annotations.Formula;
import org.springframework.data.annotation.Immutable;
import javax.persistence.*;
import java.util.UUID;
@Entity
@Table(name = "rbacrole_ev")
@Getter
@Setter
@ToString
@Immutable
@NoArgsConstructor
@AllArgsConstructor
public class RawRbacRoleEntity {
@Id
private UUID uuid;
@Column(name="objectuuid")
private UUID objectUuid;
@Column(name="objecttable")
private String objectTable;
@Column(name="objectidname")
private String objectIdName;
@Column(name="roletype")
@Enumerated(EnumType.STRING)
private RbacRoleType roleType;
@Formula("objectTable||'#'||objectIdName||'.'||roleType")
private String roleName;
}

View File

@ -0,0 +1,15 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.stream.Collectors;
public class RawRbacRoleNameExtractor {
@NotNull
public static List<String> roleNamesOf(@NotNull final List<RawRbacRoleEntity> roles) {
return roles.stream().map(RawRbacRoleEntity::getRoleName).collect(Collectors.toList());
}
}

View File

@ -0,0 +1,11 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.UUID;
public interface RawRbacRoleRepository extends Repository<RawRbacRoleEntity, UUID> {
List<RawRbacRoleEntity> findAll();
}