From 308c410f158659efaee45bda552f44d13452f755 Mon Sep 17 00:00:00 2001 From: SuZhou-Joe Date: Tue, 27 Feb 2024 18:35:54 +0800 Subject: [PATCH] feat: add workspace into includeHiddenTypes (#249) * feat: add workspace into includeHiddenTypes of client wrapper and permission control client Signed-off-by: SuZhou-Joe * fix: hiddenType side effect Signed-off-by: SuZhou-Joe --------- Signed-off-by: SuZhou-Joe --- .../server/permission_control/client.ts | 6 +++++- src/plugins/workspace/server/plugin.ts | 6 ++++-- .../workspace_saved_objects_client_wrapper.ts | 21 ++++++++++++++++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/plugins/workspace/server/permission_control/client.ts b/src/plugins/workspace/server/permission_control/client.ts index 137016721a60..8c9a0e554e31 100644 --- a/src/plugins/workspace/server/permission_control/client.ts +++ b/src/plugins/workspace/server/permission_control/client.ts @@ -4,13 +4,16 @@ */ import { i18n } from '@osd/i18n'; -import { OpenSearchDashboardsRequest, Principals, SavedObject } from '../../../../core/server'; import { ACL, TransformedPermission, SavedObjectsBulkGetObject, SavedObjectsServiceStart, Logger, + OpenSearchDashboardsRequest, + Principals, + SavedObject, + WORKSPACE_TYPE, } from '../../../../core/server'; import { WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID } from '../../common/constants'; import { getPrincipalsFromRequest } from '../utils'; @@ -28,6 +31,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 dda876cb2215..3583d4787e6d 100644 --- a/src/plugins/workspace/server/plugin.ts +++ b/src/plugins/workspace/server/plugin.ts @@ -29,6 +29,7 @@ export class WorkspacePlugin implements Plugin<{}, {}> { private client?: IWorkspaceClientImpl; private permissionControl?: SavedObjectsPermissionControlContract; private readonly config$: Observable; + private workspaceSavedObjectsClientWrapper?: WorkspaceSavedObjectsClientWrapper; private proxyWorkspaceTrafficToRealHandler(setupDeps: CoreSetup) { /** @@ -66,14 +67,14 @@ export class WorkspacePlugin implements Plugin<{}, {}> { this.proxyWorkspaceTrafficToRealHandler(core); this.permissionControl = new SavedObjectsPermissionControl(this.logger); - 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 ); } @@ -99,6 +100,7 @@ export class WorkspacePlugin implements Plugin<{}, {}> { this.logger.debug('Starting Workspace 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 3cebc7b85f80..a80b4edcc30a 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 @@ -26,9 +26,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 = () => @@ -50,6 +53,7 @@ const generateSavedObjectsPermissionError = () => ); export class WorkspaceSavedObjectsClientWrapper { + private getScopedClient?: SavedObjectsServiceStart['getScopedClient']; private formatWorkspacePermissionModeToStringArray( permission: WorkspacePermissionMode | WorkspacePermissionMode[] ): string[] { @@ -173,6 +177,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, @@ -396,8 +411,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: {