add RbacRole...

This commit is contained in:
Michael Hoennig 2022-08-03 06:12:16 +02:00
parent bb05eb4ac4
commit ece36209a5
8 changed files with 222 additions and 7 deletions

View File

@ -0,0 +1,34 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
import net.hostsharing.hsadminng.context.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import javax.transaction.Transactional;
@RestController
public class RbacRoleController {
@Autowired
private Context context;
@Autowired
private RbacRoleRepository rbacRoleRepository;
@GetMapping(value = "/api/rbacroles")
@Transactional
public Iterable<RbacRoleEntity> listCustomers(
@RequestHeader(value = "current-user") String userName,
@RequestHeader(value = "assumed-roles", required = false) String assumedRoles
) {
context.setCurrentUser(userName);
if (assumedRoles != null && !assumedRoles.isBlank()) {
context.assumeRoles(assumedRoles);
}
return rbacRoleRepository.findAll();
}
}

View File

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

View File

@ -0,0 +1,58 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface RbacRoleRepository extends Repository<RbacRoleEntity, UUID> {
/**
* Retrieves an entity by its id.
*
* @param id must not be {@literal null}.
* @return the entity with the given id or {@literal Optional#empty()} if none found.
* @throws IllegalArgumentException if {@literal id} is {@literal null}.
*/
Optional<RbacRoleEntity> findByUuid(UUID id);
/**
* Returns whether an entity with the given id exists.
*
* @param id must not be {@literal null}.
* @return {@literal true} if an entity with the given id exists, {@literal false} otherwise.
* @throws IllegalArgumentException if {@literal id} is {@literal null}.
*/
boolean existsByUuid(RbacRoleEntity id);
/**
* Returns all instances of the type.
*
* @return all entities
*/
Iterable<RbacRoleEntity> findAll();
/**
* Returns all entities sorted by the given options.
*
* @param sort the {@link Sort} specification to sort the results by, can be {@link Sort#unsorted()}, must not be
* {@literal null}.
* @return all entities sorted by the given options
*/
List<RbacRoleEntity> findAll(Sort sort);
/**
* Returns a {@link Page} of entities meeting the paging restriction provided in the {@link Pageable} object.
*
* @param pageable the pageable to request a paged result, can be {@link Pageable#unpaged()}, must not be
* {@literal null}.
* @return a page of entities
*/
Page<RbacRoleEntity> findAll(Pageable pageable);
}

View File

@ -0,0 +1,5 @@
package net.hostsharing.hsadminng.rbac.rbacrole;
public enum RbacRoleType {
owner, admin, tenant
}

View File

@ -151,13 +151,11 @@ create type RbacRoleDescriptor as
create or replace function roleDescriptor(objectTable varchar(63), objectUuid uuid, roleType RbacRoleType)
returns RbacRoleDescriptor
returns null on null input
-- STABLE LEAKPROOF
stable leakproof
language sql as $$
select objectTable, objectUuid, roleType::RbacRoleType;
$$;
create or replace function createRole(roleDescriptor RbacRoleDescriptor)
returns uuid
returns null on null input
@ -347,6 +345,22 @@ select granteeId = grantedId or granteeId in (with recursive grants as (select d
from grants);
$$;
create or replace function isGranted(granteeIds uuid[], grantedId uuid)
returns bool
returns null on null input
language plpgsql as $$
declare
granteeId uuid;
begin
-- TODO: needs optimization
foreach granteeId in array granteeIds loop
if isGranted(granteeId, grantedId) then
return true;
end if;
end loop;
return false;
end; $$;
create or replace function isPermissionGrantedToSubject(permissionId uuid, subjectId uuid)
returns BOOL
stable leakproof
@ -607,6 +621,7 @@ begin
return regexp_replace(rawIdentifier, '\W+', '');
end; $$;
-- TODO: rename to findObjectUuidByIdName
create or replace function findUuidByIdName(objectTable varchar, objectIdName varchar)
returns uuid
returns null on null input
@ -628,18 +643,38 @@ begin
return uuid;
end ; $$;
create or replace function findIdNameByObjectUuid(objectTable varchar, objectUuid uuid)
returns varchar
returns null on null input
language plpgsql as $$
declare
sql varchar;
idName varchar;
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
raise exception 'function %IdNameByUuid(...) not found, add identity view support for table %', objectTable, objectTable;
end;
return idName;
end ; $$;
create or replace function currentSubjects()
returns varchar(63)[]
stable leakproof
language plpgsql as $$
declare
assumedRoles varchar(63)[];
assumedRoles varchar(63)[];
begin
assumedRoles := assumedRoles();
if array_length(assumedRoles(), 1) > 0 then
return assumedRoles();
else
return array[currentUser()]::varchar(63)[];
return array [currentUser()]::varchar(63)[];
end if;
end; $$;
@ -708,3 +743,20 @@ grant all privileges on all tables in schema public to restricted;
--//
-- ============================================================================
--changeset rbac-base-ROLE-RESTRICTED-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Creates a view to the role table with row-level limitation
based on the grants of the current user or assumed roles.
*/
drop view if exists rbacrole_rv;
create or replace view rbacrole_rv as
select r.*, o.objectTable,
findIdNameByObjectUuid(o.objectTable, o.uuid) as objectIdName
from rbacrole as r
join rbacobject as o on o.uuid=r.objectuuid
where isGranted(currentSubjectIds(), r.uuid);
grant all privileges on rbacrole_rv to restricted;
--//

View File

@ -58,7 +58,7 @@ select target.uuid, target.name as idName
grant all privileges on global_iv to restricted;
/*
Returns the objectUuid for a given identifying name (in this case the prefix).
Returns the objectUuid for a given identifying name (in this case the idName).
*/
create or replace function globalUuidByIdName(idName varchar)
returns uuid
@ -66,6 +66,16 @@ create or replace function globalUuidByIdName(idName varchar)
strict as $$
select uuid from global_iv iv where iv.idName = globalUuidByIdName.idName;
$$;
/*
Returns the identifying name for a given objectUuid (in this case the idName).
*/
create or replace function globalIdNameByUuid(uuid uuid)
returns varchar
language sql
strict as $$
select idName from global_iv iv where iv.uuid = globalIdNameByUuid.uuid;
$$;
--//
-- ============================================================================

View File

@ -163,6 +163,16 @@ create or replace function customerUuidByIdName(idName varchar)
strict as $$
select uuid from customer_iv iv where iv.idName = customerUuidByIdName.idName;
$$;
/*
Returns the identifying name for a given objectUuid (in this case the prefix).
*/
create or replace function customerIdNameByUuid(uuid uuid)
returns varchar
language sql
strict as $$
select idName from customer_iv iv where iv.uuid = customerIdNameByUuid.uuid;
$$;
--//
@ -170,7 +180,7 @@ $$;
--changeset hs-customer-rbac-RESTRICTED-VIEW:1 endDelimiter:--//
-- ----------------------------------------------------------------------------
/*
Creates a view to the customer main table with row-level limitatation
Creates a view to the customer main table with row-level limitation
based on the 'view' permission of the current user or assumed roles.
*/
set session session authorization default;

View File

@ -162,6 +162,16 @@ create or replace function packageUuidByIdName(idName varchar)
strict as $$
select uuid from package_iv iv where iv.idName = packageUuidByIdName.idName;
$$;
/*
Returns the identifying name for a given objectUuid (in this case the name).
*/
create or replace function packageIdNameByUuid(uuid uuid)
returns varchar
language sql
strict as $$
select idName from package_iv iv where iv.uuid = packageIdNameByUuid.uuid;
$$;
--//