2022-08-19 10:28:53 +02:00
import NameExistsError from '../error/name-exists-error' ;
import getLogger from '../../test/fixtures/no-logger' ;
2023-06-22 16:42:01 +02:00
import { createFakeAccessService } from '../features/access/createAccessService' ;
2023-08-08 13:45:19 +02:00
import { AccessService , IRoleValidation } from './access-service' ;
2023-06-14 15:40:40 +02:00
import { createTestConfig } from '../../test/config/test-config' ;
2023-06-22 16:42:01 +02:00
import { CUSTOM_ROOT_ROLE_TYPE } from '../util/constants' ;
2023-08-08 13:45:19 +02:00
import FakeGroupStore from '../../test/fixtures/fake-group-store' ;
import { FakeAccountStore } from '../../test/fixtures/fake-account-store' ;
import FakeRoleStore from '../../test/fixtures/fake-role-store' ;
import FakeEnvironmentStore from '../../test/fixtures/fake-environment-store' ;
import AccessStoreMock from '../../test/fixtures/fake-access-store' ;
import { GroupService } from '../services/group-service' ;
import FakeEventStore from '../../test/fixtures/fake-event-store' ;
import { IRole } from 'lib/types/stores/access-store' ;
import { IGroup } from 'lib/types' ;
2022-08-19 10:28:53 +02:00
2023-08-10 14:11:55 +02:00
function getSetup ( customRootRolesKillSwitch : boolean = true ) {
2023-06-14 15:40:40 +02:00
const config = createTestConfig ( {
getLogger ,
2023-06-22 16:42:01 +02:00
experimental : {
flags : {
2023-08-10 14:11:55 +02:00
customRootRolesKillSwitch ,
2023-06-22 16:42:01 +02:00
} ,
} ,
2023-06-14 15:40:40 +02:00
} ) ;
2022-08-19 10:28:53 +02:00
return {
2023-06-22 16:42:01 +02:00
accessService : createFakeAccessService ( config ) ,
2022-08-19 10:28:53 +02:00
} ;
}
2023-06-22 16:42:01 +02:00
test ( 'should fail when name exists' , async ( ) = > {
const { accessService } = getSetup ( ) ;
const existingRole = await accessService . createRole ( {
2022-08-19 10:28:53 +02:00
name : 'existing role' ,
description : 'description' ,
2023-06-22 16:42:01 +02:00
permissions : [ ] ,
} ) ;
2022-08-19 10:28:53 +02:00
expect ( accessService . validateRole ( existingRole ) ) . rejects . toThrow (
new NameExistsError (
` There already exists a role with the name ${ existingRole . name } ` ,
) ,
) ;
} ) ;
test ( 'should validate a role without permissions' , async ( ) = > {
2023-06-22 16:42:01 +02:00
const { accessService } = getSetup ( ) ;
2022-08-19 10:28:53 +02:00
const withoutPermissions : IRoleValidation = {
name : 'name of the role' ,
description : 'description' ,
} ;
expect ( await accessService . validateRole ( withoutPermissions ) ) . toEqual (
withoutPermissions ,
) ;
} ) ;
test ( 'should complete description field when not present' , async ( ) = > {
2023-06-22 16:42:01 +02:00
const { accessService } = getSetup ( ) ;
2022-08-19 10:28:53 +02:00
const withoutDescription : IRoleValidation = {
name : 'name of the role' ,
} ;
expect ( await accessService . validateRole ( withoutDescription ) ) . toEqual ( {
name : 'name of the role' ,
description : '' ,
} ) ;
} ) ;
test ( 'should accept empty permissions' , async ( ) = > {
2023-06-22 16:42:01 +02:00
const { accessService } = getSetup ( ) ;
2022-08-19 10:28:53 +02:00
const withEmptyPermissions : IRoleValidation = {
name : 'name of the role' ,
description : 'description' ,
permissions : [ ] ,
} ;
expect ( await accessService . validateRole ( withEmptyPermissions ) ) . toEqual ( {
name : 'name of the role' ,
description : 'description' ,
permissions : [ ] ,
} ) ;
} ) ;
test ( 'should complete environment field of permissions when not present' , async ( ) = > {
2023-06-22 16:42:01 +02:00
const { accessService } = getSetup ( ) ;
2022-08-19 10:28:53 +02:00
const withoutEnvironmentInPermissions : IRoleValidation = {
name : 'name of the role' ,
description : 'description' ,
permissions : [
{
id : 1 ,
} ,
] ,
} ;
expect (
await accessService . validateRole ( withoutEnvironmentInPermissions ) ,
) . toEqual ( {
name : 'name of the role' ,
description : 'description' ,
permissions : [
{
id : 1 ,
environment : '' ,
} ,
] ,
} ) ;
} ) ;
test ( 'should return the same object when all fields are valid and present' , async ( ) = > {
2023-06-22 16:42:01 +02:00
const { accessService } = getSetup ( ) ;
2022-08-19 10:28:53 +02:00
const roleWithAllFields : IRoleValidation = {
name : 'name of the role' ,
description : 'description' ,
permissions : [
{
id : 1 ,
environment : 'development' ,
} ,
] ,
} ;
expect ( await accessService . validateRole ( roleWithAllFields ) ) . toEqual ( {
name : 'name of the role' ,
description : 'description' ,
permissions : [
{
id : 1 ,
environment : 'development' ,
} ,
] ,
} ) ;
} ) ;
test ( 'should be able to validate and cleanup with additional properties' , async ( ) = > {
2023-06-22 16:42:01 +02:00
const { accessService } = getSetup ( ) ;
2022-08-19 10:28:53 +02:00
const base = {
name : 'name of the role' ,
description : 'description' ,
additional : 'property' ,
permissions : [
{
id : 1 ,
environment : 'development' ,
name : 'name' ,
displayName : 'displayName' ,
type : 'type' ,
additional : 'property' ,
} ,
] ,
} ;
expect ( await accessService . validateRole ( base ) ) . toEqual ( {
name : 'name of the role' ,
description : 'description' ,
permissions : [
{
id : 1 ,
2023-09-19 16:15:27 +02:00
name : 'name' ,
2022-08-19 10:28:53 +02:00
environment : 'development' ,
} ,
] ,
} ) ;
} ) ;
2023-06-22 16:42:01 +02:00
test ( 'user with custom root role should get a user root role' , async ( ) = > {
2023-08-10 14:11:55 +02:00
const { accessService } = getSetup ( false ) ;
2023-06-22 16:42:01 +02:00
const customRootRole = await accessService . createRole ( {
name : 'custom-root-role' ,
description : 'test custom root role' ,
type : CUSTOM_ROOT_ROLE_TYPE ,
permissions : [ ] ,
} ) ;
const user = {
id : 1 ,
rootRole : customRootRole.id ,
} ;
await accessService . setUserRootRole ( user . id , customRootRole . id ) ;
const roles = await accessService . getUserRootRoles ( user . id ) ;
expect ( roles ) . toHaveLength ( 1 ) ;
expect ( roles [ 0 ] . name ) . toBe ( 'custom-root-role' ) ;
} ) ;
2023-08-08 13:45:19 +02:00
test ( 'throws error when trying to delete a project role in use by group' , async ( ) = > {
const groupIdResultOverride = async ( ) : Promise < number [ ] > = > {
return [ 1 ] ;
} ;
const config = createTestConfig ( {
getLogger ,
} ) ;
const eventStore = new FakeEventStore ( ) ;
const groupStore = new FakeGroupStore ( ) ;
groupStore . getAllWithId = async ( ) : Promise < IGroup [ ] > = > {
2023-09-05 21:30:20 +02:00
return [ { id : 1 , name : 'group' } ] ;
2023-08-08 13:45:19 +02:00
} ;
const accountStore = new FakeAccountStore ( ) ;
const roleStore = new FakeRoleStore ( ) ;
const environmentStore = new FakeEnvironmentStore ( ) ;
const accessStore = new AccessStoreMock ( ) ;
accessStore . getGroupIdsForRole = groupIdResultOverride ;
accessStore . getUserIdsForRole = async ( ) : Promise < number [ ] > = > {
return [ ] ;
} ;
accessStore . get = async ( ) : Promise < IRole > = > {
return { id : 1 , type : 'custom' , name : 'project role' } ;
} ;
const groupService = new GroupService (
{ groupStore , eventStore , accountStore } ,
{ getLogger } ,
) ;
const accessService = new AccessService (
{
accessStore ,
accountStore ,
roleStore ,
environmentStore ,
groupStore ,
} ,
config ,
groupService ,
) ;
try {
await accessService . deleteRole ( 1 ) ;
} catch ( e ) {
expect ( e . toString ( ) ) . toBe (
'RoleInUseError: Role is in use by users(0) or groups(1). You cannot delete a role that is in use without first removing the role from the users and groups.' ,
) ;
}
} ) ;