Skip to content

Commit

Permalink
add workspace name duplication check (opensearch-project#117)
Browse files Browse the repository at this point in the history
* add workspace name duplication check

Signed-off-by: Hailong Cui <ihailong@amazon.com>

* update error message

Signed-off-by: Hailong Cui <ihailong@amazon.com>

---------

Signed-off-by: Hailong Cui <ihailong@amazon.com>
  • Loading branch information
Hailong-am authored Aug 31, 2023
1 parent 0f26494 commit f3a9672
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/plugins/workspace/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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],
{
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/workspace/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
WorkspacePermissionMode,
Permissions,
WorkspaceAttribute,
ISavedObjectsRepository,
} from '../../../core/server';

export interface WorkspaceAttributeWithPermission extends WorkspaceAttribute {
Expand All @@ -35,6 +36,7 @@ export interface IRequestDetail {

export interface IWorkspaceDBImpl {
setup(dep: CoreSetup): Promise<IResponse<boolean>>;
setInternalRepository(repository: ISavedObjectsRepository): void;
create(
requestDetail: IRequestDetail,
payload: Omit<WorkspaceAttributeWithPermission, 'id'>
Expand Down
50 changes: 42 additions & 8 deletions src/plugins/workspace/server/workspace_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
}
Expand Down Expand Up @@ -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<WorkspaceAttribute, 'id'>
>(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<Omit<WorkspaceAttribute, 'id'>>(
WORKSPACE_TYPE,
attributes,
{
id,
permissions,
}
);
return {
success: true,
result: {
Expand Down Expand Up @@ -130,9 +153,20 @@ export class WorkspaceClientWithSavedObject implements IWorkspaceDBImpl {
): Promise<IResponse<boolean>> {
const { permissions, ...attributes } = payload;
try {
await this.getSavedObjectClientsFromRequestDetail(requestDetail).update<
Omit<WorkspaceAttribute, 'id'>
>(WORKSPACE_TYPE, id, attributes, {
const client = this.getSavedObjectClientsFromRequestDetail(requestDetail);
const workspaceInDB: SavedObject<WorkspaceAttribute> = 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<Omit<WorkspaceAttribute, 'id'>>(WORKSPACE_TYPE, id, attributes, {
permissions,
});
return {
Expand Down

0 comments on commit f3a9672

Please sign in to comment.