diff --git a/x-pack/plugins/cases/kibana.jsonc b/x-pack/plugins/cases/kibana.jsonc index 0bda577c93623..1f474ccf8e9d4 100644 --- a/x-pack/plugins/cases/kibana.jsonc +++ b/x-pack/plugins/cases/kibana.jsonc @@ -23,14 +23,14 @@ "kibanaUtils", "triggersActionsUi", "management", - "spaces", "security", "notifications" ], "optionalPlugins": [ "home", "taskManager", - "usageCollection" + "usageCollection", + "spaces" ], "requiredBundles": [ "savedObjects" diff --git a/x-pack/plugins/cases/server/authorization/authorization.test.ts b/x-pack/plugins/cases/server/authorization/authorization.test.ts index 0945555689fbf..d02b8f011cf75 100644 --- a/x-pack/plugins/cases/server/authorization/authorization.test.ts +++ b/x-pack/plugins/cases/server/authorization/authorization.test.ts @@ -69,6 +69,38 @@ describe('authorization', () => { await expect(authPromise).resolves.not.toThrow(); }); + it('creates an Authorization object without spaces', async () => { + expect.assertions(2); + + const authPromise = Authorization.create({ + request, + securityAuth: securityStart.authz, + features: featuresStart, + auditLogger: new AuthorizationAuditLogger(mockLogger), + logger: loggingSystemMock.createLogger(), + }); + + await expect(authPromise).resolves.toBeDefined(); + await expect(authPromise).resolves.not.toThrow(); + }); + + it('if spaces are disabled it does not filtered out disabled features', async () => { + (spacesStart.spacesService.getActiveSpace as jest.Mock).mockImplementation(() => { + return { disabledFeatures: ['1'] } as Space; + }); + + const auth = await Authorization.create({ + request, + securityAuth: securityStart.authz, + features: featuresStart, + auditLogger: new AuthorizationAuditLogger(mockLogger), + logger: loggingSystemMock.createLogger(), + }); + + // @ts-expect-error: featureCaseOwners is a private method of the auth class + expect([...auth.featureCaseOwners.values()]).toEqual(['a']); + }); + it('throws and error when a failure occurs', async () => { expect.assertions(1); diff --git a/x-pack/plugins/cases/server/authorization/authorization.ts b/x-pack/plugins/cases/server/authorization/authorization.ts index 14ecaa6111f8c..e3dc970b38182 100644 --- a/x-pack/plugins/cases/server/authorization/authorization.ts +++ b/x-pack/plugins/cases/server/authorization/authorization.ts @@ -57,19 +57,21 @@ export class Authorization { }: { request: KibanaRequest; securityAuth?: SecurityPluginStart['authz']; - spaces: SpacesPluginStart; + spaces?: SpacesPluginStart; features: FeaturesPluginStart; auditLogger: AuthorizationAuditLogger; logger: Logger; }): Promise { - const getSpace = async (): Promise => { - return spaces.spacesService.getActiveSpace(request); + const getSpace = async (): Promise => { + return spaces?.spacesService.getActiveSpace(request); }; // Since we need to do async operations, this static method handles that before creating the Auth class let caseOwners: Set; + try { - const disabledFeatures = new Set((await getSpace()).disabledFeatures ?? []); + const maybeSpace = await getSpace(); + const disabledFeatures = new Set(maybeSpace?.disabledFeatures ?? []); caseOwners = new Set( features diff --git a/x-pack/plugins/cases/server/client/factory.ts b/x-pack/plugins/cases/server/client/factory.ts index b214b40e34701..c12ce99910ac7 100644 --- a/x-pack/plugins/cases/server/client/factory.ts +++ b/x-pack/plugins/cases/server/client/factory.ts @@ -26,6 +26,7 @@ import type { LensServerPluginSetup } from '@kbn/lens-plugin/server'; import type { SpacesPluginStart } from '@kbn/spaces-plugin/server'; import type { LicensingPluginStart } from '@kbn/licensing-plugin/server'; import type { NotificationsPluginStart } from '@kbn/notifications-plugin/server'; +import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import { SAVED_OBJECT_TYPES } from '../../common/constants'; import { Authorization } from '../authorization/authorization'; import { @@ -49,7 +50,7 @@ import { EmailNotificationService } from '../services/notifications/email_notifi interface CasesClientFactoryArgs { securityPluginSetup: SecurityPluginSetup; securityPluginStart: SecurityPluginStart; - spacesPluginStart: SpacesPluginStart; + spacesPluginStart?: SpacesPluginStart; featuresPluginStart: FeaturesPluginStart; actionsPluginStart: ActionsPluginStart; licensingPluginStart: LicensingPluginStart; @@ -144,7 +145,8 @@ export class CasesClientFactory { externalReferenceAttachmentTypeRegistry: this.options.externalReferenceAttachmentTypeRegistry, securityStartPlugin: this.options.securityPluginStart, publicBaseUrl: this.options.publicBaseUrl, - spaceId: this.options.spacesPluginStart.spacesService.getSpaceId(request), + spaceId: + this.options.spacesPluginStart?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID, savedObjectsSerializer, }); } @@ -197,7 +199,8 @@ export class CasesClientFactory { notifications: this.options.notifications, security: this.options.securityPluginStart, publicBaseUrl: this.options.publicBaseUrl, - spaceId: this.options.spacesPluginStart.spacesService.getSpaceId(request), + spaceId: + this.options.spacesPluginStart?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID, }); return { diff --git a/x-pack/plugins/cases/server/plugin.ts b/x-pack/plugins/cases/server/plugin.ts index ac26cfc7b81a0..bf9033a33552f 100644 --- a/x-pack/plugins/cases/server/plugin.ts +++ b/x-pack/plugins/cases/server/plugin.ts @@ -72,7 +72,7 @@ export interface PluginsStart { licensing: LicensingPluginStart; taskManager?: TaskManagerStartContract; security: SecurityPluginStart; - spaces: SpacesPluginStart; + spaces?: SpacesPluginStart; notifications: NotificationsPluginStart; } 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 937e7449f89c7..2113c116e2787 100644 --- a/x-pack/plugins/cases/server/services/user_profiles/index.ts +++ b/x-pack/plugins/cases/server/services/user_profiles/index.ts @@ -14,6 +14,7 @@ import type { KibanaRequest, Logger } from '@kbn/core/server'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; import type { UserProfile } from '@kbn/security-plugin/common'; import type { SpacesPluginStart } from '@kbn/spaces-plugin/server'; +import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common'; import type { LicensingPluginStart } from '@kbn/licensing-plugin/server'; import { excess, SuggestUserProfilesRequestRt, throwErrors } from '../../../common/api'; @@ -28,7 +29,7 @@ const MIN_PROFILES_SIZE = 0; interface UserProfileOptions { securityPluginSetup: SecurityPluginSetup; securityPluginStart: SecurityPluginStart; - spaces: SpacesPluginStart; + spaces?: SpacesPluginStart; licensingPluginStart: LicensingPluginStart; } @@ -110,7 +111,7 @@ export class UserProfileService { size, owners, securityPluginStart: this.options.securityPluginStart, - spaceId: spaces.spacesService.getSpaceId(request), + spaceId: spaces?.spacesService.getSpaceId(request) ?? DEFAULT_SPACE_ID, }); } catch (error) { throw createCaseError({