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 69147e888aee..f73e93afd680 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 5bb04c1da9e8..865ee2ff3b68 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 3de350f5a398..74d3c3de46fa 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 2c3f1f10ad25..48ed1722149e 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 e17eb2f22f7b..22c93f8919a2 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 6a7be7deac4e..7bc57a96105f 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,