diff --git a/src/plugins/workspace/server/permission_control/client.ts b/src/plugins/workspace/server/permission_control/client.ts index 7ba4a4f454be..b141ec2e7313 100644 --- a/src/plugins/workspace/server/permission_control/client.ts +++ b/src/plugins/workspace/server/permission_control/client.ts @@ -3,7 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ import { i18n } from '@osd/i18n'; -import { OpenSearchDashboardsRequest, Principals, SavedObject } from '../../../../core/server'; +import { + OpenSearchDashboardsRequest, + Principals, + SavedObject, + WORKSPACE_TYPE, +} from '../../../../core/server'; import { ACL, TransformedPermission, @@ -27,6 +32,7 @@ export class SavedObjectsPermissionControl { private getScopedClient(request: OpenSearchDashboardsRequest) { return this._getScopedClient?.(request, { excludedWrappers: [WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID], + includedHiddenTypes: [WORKSPACE_TYPE], }); } diff --git a/src/plugins/workspace/server/plugin.ts b/src/plugins/workspace/server/plugin.ts index edf785b4a322..12c101cae6bb 100644 --- a/src/plugins/workspace/server/plugin.ts +++ b/src/plugins/workspace/server/plugin.ts @@ -11,6 +11,7 @@ import { Plugin, Logger, SavedObjectsClient, + WORKSPACE_TYPE, } from '../../../core/server'; import { IWorkspaceClientImpl } from './types'; import { WorkspaceClientWithSavedObject } from './workspace_client'; @@ -30,6 +31,7 @@ export class WorkspacePlugin implements Plugin<{}, {}> { private client?: IWorkspaceClientImpl; private permissionControl?: SavedObjectsPermissionControlContract; private readonly config$: Observable; + private workspaceSavedObjectsClientWrapper?: WorkspaceSavedObjectsClientWrapper; private proxyWorkspaceTrafficToRealHandler(setupDeps: CoreSetup) { /** @@ -71,14 +73,14 @@ export class WorkspacePlugin implements Plugin<{}, {}> { permissionControl: this.permissionControl, }); - const workspaceSavedObjectsClientWrapper = new WorkspaceSavedObjectsClientWrapper( + this.workspaceSavedObjectsClientWrapper = new WorkspaceSavedObjectsClientWrapper( this.permissionControl ); core.savedObjects.addClientWrapper( 0, WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID, - workspaceSavedObjectsClientWrapper.wrapperFactory + this.workspaceSavedObjectsClientWrapper.wrapperFactory ); } @@ -111,6 +113,7 @@ export class WorkspacePlugin implements Plugin<{}, {}> { this.logger.debug('Starting SavedObjects service'); this.permissionControl?.setup(core.savedObjects.getScopedClient); this.client?.setSavedObjects(core.savedObjects); + this.workspaceSavedObjectsClientWrapper?.setScopedClient(core.savedObjects.getScopedClient); return { client: this.client as IWorkspaceClientImpl, diff --git a/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.ts b/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.ts index e34e6b9bb607..41a4c7ee7407 100644 --- a/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.ts +++ b/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.ts @@ -28,9 +28,12 @@ import { WorkspacePermissionMode, SavedObjectsDeleteByWorkspaceOptions, SavedObjectsErrorHelpers, + SavedObjectsServiceStart, + SavedObjectsClientContract, } from '../../../../core/server'; import { SavedObjectsPermissionControlContract } from '../permission_control/client'; import { getPrincipalsFromRequest } from '../utils'; +import { WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID } from '../../common/constants'; // Can't throw unauthorized for now, the page will be refreshed if unauthorized const generateWorkspacePermissionError = () => @@ -52,6 +55,7 @@ const generateSavedObjectsPermissionError = () => ); export class WorkspaceSavedObjectsClientWrapper { + private getScopedClient?: SavedObjectsServiceStart['getScopedClient']; private formatWorkspacePermissionModeToStringArray( permission: WorkspacePermissionMode | WorkspacePermissionMode[] ): string[] { @@ -175,6 +179,17 @@ export class WorkspaceSavedObjectsClientWrapper { return hasPermission; } + private getWorkspaceTypeEnabledClient(request: OpenSearchDashboardsRequest) { + return this.getScopedClient?.(request, { + includedHiddenTypes: [WORKSPACE_TYPE], + excludedWrappers: [WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID], + }) as SavedObjectsClientContract; + } + + public setScopedClient(getScopedClient: SavedObjectsServiceStart['getScopedClient']) { + this.getScopedClient = getScopedClient; + } + public wrapperFactory: SavedObjectsClientWrapperFactory = (wrapperOptions) => { const deleteWithWorkspacePermissionControl = async ( type: string, @@ -398,8 +413,12 @@ export class WorkspaceSavedObjectsClientWrapper { ]; options.ACLSearchParams.principals = principals; } else { + /** + * Workspace is a hidden type so that we need to + * initialize a new saved objects client with workspace enabled to retrieve all the workspaces with permission. + */ const permittedWorkspaceIds = ( - await wrapperOptions.client.find({ + await this.getWorkspaceTypeEnabledClient(wrapperOptions.request).find({ type: WORKSPACE_TYPE, perPage: 999, ACLSearchParams: {