Skip to content

Commit

Permalink
feat: use bulkGetObjects and fix unit test
Browse files Browse the repository at this point in the history
Signed-off-by: SuZhou-Joe <suzhou@amazon.com>
  • Loading branch information
SuZhou-Joe committed Jul 27, 2023
1 parent 88576f1 commit 9ba2e7e
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/core/server/legacy/legacy_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ export class LegacyService implements CoreService {
registerType: setupDeps.core.savedObjects.registerType,
getImportExportObjectLimit: setupDeps.core.savedObjects.getImportExportObjectLimit,
setRepositoryFactoryProvider: setupDeps.core.savedObjects.setRepositoryFactoryProvider,
permissionControl: setupDeps.core.savedObjects.permissionControl,
},
status: {
isStatusPageAnonymous: setupDeps.core.status.isStatusPageAnonymous,
Expand Down
1 change: 1 addition & 0 deletions src/core/server/plugins/plugin_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>(
registerType: deps.savedObjects.registerType,
getImportExportObjectLimit: deps.savedObjects.getImportExportObjectLimit,
setRepositoryFactoryProvider: deps.savedObjects.setRepositoryFactoryProvider,
permissionControl: deps.savedObjects.permissionControl,
},
status: {
core$: deps.status.core$,
Expand Down
15 changes: 15 additions & 0 deletions src/core/server/saved_objects/permission_control/client.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { SavedObjectsPermissionControlContract } from './client';

export const savedObjectsPermissionControlMock: SavedObjectsPermissionControlContract = {
setup: jest.fn(),
validate: jest.fn(),
addPrinciplesToObjects: jest.fn(),
removePrinciplesFromObjects: jest.fn(),
getPrinciplesOfObjects: jest.fn(),
getPermittedWorkspaceIds: jest.fn(),
};
33 changes: 26 additions & 7 deletions src/core/server/saved_objects/permission_control/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import { OpenSearchDashboardsRequest } from '../../http';
import { SavedObjectsServiceStart } from '../saved_objects_service';
import { SavedObjectsBulkGetObject } from '../service';

export enum PermissionMode {
Read = 'read',
Expand All @@ -14,25 +15,43 @@ export enum PermissionMode {
LibraryWrite = 'library_write',
}

export type SavedObjectsPermissionControlContract = Pick<
SavedObjectsPermissionControl,
keyof SavedObjectsPermissionControl
>;

export class SavedObjectsPermissionControl {
private getScopedClient?: SavedObjectsServiceStart['getScopedClient'];
public async setup(getScopedClient: SavedObjectsServiceStart['getScopedClient']) {
this.getScopedClient = getScopedClient;
}
private getScopedSavedObjectsClient(request: OpenSearchDashboardsRequest) {
return this.getScopedClient?.(request);
}
private async bulkGetSavedObjects(
request: OpenSearchDashboardsRequest,
savedObjects: SavedObjectsBulkGetObject[]
) {
return (
(await this.getScopedSavedObjectsClient(request)?.bulkGet(savedObjects))?.saved_objects || []
);
}
public async setup(getScopedClient: SavedObjectsServiceStart['getScopedClient']) {
this.getScopedClient = getScopedClient;
}
public async validate(
request: OpenSearchDashboardsRequest,
savedObjectId: string,
savedObject: SavedObjectsBulkGetObject,
permissionModeOrModes: PermissionMode | PermissionMode[]
) {
const savedObjectsGet = await this.bulkGetSavedObjects(request, [savedObject]);
if (savedObjectsGet) {
return true;
}

return true;
}

public async addPrinciplesToObjects(
request: OpenSearchDashboardsRequest,
savedObjectIds: string[],
savedObjects: SavedObjectsBulkGetObject[],
personas: string[],
permissionModeOrModes: PermissionMode | PermissionMode[]
): Promise<boolean> {
Expand All @@ -41,7 +60,7 @@ export class SavedObjectsPermissionControl {

public async removePrinciplesFromObjects(
request: OpenSearchDashboardsRequest,
savedObjectIds: string[],
savedObjects: SavedObjectsBulkGetObject[],
personas: string[],
permissionModeOrModes: PermissionMode | PermissionMode[]
): Promise<boolean> {
Expand All @@ -50,7 +69,7 @@ export class SavedObjectsPermissionControl {

public async getPrinciplesOfObjects(
request: OpenSearchDashboardsRequest,
savedObjectIds: string[]
savedObjects: SavedObjectsBulkGetObject[]
): Promise<Record<string, unknown>> {
return {};
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/server/saved_objects/saved_objects_service.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { typeRegistryMock } from './saved_objects_type_registry.mock';
import { migrationMocks } from './migrations/mocks';
import { ServiceStatusLevels } from '../status';
import { ISavedObjectTypeRegistry } from './saved_objects_type_registry';
import { savedObjectsPermissionControlMock } from './permission_control/client.mock';

type SavedObjectsServiceContract = PublicMethodsOf<SavedObjectsService>;

Expand Down Expand Up @@ -80,6 +81,7 @@ const createSetupContractMock = () => {
registerType: jest.fn(),
getImportExportObjectLimit: jest.fn(),
setRepositoryFactoryProvider: jest.fn(),
permissionControl: savedObjectsPermissionControlMock,
};

setupContract.getImportExportObjectLimit.mockReturnValue(100);
Expand Down
9 changes: 6 additions & 3 deletions src/core/server/saved_objects/saved_objects_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ import { registerRoutes } from './routes';
import { ServiceStatus } from '../status';
import { calculateStatus$ } from './status';
import { createMigrationOpenSearchClient } from './migrations/core/';
import { SavedObjectsPermissionControl } from './permission_control/client';
import {
SavedObjectsPermissionControl,
SavedObjectsPermissionControlContract,
} from './permission_control/client';
/**
* Saved Objects is OpenSearchDashboards's data persistence mechanism allowing plugins to
* use OpenSearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods
Expand Down Expand Up @@ -177,7 +180,7 @@ export interface SavedObjectsServiceSetup {
respositoryFactoryProvider: SavedObjectRepositoryFactoryProvider
) => void;

permissionControl: SavedObjectsPermissionControl;
permissionControl: SavedObjectsPermissionControlContract;
}

/**
Expand Down Expand Up @@ -304,7 +307,7 @@ export class SavedObjectsService
private started = false;

private respositoryFactoryProvider?: SavedObjectRepositoryFactoryProvider;
private permissionControl?: SavedObjectsPermissionControl;
private permissionControl?: SavedObjectsPermissionControlContract;

constructor(private readonly coreContext: CoreContext) {
this.logger = coreContext.logger.get('savedobjects-service');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ import {
SavedObjectsFindOptions,
} from 'opensearch-dashboards/server';
import {
SavedObjectsPermissionControl,
PermissionMode,
SavedObjectsPermissionControlContract,
} from '../../saved_objects/permission_control/client';
import { WORKSPACE_TYPE } from '../constants';

// Can't throw unauthorized for now, the page will be refreshed if unauthorized
const generateWorkspacePermissionError = () =>
Expand Down Expand Up @@ -51,7 +52,16 @@ export class WorkspaceSavedObjectsClientWrapper {
return;
}
for (const workspaceId of workspaces) {
if (!(await this.permissionControl.validate(request, workspaceId, permissionMode))) {
if (
!(await this.permissionControl.validate(
request,
{
type: WORKSPACE_TYPE,
id: workspaceId,
},
permissionMode
))
) {
throw generateWorkspacePermissionError();
}
}
Expand All @@ -67,7 +77,16 @@ export class WorkspaceSavedObjectsClientWrapper {
}
let permitted = false;
for (const workspaceId of workspaces) {
if (await this.permissionControl.validate(request, workspaceId, permissionMode)) {
if (
await this.permissionControl.validate(
request,
{
type: WORKSPACE_TYPE,
id: workspaceId,
},
permissionMode
)
) {
permitted = true;
break;
}
Expand Down Expand Up @@ -151,7 +170,10 @@ export class WorkspaceSavedObjectsClientWrapper {
async (workspaceId) =>
await this.permissionControl.validate(
wrapperOptions.request,
workspaceId,
{
type: WORKSPACE_TYPE,
id: workspaceId,
},
PermissionMode.Read
)
);
Expand Down Expand Up @@ -184,5 +206,5 @@ export class WorkspaceSavedObjectsClientWrapper {
};
};

constructor(private readonly permissionControl: SavedObjectsPermissionControl) {}
constructor(private readonly permissionControl: SavedObjectsPermissionControlContract) {}
}

0 comments on commit 9ba2e7e

Please sign in to comment.