From e333c6ee2eec37e69c0a07967917ee56158b1bae Mon Sep 17 00:00:00 2001 From: Antonio Date: Wed, 29 Nov 2023 08:56:30 +0100 Subject: [PATCH] [Cases] Suggest user profiles with read permission (#172047) Fixes #171446 ## Summary We will now also suggest users with only `Read Cases` permissions for case assignment. ## Release notes Fixed a bug that prevented users with read permission from being assigned to cases. --- .../server/services/user_profiles/index.ts | 4 +- .../tests/trial/cases/find_cases.ts | 5 +- .../trial/internal/suggest_user_profiles.ts | 61 +++++++++++++------ 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/x-pack/plugins/cases/server/services/user_profiles/index.ts b/x-pack/plugins/cases/server/services/user_profiles/index.ts index ab8a9d8cf7d5b..7808cf74b0112 100644 --- a/x-pack/plugins/cases/server/services/user_profiles/index.ts +++ b/x-pack/plugins/cases/server/services/user_profiles/index.ts @@ -151,9 +151,7 @@ export class UserProfileService { private static buildRequiredPrivileges(owners: string[], security: SecurityPluginStart) { const privileges: string[] = []; for (const owner of owners) { - for (const operation of [Operations.updateCase.name, Operations.getCase.name]) { - privileges.push(security.authz.actions.cases.get(owner, operation)); - } + privileges.push(security.authz.actions.cases.get(owner, Operations.getCase.name)); } return privileges; diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/find_cases.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/find_cases.ts index a8bfb21c253ca..34a77e1083c43 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/find_cases.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/cases/find_cases.ts @@ -7,7 +7,6 @@ import expect from '@kbn/expect'; import { Cookie } from 'tough-cookie'; -import { User } from '@kbn/cases-plugin/common/types/domain'; import { UserProfile } from '@kbn/security-plugin/common'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; @@ -20,7 +19,6 @@ import { loginUsers, } from '../../../../common/lib/api'; import { secOnlySpacesAll, superUser } from '../../../../common/lib/authentication/users'; -import { getUserInfo } from '../../../../common/lib/authentication'; import { createUsersAndRoles, deleteUsersAndRoles } from '../../../../common/lib/authentication'; import { securitySolutionOnlyAllSpacesRole } from '../../../../common/lib/authentication/roles'; @@ -31,7 +29,6 @@ export default ({ getService }: FtrProviderContext): void => { const supertestWithoutAuth = getService('supertestWithoutAuth'); describe('find_cases', () => { - const secOnlyInfo: User = getUserInfo(secOnlySpacesAll); let cookies: Cookie[]; let suggestedSecUsers: UserProfile[]; let superUserHeaders: { Cookie: string }; @@ -62,7 +59,7 @@ export default ({ getService }: FtrProviderContext): void => { suggestedSecUsers = await suggestUserProfiles({ supertest: supertestWithoutAuth, req: { - name: secOnlyInfo.username!, + name: 'all_spaces', owners: ['securitySolutionFixture'], size: 1, }, diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/internal/suggest_user_profiles.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/internal/suggest_user_profiles.ts index db3f529863f01..e8e7023c06937 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/internal/suggest_user_profiles.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/trial/internal/suggest_user_profiles.ts @@ -58,6 +58,30 @@ export default function ({ getService }: FtrProviderContext) { `); }); + it('find a user who only has read privilege for cases', async () => { + const profiles = await suggestUserProfiles({ + supertest: supertestWithoutAuth, + req: { + name: 'read', + owners: ['securitySolutionFixture'], + }, + auth: { user: superUser, space: 'space1' }, + }); + + expectSnapshot(profiles.map(({ user, data }) => ({ user, data }))).toMatchInline(` + Array [ + Object { + "data": Object {}, + "user": Object { + "email": "sec_only_read@elastic.co", + "full_name": "sec only_read", + "username": "sec_only_read", + }, + }, + ] + `); + }); + it('does not find a user who does not have access to the default space', async () => { const profiles = await suggestUserProfiles({ supertest: supertestWithoutAuth, @@ -85,6 +109,14 @@ export default function ({ getService }: FtrProviderContext) { expect(profiles.filter(({ user }) => user.username === obsOnly.username)).to.be.empty(); expectSnapshot(profiles.map(({ user, data }) => ({ user, data }))).toMatchInline(` Array [ + Object { + "data": Object {}, + "user": Object { + "email": "sec_only_read@elastic.co", + "full_name": "sec only_read", + "username": "sec_only_read", + }, + }, Object { "data": Object {}, "user": Object { @@ -105,19 +137,6 @@ export default function ({ getService }: FtrProviderContext) { `); }); - it('does not find a user who does not have update privileges to cases', async () => { - const profiles = await suggestUserProfiles({ - supertest: supertestWithoutAuth, - req: { - name: 'read', - owners: ['securitySolutionFixture'], - }, - auth: { user: superUser, space: 'space1' }, - }); - - expect(profiles).to.be.empty(); - }); - it('fails with a 403 because the user making the request does not have the appropriate api kibana endpoint privileges', async () => { await suggestUserProfiles({ supertest: supertestWithoutAuth, @@ -186,9 +205,9 @@ export default function ({ getService }: FtrProviderContext) { Object { "data": Object {}, "user": Object { - "email": "sec_only_no_delete@elastic.co", - "full_name": "sec only_no_delete", - "username": "sec_only_no_delete", + "email": "sec_only_read@elastic.co", + "full_name": "sec only_read", + "username": "sec_only_read", }, }, ] @@ -242,7 +261,7 @@ export default function ({ getService }: FtrProviderContext) { await deleteUsersAndRoles(getService, users, roles); }); - it('finds 3 profiles when searching for the name sec when a user has both security and observability privileges', async () => { + it('finds 4 profiles when searching for the name sec when a user has both security and observability privileges', async () => { const profiles = await suggestUserProfiles({ supertest: supertestWithoutAuth, req: { @@ -254,6 +273,14 @@ export default function ({ getService }: FtrProviderContext) { expectSnapshot(profiles.map(({ user, data }) => ({ user, data }))).toMatchInline(` Array [ + Object { + "data": Object {}, + "user": Object { + "email": "sec_only_read@elastic.co", + "full_name": "sec only_read", + "username": "sec_only_read", + }, + }, Object { "data": Object {}, "user": Object {