diff --git a/src/plugins/workspace/server/plugin.ts b/src/plugins/workspace/server/plugin.ts index 824135698536..f9b7b28f1b72 100644 --- a/src/plugins/workspace/server/plugin.ts +++ b/src/plugins/workspace/server/plugin.ts @@ -147,6 +147,7 @@ export class WorkspacePlugin implements Plugin<{}, {}> { throw new Error('UI setting client can not be found'); } const internalRepository = this.coreStart.savedObjects.createInternalRepository(); + this.client?.setInternalRepository(internalRepository); const publicWorkspaceACL = new ACL().addPermission( [WorkspacePermissionMode.LibraryRead, WorkspacePermissionMode.LibraryWrite], { diff --git a/src/plugins/workspace/server/types.ts b/src/plugins/workspace/server/types.ts index c45d13f0fb87..c87588535d88 100644 --- a/src/plugins/workspace/server/types.ts +++ b/src/plugins/workspace/server/types.ts @@ -11,6 +11,7 @@ import { WorkspacePermissionMode, Permissions, WorkspaceAttribute, + ISavedObjectsRepository, } from '../../../core/server'; export interface WorkspaceAttributeWithPermission extends WorkspaceAttribute { @@ -35,6 +36,7 @@ export interface IRequestDetail { export interface IWorkspaceDBImpl { setup(dep: CoreSetup): Promise>; + setInternalRepository(repository: ISavedObjectsRepository): void; create( requestDetail: IRequestDetail, payload: Omit diff --git a/src/plugins/workspace/server/workspace_client.ts b/src/plugins/workspace/server/workspace_client.ts index b569736aa924..f72952f72378 100644 --- a/src/plugins/workspace/server/workspace_client.ts +++ b/src/plugins/workspace/server/workspace_client.ts @@ -2,11 +2,13 @@ * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ +import { i18n } from '@osd/i18n'; import type { SavedObject, SavedObjectsClientContract, CoreSetup, WorkspaceAttribute, + ISavedObjectsRepository, } from '../../../core/server'; import { WORKSPACE_TYPE } from '../../../core/server'; import { @@ -21,8 +23,18 @@ import { generateRandomId } from './utils'; const WORKSPACE_ID_SIZE = 6; +const DUPLICATE_WORKSPACE_NAME_ERROR = i18n.translate('workspace.duplicate.name.error', { + defaultMessage: 'workspace name has already been used, try with a different name', +}); + export class WorkspaceClientWithSavedObject implements IWorkspaceDBImpl { private setupDep: CoreSetup; + + private internalSavedObjectsRepository?: ISavedObjectsRepository; + setInternalRepository(repository: ISavedObjectsRepository) { + this.internalSavedObjectsRepository = repository; + } + constructor(core: CoreSetup) { this.setupDep = core; } @@ -57,12 +69,23 @@ export class WorkspaceClientWithSavedObject implements IWorkspaceDBImpl { try { const { permissions, ...attributes } = payload; const id = generateRandomId(WORKSPACE_ID_SIZE); - const result = await this.getSavedObjectClientsFromRequestDetail(requestDetail).create< - Omit - >(WORKSPACE_TYPE, attributes, { - id, - permissions, + const client = this.getSavedObjectClientsFromRequestDetail(requestDetail); + const existingWorkspaceRes = await this.internalSavedObjectsRepository?.find({ + type: WORKSPACE_TYPE, + search: attributes.name, + searchFields: ['name'], }); + if (existingWorkspaceRes && existingWorkspaceRes.total > 0) { + throw new Error(DUPLICATE_WORKSPACE_NAME_ERROR); + } + const result = await client.create>( + WORKSPACE_TYPE, + attributes, + { + id, + permissions, + } + ); return { success: true, result: { @@ -130,9 +153,20 @@ export class WorkspaceClientWithSavedObject implements IWorkspaceDBImpl { ): Promise> { const { permissions, ...attributes } = payload; try { - await this.getSavedObjectClientsFromRequestDetail(requestDetail).update< - Omit - >(WORKSPACE_TYPE, id, attributes, { + const client = this.getSavedObjectClientsFromRequestDetail(requestDetail); + const workspaceInDB: SavedObject = await client.get(WORKSPACE_TYPE, id); + if (workspaceInDB.attributes.name !== attributes.name) { + const existingWorkspaceRes = await this.internalSavedObjectsRepository?.find({ + type: WORKSPACE_TYPE, + search: attributes.name, + searchFields: ['name'], + fields: ['_id'], + }); + if (existingWorkspaceRes && existingWorkspaceRes.total > 0) { + throw new Error(DUPLICATE_WORKSPACE_NAME_ERROR); + } + } + await client.update>(WORKSPACE_TYPE, id, attributes, { permissions, }); return {