add RbacRole...
This commit is contained in:
parent
bb05eb4ac4
commit
ece36209a5
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
package net.hostsharing.hsadminng.rbac.rbacrole;
|
||||||
|
|
||||||
|
public enum RbacRoleType {
|
||||||
|
owner, admin, tenant
|
||||||
|
}
|
@ -151,13 +151,11 @@ create type RbacRoleDescriptor as
|
|||||||
create or replace function roleDescriptor(objectTable varchar(63), objectUuid uuid, roleType RbacRoleType)
|
create or replace function roleDescriptor(objectTable varchar(63), objectUuid uuid, roleType RbacRoleType)
|
||||||
returns RbacRoleDescriptor
|
returns RbacRoleDescriptor
|
||||||
returns null on null input
|
returns null on null input
|
||||||
-- STABLE LEAKPROOF
|
stable leakproof
|
||||||
language sql as $$
|
language sql as $$
|
||||||
select objectTable, objectUuid, roleType::RbacRoleType;
|
select objectTable, objectUuid, roleType::RbacRoleType;
|
||||||
$$;
|
$$;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
create or replace function createRole(roleDescriptor RbacRoleDescriptor)
|
create or replace function createRole(roleDescriptor RbacRoleDescriptor)
|
||||||
returns uuid
|
returns uuid
|
||||||
returns null on null input
|
returns null on null input
|
||||||
@ -347,6 +345,22 @@ select granteeId = grantedId or granteeId in (with recursive grants as (select d
|
|||||||
from grants);
|
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)
|
create or replace function isPermissionGrantedToSubject(permissionId uuid, subjectId uuid)
|
||||||
returns BOOL
|
returns BOOL
|
||||||
stable leakproof
|
stable leakproof
|
||||||
@ -607,6 +621,7 @@ begin
|
|||||||
return regexp_replace(rawIdentifier, '\W+', '');
|
return regexp_replace(rawIdentifier, '\W+', '');
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
|
-- TODO: rename to findObjectUuidByIdName
|
||||||
create or replace function findUuidByIdName(objectTable varchar, objectIdName varchar)
|
create or replace function findUuidByIdName(objectTable varchar, objectIdName varchar)
|
||||||
returns uuid
|
returns uuid
|
||||||
returns null on null input
|
returns null on null input
|
||||||
@ -628,18 +643,38 @@ begin
|
|||||||
return uuid;
|
return uuid;
|
||||||
end ; $$;
|
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()
|
create or replace function currentSubjects()
|
||||||
returns varchar(63)[]
|
returns varchar(63)[]
|
||||||
stable leakproof
|
stable leakproof
|
||||||
language plpgsql as $$
|
language plpgsql as $$
|
||||||
declare
|
declare
|
||||||
assumedRoles varchar(63)[];
|
assumedRoles varchar(63)[];
|
||||||
begin
|
begin
|
||||||
assumedRoles := assumedRoles();
|
assumedRoles := assumedRoles();
|
||||||
if array_length(assumedRoles(), 1) > 0 then
|
if array_length(assumedRoles(), 1) > 0 then
|
||||||
return assumedRoles();
|
return assumedRoles();
|
||||||
else
|
else
|
||||||
return array[currentUser()]::varchar(63)[];
|
return array [currentUser()]::varchar(63)[];
|
||||||
end if;
|
end if;
|
||||||
end; $$;
|
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;
|
||||||
|
--//
|
||||||
|
@ -58,7 +58,7 @@ select target.uuid, target.name as idName
|
|||||||
grant all privileges on global_iv to restricted;
|
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)
|
create or replace function globalUuidByIdName(idName varchar)
|
||||||
returns uuid
|
returns uuid
|
||||||
@ -66,6 +66,16 @@ create or replace function globalUuidByIdName(idName varchar)
|
|||||||
strict as $$
|
strict as $$
|
||||||
select uuid from global_iv iv where iv.idName = globalUuidByIdName.idName;
|
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;
|
||||||
|
$$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
@ -163,6 +163,16 @@ create or replace function customerUuidByIdName(idName varchar)
|
|||||||
strict as $$
|
strict as $$
|
||||||
select uuid from customer_iv iv where iv.idName = customerUuidByIdName.idName;
|
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:--//
|
--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.
|
based on the 'view' permission of the current user or assumed roles.
|
||||||
*/
|
*/
|
||||||
set session session authorization default;
|
set session session authorization default;
|
||||||
|
@ -162,6 +162,16 @@ create or replace function packageUuidByIdName(idName varchar)
|
|||||||
strict as $$
|
strict as $$
|
||||||
select uuid from package_iv iv where iv.idName = packageUuidByIdName.idName;
|
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;
|
||||||
|
$$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user