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)
|
||||
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;
|
||||
--//
|
||||
|
@ -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;
|
||||
$$;
|
||||
--//
|
||||
|
||||
-- ============================================================================
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
$$;
|
||||
--//
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user