From ffb4a0fc8bed13b814262e83659b766082f78d8a Mon Sep 17 00:00:00 2001 From: yubonluo Date: Fri, 24 May 2024 17:38:35 +0800 Subject: [PATCH 01/18] Only OSD admin can create workspace Signed-off-by: yubonluo --- src/plugins/workspace/server/plugin.ts | 2 +- .../workspace/server/workspace_client.ts | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/plugins/workspace/server/plugin.ts b/src/plugins/workspace/server/plugin.ts index 2ec8447ad817..0e4e7df60565 100644 --- a/src/plugins/workspace/server/plugin.ts +++ b/src/plugins/workspace/server/plugin.ts @@ -112,7 +112,7 @@ export class WorkspacePlugin implements Plugin> { this.setupDep.savedObjects.registerType(workspace); return { @@ -89,6 +104,7 @@ export class WorkspaceClient implements IWorkspaceClientImpl { payload: Omit ): ReturnType { try { + this.hasOSDAdminPermission(requestDetail); const { permissions, ...attributes } = payload; const id = generateRandomId(WORKSPACE_ID_SIZE); const client = this.getSavedObjectClientsFromRequestDetail(requestDetail); From 2ba437e58a3360e7e2c43d3978b62c480fbe22ba Mon Sep 17 00:00:00 2001 From: "opensearch-changeset-bot[bot]" <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> Date: Fri, 24 May 2024 09:47:28 +0000 Subject: [PATCH 02/18] Changeset file for PR #6831 created/updated --- changelogs/fragments/6831.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/6831.yml diff --git a/changelogs/fragments/6831.yml b/changelogs/fragments/6831.yml new file mode 100644 index 000000000000..123bf944a65d --- /dev/null +++ b/changelogs/fragments/6831.yml @@ -0,0 +1,2 @@ +feat: +- Only OSD admin can create workspace ([#6831](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6831)) \ No newline at end of file From ec1f413d6276396bbaadec4990d5e7ca2c3c56a2 Mon Sep 17 00:00:00 2001 From: "opensearch-changeset-bot[bot]" <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com> Date: Fri, 24 May 2024 09:54:53 +0000 Subject: [PATCH 03/18] Changeset file for PR #6831 created/updated --- changelogs/fragments/6831.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/6831.yml b/changelogs/fragments/6831.yml index 123bf944a65d..a7dc8210023b 100644 --- a/changelogs/fragments/6831.yml +++ b/changelogs/fragments/6831.yml @@ -1,2 +1,2 @@ feat: -- Only OSD admin can create workspace ([#6831](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6831)) \ No newline at end of file +- [Workspace] Only OSD admin can create workspace ([#6831](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6831)) \ No newline at end of file From 893b039f400a223636c17d7dc5b9e9438bfb9edb Mon Sep 17 00:00:00 2001 From: yubonluo Date: Mon, 27 May 2024 12:55:14 +0800 Subject: [PATCH 04/18] optimize the code Signed-off-by: yubonluo --- src/plugins/workspace/server/plugin.ts | 2 +- ...space_saved_objects_client_wrapper.test.ts | 25 +++++++++++++++++++ .../workspace_saved_objects_client_wrapper.ts | 17 +++++++++++++ .../workspace/server/workspace_client.ts | 19 ++------------ 4 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/plugins/workspace/server/plugin.ts b/src/plugins/workspace/server/plugin.ts index 0e4e7df60565..2ec8447ad817 100644 --- a/src/plugins/workspace/server/plugin.ts +++ b/src/plugins/workspace/server/plugin.ts @@ -112,7 +112,7 @@ export class WorkspacePlugin implements Plugin { workspaces: ['workspace-1'], }); }); + it('should throw permission error when user bulkCreate workspace and is not dashboard admin', async () => { + const { wrapper } = generateWorkspaceSavedObjectsClientWrapper(); + + const objectsToBulkCreate = [ + { type: 'workspace', id: 'w1', attributes: { bar: 'baz' } }, + { type: 'workspace', id: 'w2', attributes: { bar: 'foo' } }, + ]; + let errorCatched; + try { + await wrapper.bulkCreate(objectsToBulkCreate); + } catch (e) { + errorCatched = e; + } + expect(errorCatched?.message).toEqual('Invalid permission, please contact OSD admin'); + }); }); describe('create', () => { @@ -426,6 +441,16 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { } ); }); + it('should throw permission error when user create a workspace and is not dashboard admin', async () => { + const { wrapper } = generateWorkspaceSavedObjectsClientWrapper(); + let errorCatched; + try { + await wrapper.create('workspace', { name: 'test' }, {}); + } catch (e) { + errorCatched = e; + } + expect(errorCatched?.message).toEqual('Invalid permission, please contact OSD admin'); + }); }); describe('get', () => { it('should return saved object if no need to validate permission', async () => { 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 f97d423b3058..79294da70d51 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 @@ -33,6 +33,7 @@ import { WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID, WorkspacePermissionMode, } from '../../common/constants'; +import { isWorkspaceType } from '../utils'; // Can't throw unauthorized for now, the page will be refreshed if unauthorized const generateWorkspacePermissionError = () => @@ -53,6 +54,15 @@ const generateSavedObjectsPermissionError = () => ) ); +const generateOSDAdminPermissionError = () => + SavedObjectsErrorHelpers.decorateForbiddenError( + new Error( + i18n.translate('dashboard.admin.permission.invalidate', { + defaultMessage: 'Invalid permission, please contact OSD admin', + }) + ) + ); + const intersection = (...args: T[][]) => { const occursCountMap: { [key: string]: number } = {}; for (let i = 0; i < args.length; i++) { @@ -272,6 +282,10 @@ export class WorkspaceSavedObjectsClientWrapper { objects: Array>, options: SavedObjectsCreateOptions = {} ): Promise> => { + // Only OSD admin can bulkCreate workspace + if (this.isRelatedToWorkspace(objects.map((object) => object.type))) + throw generateOSDAdminPermissionError(); + const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; if ( @@ -330,6 +344,9 @@ export class WorkspaceSavedObjectsClientWrapper { attributes: T, options?: SavedObjectsCreateOptions ) => { + // Only OSD admin can create workspace + if (this.isRelatedToWorkspace(type)) throw generateOSDAdminPermissionError(); + const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; if ( diff --git a/src/plugins/workspace/server/workspace_client.ts b/src/plugins/workspace/server/workspace_client.ts index 2a9b4dacaa7e..1c5e30266f86 100644 --- a/src/plugins/workspace/server/workspace_client.ts +++ b/src/plugins/workspace/server/workspace_client.ts @@ -4,7 +4,6 @@ */ import { i18n } from '@osd/i18n'; -import { getWorkspaceState } from '../../../core/server/utils'; import { SavedObject, SavedObjectsClientContract, @@ -33,18 +32,12 @@ const DUPLICATE_WORKSPACE_NAME_ERROR = i18n.translate('workspace.duplicate.name. defaultMessage: 'workspace name has already been used, try with a different name', }); -const INVALID_PERMISSION_ERROR = i18n.translate('workspace.invalid.permission.error', { - defaultMessage: 'No permission to perform this operation, please contact OSD admin', -}); - export class WorkspaceClient implements IWorkspaceClientImpl { private setupDep: CoreSetup; private savedObjects?: SavedObjectsServiceStart; - private isPermissionControlEnabled: boolean; - constructor(core: CoreSetup, isPermissionControlEnabled: boolean) { + constructor(core: CoreSetup) { this.setupDep = core; - this.isPermissionControlEnabled = isPermissionControlEnabled; } private getScopedClientWithoutPermission( @@ -84,14 +77,7 @@ export class WorkspaceClient implements IWorkspaceClientImpl { private formatError(error: Error | any): string { return error.message || error.error || 'Error'; } - private hasOSDAdminPermission(requestDetail: IRequestDetail) { - if ( - this.isPermissionControlEnabled && - !getWorkspaceState(requestDetail.request).isDashboardAdmin - ) { - throw new Error(INVALID_PERMISSION_ERROR); - } - } + public async setup(core: CoreSetup): Promise> { this.setupDep.savedObjects.registerType(workspace); return { @@ -104,7 +90,6 @@ export class WorkspaceClient implements IWorkspaceClientImpl { payload: Omit ): ReturnType { try { - this.hasOSDAdminPermission(requestDetail); const { permissions, ...attributes } = payload; const id = generateRandomId(WORKSPACE_ID_SIZE); const client = this.getSavedObjectClientsFromRequestDetail(requestDetail); From 11f639643f74dddb4788c2170964541fe4512737 Mon Sep 17 00:00:00 2001 From: yubonluo Date: Mon, 27 May 2024 12:57:19 +0800 Subject: [PATCH 05/18] delete useless code Signed-off-by: yubonluo --- src/plugins/workspace/server/workspace_client.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/workspace/server/workspace_client.ts b/src/plugins/workspace/server/workspace_client.ts index 1c5e30266f86..a906e3548cab 100644 --- a/src/plugins/workspace/server/workspace_client.ts +++ b/src/plugins/workspace/server/workspace_client.ts @@ -77,7 +77,6 @@ export class WorkspaceClient implements IWorkspaceClientImpl { private formatError(error: Error | any): string { return error.message || error.error || 'Error'; } - public async setup(core: CoreSetup): Promise> { this.setupDep.savedObjects.registerType(workspace); return { From dec5cbe21b1749fca7ed5c636abbd0bfa453aaab Mon Sep 17 00:00:00 2001 From: yubonluo Date: Mon, 27 May 2024 13:06:57 +0800 Subject: [PATCH 06/18] add integration tests Signed-off-by: yubonluo --- ...space_saved_objects_client_wrapper.test.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts index 432760aa692a..8ba7d55be528 100644 --- a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts +++ b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts @@ -316,6 +316,17 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { expect(createResult.error).toBeUndefined(); }); + + it('should throw forbidden error when user create a workspce and is not OSD admin', async () => { + let error; + try { + await notPermittedSavedObjectedClient.create('workspace', {}, {}); + } catch (e) { + error = e; + } + + expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true); + }); }); describe('bulkCreate', () => { @@ -384,6 +395,17 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { expect(createResult.saved_objects).toHaveLength(1); }); + + it('should throw forbidden error when user bulkCreate workspace and is not OSD admin', async () => { + let error; + try { + await notPermittedSavedObjectedClient.bulkCreate([{ type: 'workspace', attributes: {} }]); + } catch (e) { + error = e; + } + + expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true); + }); }); describe('update', () => { From d83e340066777b344818731f09c597f8dd4fc12a Mon Sep 17 00:00:00 2001 From: yubonluo Date: Mon, 27 May 2024 14:17:56 +0800 Subject: [PATCH 07/18] optimize the code Signed-off-by: yubonluo --- .../workspace_saved_objects_client_wrapper.ts | 11 ++++++++--- src/plugins/workspace/server/utils.test.ts | 19 +++++++++++++++++++ src/plugins/workspace/server/utils.ts | 12 ++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) 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 79294da70d51..2cac49f1394b 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 @@ -33,7 +33,7 @@ import { WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID, WorkspacePermissionMode, } from '../../common/constants'; -import { isWorkspaceType } from '../utils'; +import { isTypeContained, isWorkspaceType } from '../utils'; // Can't throw unauthorized for now, the page will be refreshed if unauthorized const generateWorkspacePermissionError = () => @@ -283,7 +283,12 @@ export class WorkspaceSavedObjectsClientWrapper { options: SavedObjectsCreateOptions = {} ): Promise> => { // Only OSD admin can bulkCreate workspace - if (this.isRelatedToWorkspace(objects.map((object) => object.type))) + if ( + isTypeContained( + WORKSPACE_TYPE, + objects.map((object) => object.type) + ) + ) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; @@ -345,7 +350,7 @@ export class WorkspaceSavedObjectsClientWrapper { options?: SavedObjectsCreateOptions ) => { // Only OSD admin can create workspace - if (this.isRelatedToWorkspace(type)) throw generateOSDAdminPermissionError(); + if (isTypeContained(WORKSPACE_TYPE, type)) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; diff --git a/src/plugins/workspace/server/utils.test.ts b/src/plugins/workspace/server/utils.test.ts index 15e6783c2cab..a7ac6c96c976 100644 --- a/src/plugins/workspace/server/utils.test.ts +++ b/src/plugins/workspace/server/utils.test.ts @@ -9,6 +9,7 @@ import { generateRandomId, getOSDAdminConfigFromYMLConfig, getPrincipalsFromRequest, + isTypeContained, updateDashboardAdminStateForRequest, } from './utils'; import { getWorkspaceState } from '../../../core/server/utils'; @@ -151,4 +152,22 @@ describe('workspace utils', () => { expect(groups).toEqual([]); expect(users).toEqual([]); }); + + it('should return true when source type contains target type', async () => { + let result; + result = isTypeContained('workspace', 'workspace'); + expect(result).toBe(true); + + result = isTypeContained('workspace', ['workspace', 'dashboard']); + expect(result).toBe(true); + }); + + it('should return false when source type does not contain target type', async () => { + let result; + result = isTypeContained('workspace', 'dashboard'); + expect(result).toBe(false); + + result = isTypeContained('workspace', ['config', 'dashboard']); + expect(result).toBe(false); + }); }); diff --git a/src/plugins/workspace/server/utils.ts b/src/plugins/workspace/server/utils.ts index 9037038f16af..92c1ba16a9e1 100644 --- a/src/plugins/workspace/server/utils.ts +++ b/src/plugins/workspace/server/utils.ts @@ -89,3 +89,15 @@ export const getOSDAdminConfigFromYMLConfig = async ( return [groupsResult, usersResult]; }; + +/** + * check if the source type include the tartget type + * @param targetType + * @param sourceType + * @returns If the target type is included in the source type, return true, otherwise return false. + */ +export const isTypeContained = (targetType: string, sourceType: string | string[]): boolean => { + return ( + targetType === sourceType || (Array.isArray(sourceType) && sourceType.includes(targetType)) + ); +}; From fa6809df90d530f21308fc444354bd0d5b42da68 Mon Sep 17 00:00:00 2001 From: yubonluo Date: Mon, 27 May 2024 14:19:08 +0800 Subject: [PATCH 08/18] delete useless code Signed-off-by: yubonluo --- .../saved_objects/workspace_saved_objects_client_wrapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2cac49f1394b..e7506241c83c 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 @@ -33,7 +33,7 @@ import { WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID, WorkspacePermissionMode, } from '../../common/constants'; -import { isTypeContained, isWorkspaceType } from '../utils'; +import { isTypeContained } from '../utils'; // Can't throw unauthorized for now, the page will be refreshed if unauthorized const generateWorkspacePermissionError = () => From e979d775decb488b736fada810fc60253e3b9574 Mon Sep 17 00:00:00 2001 From: yubonluo Date: Mon, 27 May 2024 15:03:38 +0800 Subject: [PATCH 09/18] optimize the code Signed-off-by: yubonluo --- .../workspace_saved_objects_client_wrapper.ts | 10 ++-------- src/plugins/workspace/server/utils.test.ts | 19 ------------------- src/plugins/workspace/server/utils.ts | 11 ----------- 3 files changed, 2 insertions(+), 38 deletions(-) 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 e7506241c83c..15788ef9ac07 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 @@ -33,7 +33,6 @@ import { WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID, WorkspacePermissionMode, } from '../../common/constants'; -import { isTypeContained } from '../utils'; // Can't throw unauthorized for now, the page will be refreshed if unauthorized const generateWorkspacePermissionError = () => @@ -283,12 +282,7 @@ export class WorkspaceSavedObjectsClientWrapper { options: SavedObjectsCreateOptions = {} ): Promise> => { // Only OSD admin can bulkCreate workspace - if ( - isTypeContained( - WORKSPACE_TYPE, - objects.map((object) => object.type) - ) - ) + if (objects.some((obj) => obj.type === WORKSPACE_TYPE)) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; @@ -350,7 +344,7 @@ export class WorkspaceSavedObjectsClientWrapper { options?: SavedObjectsCreateOptions ) => { // Only OSD admin can create workspace - if (isTypeContained(WORKSPACE_TYPE, type)) throw generateOSDAdminPermissionError(); + if (type === WORKSPACE_TYPE) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; diff --git a/src/plugins/workspace/server/utils.test.ts b/src/plugins/workspace/server/utils.test.ts index a7ac6c96c976..15e6783c2cab 100644 --- a/src/plugins/workspace/server/utils.test.ts +++ b/src/plugins/workspace/server/utils.test.ts @@ -9,7 +9,6 @@ import { generateRandomId, getOSDAdminConfigFromYMLConfig, getPrincipalsFromRequest, - isTypeContained, updateDashboardAdminStateForRequest, } from './utils'; import { getWorkspaceState } from '../../../core/server/utils'; @@ -152,22 +151,4 @@ describe('workspace utils', () => { expect(groups).toEqual([]); expect(users).toEqual([]); }); - - it('should return true when source type contains target type', async () => { - let result; - result = isTypeContained('workspace', 'workspace'); - expect(result).toBe(true); - - result = isTypeContained('workspace', ['workspace', 'dashboard']); - expect(result).toBe(true); - }); - - it('should return false when source type does not contain target type', async () => { - let result; - result = isTypeContained('workspace', 'dashboard'); - expect(result).toBe(false); - - result = isTypeContained('workspace', ['config', 'dashboard']); - expect(result).toBe(false); - }); }); diff --git a/src/plugins/workspace/server/utils.ts b/src/plugins/workspace/server/utils.ts index 92c1ba16a9e1..f798017981b6 100644 --- a/src/plugins/workspace/server/utils.ts +++ b/src/plugins/workspace/server/utils.ts @@ -90,14 +90,3 @@ export const getOSDAdminConfigFromYMLConfig = async ( return [groupsResult, usersResult]; }; -/** - * check if the source type include the tartget type - * @param targetType - * @param sourceType - * @returns If the target type is included in the source type, return true, otherwise return false. - */ -export const isTypeContained = (targetType: string, sourceType: string | string[]): boolean => { - return ( - targetType === sourceType || (Array.isArray(sourceType) && sourceType.includes(targetType)) - ); -}; From 87ebeefeb783b7b16c4c64ccde3a1d0264a0789b Mon Sep 17 00:00:00 2001 From: yubonluo Date: Mon, 27 May 2024 15:04:29 +0800 Subject: [PATCH 10/18] optimize the code Signed-off-by: yubonluo --- src/plugins/workspace/server/utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/workspace/server/utils.ts b/src/plugins/workspace/server/utils.ts index f798017981b6..9037038f16af 100644 --- a/src/plugins/workspace/server/utils.ts +++ b/src/plugins/workspace/server/utils.ts @@ -89,4 +89,3 @@ export const getOSDAdminConfigFromYMLConfig = async ( return [groupsResult, usersResult]; }; - From 5b9a7860a39beef9afc9df43fb06f6d6dc4ca1fd Mon Sep 17 00:00:00 2001 From: yubonluo Date: Mon, 27 May 2024 15:24:52 +0800 Subject: [PATCH 11/18] optimize the code Signed-off-by: yubonluo --- .../workspace_saved_objects_client_wrapper.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts index 8ba7d55be528..03e8e105e0fb 100644 --- a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts +++ b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts @@ -320,7 +320,7 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { it('should throw forbidden error when user create a workspce and is not OSD admin', async () => { let error; try { - await notPermittedSavedObjectedClient.create('workspace', {}, {}); + await permittedSavedObjectedClient.create('workspace', {}, {}); } catch (e) { error = e; } @@ -399,7 +399,7 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { it('should throw forbidden error when user bulkCreate workspace and is not OSD admin', async () => { let error; try { - await notPermittedSavedObjectedClient.bulkCreate([{ type: 'workspace', attributes: {} }]); + await permittedSavedObjectedClient.bulkCreate([{ type: 'workspace', attributes: {} }]); } catch (e) { error = e; } From 0cfa4b02c2d62676b2e62bd648df3f514e8676d1 Mon Sep 17 00:00:00 2001 From: yubonluo Date: Mon, 27 May 2024 18:20:04 +0800 Subject: [PATCH 12/18] add overwrite check Signed-off-by: yubonluo --- .../saved_objects/workspace_saved_objects_client_wrapper.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 15788ef9ac07..f465f207e288 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 @@ -282,7 +282,7 @@ export class WorkspaceSavedObjectsClientWrapper { options: SavedObjectsCreateOptions = {} ): Promise> => { // Only OSD admin can bulkCreate workspace - if (objects.some((obj) => obj.type === WORKSPACE_TYPE)) + if (objects.some((obj) => obj.type === WORKSPACE_TYPE) && !options?.overwrite) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; @@ -344,7 +344,7 @@ export class WorkspaceSavedObjectsClientWrapper { options?: SavedObjectsCreateOptions ) => { // Only OSD admin can create workspace - if (type === WORKSPACE_TYPE) throw generateOSDAdminPermissionError(); + if (type === WORKSPACE_TYPE && !options?.overwrite) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; From 41b17abcc7e5374ccf40959745cf6bb42d528f7a Mon Sep 17 00:00:00 2001 From: yubonluo Date: Mon, 27 May 2024 19:33:28 +0800 Subject: [PATCH 13/18] optimize the code Signed-off-by: yubonluo --- .../saved_objects/workspace_saved_objects_client_wrapper.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 f465f207e288..f24c6c8cc345 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 @@ -282,7 +282,7 @@ export class WorkspaceSavedObjectsClientWrapper { options: SavedObjectsCreateOptions = {} ): Promise> => { // Only OSD admin can bulkCreate workspace - if (objects.some((obj) => obj.type === WORKSPACE_TYPE) && !options?.overwrite) + if (objects.some((obj) => obj.type === WORKSPACE_TYPE)) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; @@ -344,7 +344,8 @@ export class WorkspaceSavedObjectsClientWrapper { options?: SavedObjectsCreateOptions ) => { // Only OSD admin can create workspace - if (type === WORKSPACE_TYPE && !options?.overwrite) throw generateOSDAdminPermissionError(); + if (type === WORKSPACE_TYPE && !options?.id && !options?.overwrite) + throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; From a1798555466761b13a7620e5412b422b179d4b95 Mon Sep 17 00:00:00 2001 From: yubonluo Date: Mon, 27 May 2024 14:19:08 +0800 Subject: [PATCH 14/18] optimize the code Signed-off-by: yubonluo --- ...space_saved_objects_client_wrapper.test.ts | 6 ++++-- ...space_saved_objects_client_wrapper.test.ts | 6 +++--- .../workspace_saved_objects_client_wrapper.ts | 11 +++-------- src/plugins/workspace/server/utils.test.ts | 19 ------------------- src/plugins/workspace/server/utils.ts | 12 ------------ 5 files changed, 10 insertions(+), 44 deletions(-) diff --git a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts index 8ba7d55be528..9f8e8224ebda 100644 --- a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts +++ b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts @@ -320,7 +320,7 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { it('should throw forbidden error when user create a workspce and is not OSD admin', async () => { let error; try { - await notPermittedSavedObjectedClient.create('workspace', {}, {}); + await permittedSavedObjectedClient.create('workspace', {}, {}); } catch (e) { error = e; } @@ -399,7 +399,9 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { it('should throw forbidden error when user bulkCreate workspace and is not OSD admin', async () => { let error; try { - await notPermittedSavedObjectedClient.bulkCreate([{ type: 'workspace', attributes: {} }]); + await permittedSavedObjectedClient.bulkCreate([{ type: 'workspace', attributes: {} }], { + overwrite: true, + }); } catch (e) { error = e; } diff --git a/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.test.ts b/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.test.ts index 02ee2fa0a294..d0c55c4d79b4 100644 --- a/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.test.ts +++ b/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.test.ts @@ -356,12 +356,12 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { const { wrapper } = generateWorkspaceSavedObjectsClientWrapper(); const objectsToBulkCreate = [ - { type: 'workspace', id: 'w1', attributes: { bar: 'baz' } }, - { type: 'workspace', id: 'w2', attributes: { bar: 'foo' } }, + { type: 'workspace', id: 'w1', attributes: {} }, + { type: 'workspace', id: 'w2', attributes: {} }, ]; let errorCatched; try { - await wrapper.bulkCreate(objectsToBulkCreate); + await wrapper.bulkCreate(objectsToBulkCreate, { overwrite: true }); } catch (e) { errorCatched = e; } 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 2cac49f1394b..f24c6c8cc345 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 @@ -33,7 +33,6 @@ import { WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID, WorkspacePermissionMode, } from '../../common/constants'; -import { isTypeContained, isWorkspaceType } from '../utils'; // Can't throw unauthorized for now, the page will be refreshed if unauthorized const generateWorkspacePermissionError = () => @@ -283,12 +282,7 @@ export class WorkspaceSavedObjectsClientWrapper { options: SavedObjectsCreateOptions = {} ): Promise> => { // Only OSD admin can bulkCreate workspace - if ( - isTypeContained( - WORKSPACE_TYPE, - objects.map((object) => object.type) - ) - ) + if (objects.some((obj) => obj.type === WORKSPACE_TYPE)) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; @@ -350,7 +344,8 @@ export class WorkspaceSavedObjectsClientWrapper { options?: SavedObjectsCreateOptions ) => { // Only OSD admin can create workspace - if (isTypeContained(WORKSPACE_TYPE, type)) throw generateOSDAdminPermissionError(); + if (type === WORKSPACE_TYPE && !options?.id && !options?.overwrite) + throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; diff --git a/src/plugins/workspace/server/utils.test.ts b/src/plugins/workspace/server/utils.test.ts index a7ac6c96c976..15e6783c2cab 100644 --- a/src/plugins/workspace/server/utils.test.ts +++ b/src/plugins/workspace/server/utils.test.ts @@ -9,7 +9,6 @@ import { generateRandomId, getOSDAdminConfigFromYMLConfig, getPrincipalsFromRequest, - isTypeContained, updateDashboardAdminStateForRequest, } from './utils'; import { getWorkspaceState } from '../../../core/server/utils'; @@ -152,22 +151,4 @@ describe('workspace utils', () => { expect(groups).toEqual([]); expect(users).toEqual([]); }); - - it('should return true when source type contains target type', async () => { - let result; - result = isTypeContained('workspace', 'workspace'); - expect(result).toBe(true); - - result = isTypeContained('workspace', ['workspace', 'dashboard']); - expect(result).toBe(true); - }); - - it('should return false when source type does not contain target type', async () => { - let result; - result = isTypeContained('workspace', 'dashboard'); - expect(result).toBe(false); - - result = isTypeContained('workspace', ['config', 'dashboard']); - expect(result).toBe(false); - }); }); diff --git a/src/plugins/workspace/server/utils.ts b/src/plugins/workspace/server/utils.ts index 92c1ba16a9e1..9037038f16af 100644 --- a/src/plugins/workspace/server/utils.ts +++ b/src/plugins/workspace/server/utils.ts @@ -89,15 +89,3 @@ export const getOSDAdminConfigFromYMLConfig = async ( return [groupsResult, usersResult]; }; - -/** - * check if the source type include the tartget type - * @param targetType - * @param sourceType - * @returns If the target type is included in the source type, return true, otherwise return false. - */ -export const isTypeContained = (targetType: string, sourceType: string | string[]): boolean => { - return ( - targetType === sourceType || (Array.isArray(sourceType) && sourceType.includes(targetType)) - ); -}; From 9417e211df07840c18d1b984ee87c3219afcb98b Mon Sep 17 00:00:00 2001 From: yubonluo Date: Thu, 30 May 2024 10:56:38 +0800 Subject: [PATCH 15/18] Add the logic of whether to update the operation Signed-off-by: yubonluo --- ...space_saved_objects_client_wrapper.test.ts | 34 ++++++++++++++++++ ...space_saved_objects_client_wrapper.test.ts | 35 +++++++++++++++---- .../workspace_saved_objects_client_wrapper.ts | 11 ++++-- 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts index 9f8e8224ebda..b14e0c8cb933 100644 --- a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts +++ b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts @@ -326,6 +326,22 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { } expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true); + + try { + await permittedSavedObjectedClient.create('workspace', {}, { id: 'workspace-1' }); + } catch (e) { + error = e; + } + + expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true); + + try { + await permittedSavedObjectedClient.create('workspace', {}, { overwrite: true }); + } catch (e) { + error = e; + } + + expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true); }); }); @@ -398,6 +414,14 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { it('should throw forbidden error when user bulkCreate workspace and is not OSD admin', async () => { let error; + try { + await permittedSavedObjectedClient.bulkCreate([{ type: 'workspace', attributes: {} }]); + } catch (e) { + error = e; + } + + expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true); + try { await permittedSavedObjectedClient.bulkCreate([{ type: 'workspace', attributes: {} }], { overwrite: true, @@ -407,6 +431,16 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { } expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true); + + try { + await permittedSavedObjectedClient.bulkCreate([ + { type: 'workspace', id: 'test', attributes: {} }, + ]); + } catch (e) { + error = e; + } + + expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true); }); }); diff --git a/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.test.ts b/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.test.ts index d0c55c4d79b4..79e1b25cd823 100644 --- a/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.test.ts +++ b/src/plugins/workspace/server/saved_objects/workspace_saved_objects_client_wrapper.test.ts @@ -354,14 +354,23 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { }); it('should throw permission error when user bulkCreate workspace and is not dashboard admin', async () => { const { wrapper } = generateWorkspaceSavedObjectsClientWrapper(); - - const objectsToBulkCreate = [ - { type: 'workspace', id: 'w1', attributes: {} }, - { type: 'workspace', id: 'w2', attributes: {} }, - ]; let errorCatched; try { - await wrapper.bulkCreate(objectsToBulkCreate, { overwrite: true }); + await wrapper.bulkCreate([{ type: 'workspace', attributes: {} }]); + } catch (e) { + errorCatched = e; + } + expect(errorCatched?.message).toEqual('Invalid permission, please contact OSD admin'); + + try { + await wrapper.bulkCreate([{ type: 'workspace', id: 'test', attributes: {} }]); + } catch (e) { + errorCatched = e; + } + expect(errorCatched?.message).toEqual('Invalid permission, please contact OSD admin'); + + try { + await wrapper.bulkCreate([{ type: 'workspace', attributes: {} }], { overwrite: true }); } catch (e) { errorCatched = e; } @@ -444,6 +453,20 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { it('should throw permission error when user create a workspace and is not dashboard admin', async () => { const { wrapper } = generateWorkspaceSavedObjectsClientWrapper(); let errorCatched; + try { + await wrapper.create('workspace', { name: 'test' }, { overwrite: true }); + } catch (e) { + errorCatched = e; + } + expect(errorCatched?.message).toEqual('Invalid permission, please contact OSD admin'); + + try { + await wrapper.create('workspace', { name: 'test' }, { id: 'test' }); + } catch (e) { + errorCatched = e; + } + expect(errorCatched?.message).toEqual('Invalid permission, please contact OSD admin'); + try { await wrapper.create('workspace', { name: 'test' }, {}); } catch (e) { 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 f24c6c8cc345..f7d37d9a9577 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 @@ -282,7 +282,10 @@ export class WorkspaceSavedObjectsClientWrapper { options: SavedObjectsCreateOptions = {} ): Promise> => { // Only OSD admin can bulkCreate workspace - if (objects.some((obj) => obj.type === WORKSPACE_TYPE)) + if ( + objects.some((obj) => obj.type === WORKSPACE_TYPE) && + !(objects.some((obj) => obj.id && obj.type === WORKSPACE_TYPE) && options.overwrite) + ) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; @@ -343,9 +346,11 @@ export class WorkspaceSavedObjectsClientWrapper { attributes: T, options?: SavedObjectsCreateOptions ) => { - // Only OSD admin can create workspace - if (type === WORKSPACE_TYPE && !options?.id && !options?.overwrite) + // Only OSD admin can create workspace. + // If options contains id and overwrite, it is an update action. + if (type === WORKSPACE_TYPE && !(options?.id && options?.overwrite)) { throw generateOSDAdminPermissionError(); + } const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; From 8c3675b59459ab4c537ec72db2953ea9f3b20ccf Mon Sep 17 00:00:00 2001 From: yubonluo Date: Fri, 31 May 2024 14:10:18 +0800 Subject: [PATCH 16/18] optimize the code Signed-off-by: yubonluo --- ...rkspace_saved_objects_client_wrapper.test.ts | 12 ++++++++++++ .../workspace_saved_objects_client_wrapper.ts | 17 ++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts index b14e0c8cb933..e58f606a38b3 100644 --- a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts +++ b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts @@ -342,6 +342,18 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { } expect(SavedObjectsErrorHelpers.isForbiddenError(error)).toBe(true); + + try { + await permittedSavedObjectedClient.create( + 'workspace', + {}, + { id: 'no-exist', overwrite: true } + ); + } catch (e) { + error = e; + } + + expect(SavedObjectsErrorHelpers.isNotFoundError(error)).toBe(true); }); }); 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 f7d37d9a9577..584c7320ea75 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 @@ -281,11 +281,11 @@ export class WorkspaceSavedObjectsClientWrapper { objects: Array>, options: SavedObjectsCreateOptions = {} ): Promise> => { - // Only OSD admin can bulkCreate workspace - if ( - objects.some((obj) => obj.type === WORKSPACE_TYPE) && - !(objects.some((obj) => obj.id && obj.type === WORKSPACE_TYPE) && options.overwrite) - ) + // If objects contain workspace id and options.overwrite is true, it is a bulkCreate action. + const isUpdateWorkspaceMode = + objects.some((obj) => obj.id && obj.type === WORKSPACE_TYPE) && options.overwrite; + // Only OSD admin can bulkCreate workspace. + if (objects.some((obj) => obj.type === WORKSPACE_TYPE) && !isUpdateWorkspaceMode) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; @@ -346,11 +346,10 @@ export class WorkspaceSavedObjectsClientWrapper { attributes: T, options?: SavedObjectsCreateOptions ) => { - // Only OSD admin can create workspace. // If options contains id and overwrite, it is an update action. - if (type === WORKSPACE_TYPE && !(options?.id && options?.overwrite)) { - throw generateOSDAdminPermissionError(); - } + const isUpdateMode = options?.id && options?.overwrite; + // Only OSD admin can create workspace. + if (type === WORKSPACE_TYPE && !isUpdateMode) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; From 8a5721e2c13aa5a3ca7c156c9835064548d6fcc3 Mon Sep 17 00:00:00 2001 From: yubonluo Date: Fri, 31 May 2024 17:03:23 +0800 Subject: [PATCH 17/18] Optimize the code Signed-off-by: yubonluo --- ...space_saved_objects_client_wrapper.test.ts | 54 ++++++++++++++++++- .../workspace_saved_objects_client_wrapper.ts | 7 ++- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts index e58f606a38b3..b5399de9fb5d 100644 --- a/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts +++ b/src/plugins/workspace/server/saved_objects/integration_tests/workspace_saved_objects_client_wrapper.test.ts @@ -97,6 +97,20 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { id: 'workspace-1', permissions: { library_read: { users: ['foo'] }, + write: { users: ['foo'] }, + library_write: { users: ['foo'] }, + }, + } + ); + + await repositoryKit.create( + internalSavedObjectsRepository, + 'workspace', + {}, + { + id: 'workspace-2', + permissions: { + write: { users: ['foo'] }, library_write: { users: ['foo'] }, }, } @@ -132,7 +146,9 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { return { users: ['foo'] }; }); - permittedSavedObjectedClient = osd.coreStart.savedObjects.getScopedClient(permittedRequest); + permittedSavedObjectedClient = osd.coreStart.savedObjects.getScopedClient(permittedRequest, { + includedHiddenTypes: ['workspace'], + }); notPermittedSavedObjectedClient = osd.coreStart.savedObjects.getScopedClient( notPermittedRequest ); @@ -317,6 +333,23 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { expect(createResult.error).toBeUndefined(); }); + it('should able to create workspace with override', async () => { + const createResult = await permittedSavedObjectedClient.create( + 'workspace', + {}, + { + id: 'workspace-2', + overwrite: true, + permissions: { + library_write: { users: ['foo'] }, + write: { users: ['foo'] }, + }, + } + ); + + expect(createResult.error).toBeUndefined(); + }); + it('should throw forbidden error when user create a workspce and is not OSD admin', async () => { let error; try { @@ -424,7 +457,24 @@ describe('WorkspaceSavedObjectsClientWrapper', () => { expect(createResult.saved_objects).toHaveLength(1); }); - it('should throw forbidden error when user bulkCreate workspace and is not OSD admin', async () => { + it('should able to bulk create workspace with override', async () => { + const createResult = await permittedSavedObjectedClient.bulkCreate( + [ + { + id: 'workspace-2', + type: 'workspace', + attributes: {}, + }, + ], + { + overwrite: true, + } + ); + + expect(createResult.saved_objects).toHaveLength(1); + }); + + it('should throw forbidden error when user bulk create workspace and is not OSD admin', async () => { let error; try { await permittedSavedObjectedClient.bulkCreate([{ type: 'workspace', attributes: {} }]); 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 584c7320ea75..2a40a4142cb0 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 @@ -281,11 +281,10 @@ export class WorkspaceSavedObjectsClientWrapper { objects: Array>, options: SavedObjectsCreateOptions = {} ): Promise> => { - // If objects contain workspace id and options.overwrite is true, it is a bulkCreate action. - const isUpdateWorkspaceMode = - objects.some((obj) => obj.id && obj.type === WORKSPACE_TYPE) && options.overwrite; + // Objects with id in overwrite mode will be regarded as update + const objectsToCreate = options.overwrite ? objects.filter((obj) => !obj.id) : objects; // Only OSD admin can bulkCreate workspace. - if (objects.some((obj) => obj.type === WORKSPACE_TYPE) && !isUpdateWorkspaceMode) + if (objectsToCreate.some((obj) => obj.type === WORKSPACE_TYPE)) throw generateOSDAdminPermissionError(); const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; From 35b04bdad95c6b9425656d7d0d678df274eca898 Mon Sep 17 00:00:00 2001 From: yubonluo Date: Tue, 4 Jun 2024 01:16:51 +0800 Subject: [PATCH 18/18] Optimize the code Signed-off-by: yubonluo --- .../workspace_saved_objects_client_wrapper.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 2a40a4142cb0..06701fba338a 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 @@ -284,8 +284,9 @@ export class WorkspaceSavedObjectsClientWrapper { // Objects with id in overwrite mode will be regarded as update const objectsToCreate = options.overwrite ? objects.filter((obj) => !obj.id) : objects; // Only OSD admin can bulkCreate workspace. - if (objectsToCreate.some((obj) => obj.type === WORKSPACE_TYPE)) + if (objectsToCreate.some((obj) => obj.type === WORKSPACE_TYPE)) { throw generateOSDAdminPermissionError(); + } const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0; @@ -348,7 +349,9 @@ export class WorkspaceSavedObjectsClientWrapper { // If options contains id and overwrite, it is an update action. const isUpdateMode = options?.id && options?.overwrite; // Only OSD admin can create workspace. - if (type === WORKSPACE_TYPE && !isUpdateMode) throw generateOSDAdminPermissionError(); + if (type === WORKSPACE_TYPE && !isUpdateMode) { + throw generateOSDAdminPermissionError(); + } const hasTargetWorkspaces = options?.workspaces && options.workspaces.length > 0;