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-11-24 14:22:31 +01:00
import {
AccessService ,
IRoleCreation ,
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' ;
2023-11-24 14:22:31 +01:00
import { IRole } from '../../lib/types/stores/access-store' ;
import { IGroup , ROLE_CREATED } from '../../lib/types' ;
2023-09-27 15:23:05 +02:00
import EventService from './event-service' ;
import FakeFeatureTagStore from '../../test/fixtures/fake-feature-tag-store' ;
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
} ) ;
2023-11-24 14:22:31 +01:00
return 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-11-24 14:22:31 +01:00
const { accessService , eventStore } = getSetup ( false ) ;
const createRoleInput : IRoleCreation = {
2023-06-22 16:42:01 +02:00
name : 'custom-root-role' ,
description : 'test custom root role' ,
type : CUSTOM_ROOT_ROLE_TYPE ,
2023-11-24 14:22:31 +01:00
permissions : [
{
id : 1 ,
environment : 'development' ,
name : 'fake' ,
} ,
{
name : 'root-fake-permission' ,
} ,
] ,
} ;
const customRootRole = await accessService . createRole ( createRoleInput ) ;
2023-06-22 16:42:01 +02:00
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-11-24 14:22:31 +01:00
const events = await eventStore . getEvents ( ) ;
expect ( events ) . toHaveLength ( 1 ) ;
expect ( events [ 0 ] ) . toEqual ( {
type : ROLE_CREATED ,
createdBy : 'unknown' ,
data : {
id : 0 ,
name : 'custom-root-role' ,
description : 'test custom root role' ,
type : CUSTOM_ROOT_ROLE_TYPE ,
// make sure we have a cleaned up version of permissions in the event
permissions : [
{ environment : 'development' , name : 'fake' } ,
{ name : 'root-fake-permission' } ,
] ,
} ,
} ) ;
2023-06-22 16:42:01 +02:00
} ) ;
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' } ;
} ;
2023-09-27 15:23:05 +02:00
const eventService = new EventService (
{ eventStore , featureTagStore : new FakeFeatureTagStore ( ) } ,
config ,
) ;
2023-08-08 13:45:19 +02:00
const groupService = new GroupService (
2023-09-27 15:23:05 +02:00
{ groupStore , accountStore } ,
2023-08-08 13:45:19 +02:00
{ getLogger } ,
2023-09-27 15:23:05 +02:00
eventService ,
2023-08-08 13:45:19 +02:00
) ;
const accessService = new AccessService (
{
accessStore ,
accountStore ,
roleStore ,
environmentStore ,
} ,
config ,
groupService ,
2023-11-24 14:22:31 +01:00
eventService ,
2023-08-08 13:45:19 +02:00
) ;
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.' ,
) ;
}
} ) ;