From 4eb07b101e74006672c302af7568159ed5bb2286 Mon Sep 17 00:00:00 2001 From: "Christiane (Tina) Heiligers" Date: Sun, 30 Jun 2024 14:51:06 -0700 Subject: [PATCH] Migrate authc dependency from security plugin to core security service (#187124) ## Summary Part of https://github.com/elastic/kibana/issues/186574 Background: This PR is an example of a plugin migrating away from depending on the Security plugin, which is a high-priority effort for the last release before 9.0. The Cases plugin uses authc.getCurrentUser from the security plugin's start contract on the server side. This PR migrates authc.getCurrentUser from the security plugin start contract to the core security service. Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/cases/server/client/factory.test.ts | 10 +++++----- x-pack/plugins/cases/server/client/factory.ts | 5 ++++- x-pack/plugins/cases/server/client/mocks.ts | 7 ++++++- x-pack/plugins/cases/server/plugin.ts | 1 + .../notifications/email_notification_service.ts | 2 +- .../cases/server/services/user_profiles/index.ts | 3 ++- 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/cases/server/client/factory.test.ts b/x-pack/plugins/cases/server/client/factory.test.ts index 69147e888aeec..f73e93afd680c 100644 --- a/x-pack/plugins/cases/server/client/factory.test.ts +++ b/x-pack/plugins/cases/server/client/factory.test.ts @@ -52,7 +52,7 @@ describe('CasesClientFactory', () => { }); expect(args.securityPluginStart.userProfiles.getCurrent).toHaveBeenCalled(); - expect(args.securityPluginStart.authc.getCurrentUser).not.toHaveBeenCalled(); + expect(args.securityServiceStart.authc.getCurrentUser).not.toHaveBeenCalled(); expect(createCasesClientMocked.mock.calls[0][0].user).toEqual({ username: 'my_user', full_name: 'My user', @@ -63,7 +63,7 @@ describe('CasesClientFactory', () => { it('constructs the user info from the authc service if the user profile is not available', async () => { const scopedClusterClient = coreStart.elasticsearch.client.asScoped(request).asCurrentUser; // @ts-expect-error: not all fields are needed - args.securityPluginStart.authc.getCurrentUser.mockReturnValueOnce({ + args.securityServiceStart.authc.getCurrentUser.mockReturnValueOnce({ username: 'my_user_2', full_name: 'My user 2', email: 'elastic2@elastic.co', @@ -76,7 +76,7 @@ describe('CasesClientFactory', () => { }); expect(args.securityPluginStart.userProfiles.getCurrent).toHaveBeenCalled(); - expect(args.securityPluginStart.authc.getCurrentUser).toHaveBeenCalled(); + expect(args.securityServiceStart.authc.getCurrentUser).toHaveBeenCalled(); expect(createCasesClientMocked.mock.calls[0][0].user).toEqual({ username: 'my_user_2', full_name: 'My user 2', @@ -95,7 +95,7 @@ describe('CasesClientFactory', () => { }); expect(args.securityPluginStart.userProfiles.getCurrent).toHaveBeenCalled(); - expect(args.securityPluginStart.authc.getCurrentUser).toHaveBeenCalled(); + expect(args.securityServiceStart.authc.getCurrentUser).toHaveBeenCalled(); expect(createCasesClientMocked.mock.calls[0][0].user).toEqual({ username: 'elastic/kibana', full_name: null, @@ -113,7 +113,7 @@ describe('CasesClientFactory', () => { }); expect(args.securityPluginStart.userProfiles.getCurrent).toHaveBeenCalled(); - expect(args.securityPluginStart.authc.getCurrentUser).toHaveBeenCalled(); + expect(args.securityServiceStart.authc.getCurrentUser).toHaveBeenCalled(); expect(createCasesClientMocked.mock.calls[0][0].user).toEqual({ username: null, full_name: null, diff --git a/x-pack/plugins/cases/server/client/factory.ts b/x-pack/plugins/cases/server/client/factory.ts index 5bb04c1da9e86..865ee2ff3b684 100644 --- a/x-pack/plugins/cases/server/client/factory.ts +++ b/x-pack/plugins/cases/server/client/factory.ts @@ -12,6 +12,7 @@ import type { ElasticsearchClient, SavedObjectsClientContract, IBasePath, + SecurityServiceStart, } from '@kbn/core/server'; import type { ISavedObjectsSerializer } from '@kbn/core-saved-objects-server'; import { SECURITY_EXTENSION_ID } from '@kbn/core-saved-objects-server'; @@ -57,6 +58,7 @@ import { EmailNotificationService } from '../services/notifications/email_notifi interface CasesClientFactoryArgs { securityPluginSetup: SecurityPluginSetup; securityPluginStart: SecurityPluginStart; + securityServiceStart: SecurityServiceStart; spacesPluginStart?: SpacesPluginStart; featuresPluginStart: FeaturesPluginStart; actionsPluginStart: ActionsPluginStart; @@ -257,6 +259,7 @@ export class CasesClientFactory { try { const userProfile = await this.options.securityPluginStart.userProfiles.getCurrent({ + // todo: Access userProfiles from core's UserProfileService contract request, }); @@ -273,7 +276,7 @@ export class CasesClientFactory { } try { - const user = this.options.securityPluginStart.authc.getCurrentUser(request); + const user = this.options.securityServiceStart.authc.getCurrentUser(request); if (user != null) { return { diff --git a/x-pack/plugins/cases/server/client/mocks.ts b/x-pack/plugins/cases/server/client/mocks.ts index 3de350f5a3981..74d3c3de46fa0 100644 --- a/x-pack/plugins/cases/server/client/mocks.ts +++ b/x-pack/plugins/cases/server/client/mocks.ts @@ -6,7 +6,11 @@ */ import type { PublicContract, PublicMethodsOf } from '@kbn/utility-types'; -import { loggingSystemMock, savedObjectsClientMock } from '@kbn/core/server/mocks'; +import { + loggingSystemMock, + savedObjectsClientMock, + securityServiceMock, +} from '@kbn/core/server/mocks'; import type { ISavedObjectsSerializer } from '@kbn/core-saved-objects-server'; import { @@ -226,6 +230,7 @@ export const createCasesClientFactoryMockArgs = () => { return { securityPluginSetup: securityMock.createSetup(), securityPluginStart: securityMock.createStart(), + securityServiceStart: securityServiceMock.createStart(), spacesPluginStart: spacesMock.createStart(), featuresPluginStart: featuresPluginMock.createSetup(), actionsPluginStart: actionsMock.createStart(), diff --git a/x-pack/plugins/cases/server/plugin.ts b/x-pack/plugins/cases/server/plugin.ts index 2c3f1f10ad254..48ed1722149ed 100644 --- a/x-pack/plugins/cases/server/plugin.ts +++ b/x-pack/plugins/cases/server/plugin.ts @@ -186,6 +186,7 @@ export class CasePlugin // eslint-disable-next-line @typescript-eslint/no-non-null-assertion securityPluginSetup: this.securityPluginSetup!, securityPluginStart: plugins.security, + securityServiceStart: core.security, spacesPluginStart: plugins.spaces, featuresPluginStart: plugins.features, actionsPluginStart: plugins.actions, diff --git a/x-pack/plugins/cases/server/services/notifications/email_notification_service.ts b/x-pack/plugins/cases/server/services/notifications/email_notification_service.ts index e17eb2f22f7bc..22c93f8919a2a 100644 --- a/x-pack/plugins/cases/server/services/notifications/email_notification_service.ts +++ b/x-pack/plugins/cases/server/services/notifications/email_notification_service.ts @@ -100,7 +100,7 @@ export class EmailNotificationService implements NotificationService { ); const uids = new Set(assignees.map((assignee) => assignee.uid)); - const userProfiles = await this.security.userProfiles.bulkGet({ uids }); + const userProfiles = await this.security.userProfiles.bulkGet({ uids }); // todo: access userProfiles from core security service start contract const users = userProfiles.map((profile) => profile.user); const to = users 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 6a7be7deac4eb..7bc57a96105f5 100644 --- a/x-pack/plugins/cases/server/services/user_profiles/index.ts +++ b/x-pack/plugins/cases/server/services/user_profiles/index.ts @@ -27,7 +27,7 @@ const MIN_PROFILES_SIZE = 0; interface UserProfileOptions { securityPluginSetup: SecurityPluginSetup; - securityPluginStart: SecurityPluginStart; + securityPluginStart: SecurityPluginStart; // TODO: Use core's UserProfileService spaces?: SpacesPluginStart; licensingPluginStart: LicensingPluginStart; } @@ -58,6 +58,7 @@ export class UserProfileService { size?: number; owners: string[]; }) { + // TODO: Use core's UserProfileService return securityPluginStart.userProfiles.suggest({ name: searchTerm, size,