Skip to content

Commit

Permalink
feat: add permission check for saved objects
Browse files Browse the repository at this point in the history
Signed-off-by: tygao <[email protected]>
  • Loading branch information
raintygao committed Aug 14, 2023
1 parent 3b8879d commit a1cc4f7
Showing 1 changed file with 102 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,21 @@ export class WorkspaceSavedObjectsClientWrapper {

return [permission];
}
private async validateSingleWorkspacePermissions(
workspaceId: string | undefined,
private async validateSingleObjectPermissions(
id: string | undefined,
request: OpenSearchDashboardsRequest,
permissionMode: WorkspacePermissionMode | WorkspacePermissionMode[]
permissionMode: WorkspacePermissionMode | WorkspacePermissionMode[],
type = WORKSPACE_TYPE
) {
if (!workspaceId) {
if (!id) {
return;
}
if (
!(await this.permissionControl.validate(
request,
{
type: WORKSPACE_TYPE,
id: workspaceId,
type,
id,
},
this.formatWorkspacePermissionModeToStringArray(permissionMode)
))
Expand All @@ -87,21 +88,22 @@ export class WorkspaceSavedObjectsClientWrapper {
}
}

private async validateMultiWorkspacesPermissions(
workspaces: string[] | undefined,
private async validateMultiObjectsPermissions(
objects: string[] | undefined,
request: OpenSearchDashboardsRequest,
permissionMode: WorkspacePermissionMode | WorkspacePermissionMode[]
permissionMode: WorkspacePermissionMode | WorkspacePermissionMode[],
type = WORKSPACE_TYPE
) {
if (!workspaces) {
if (!objects) {
return;
}
for (const workspaceId of workspaces) {
for (const id of objects) {
if (
!(await this.permissionControl.validate(
request,
{
type: WORKSPACE_TYPE,
id: workspaceId,
type,
id,
},
this.formatWorkspacePermissionModeToStringArray(permissionMode)
))
Expand Down Expand Up @@ -157,13 +159,20 @@ export class WorkspaceSavedObjectsClientWrapper {
options: SavedObjectsDeleteOptions = {}
) => {
if (this.isRelatedToWorkspace(type)) {
await this.validateSingleWorkspacePermissions(id, wrapperOptions.request, [
await this.validateSingleObjectPermissions(id, wrapperOptions.request, [
WorkspacePermissionMode.Management,
]);
} else {
await this.validateSingleObjectPermissions(
id,
wrapperOptions.request,
[WorkspacePermissionMode.Write],
type
);
}

const objectToDeleted = await wrapperOptions.client.get(type, id, options);
await this.validateMultiWorkspacesPermissions(
await this.validateMultiObjectsPermissions(
objectToDeleted.workspaces,
wrapperOptions.request,
WorkspacePermissionMode.Management
Expand All @@ -178,9 +187,16 @@ export class WorkspaceSavedObjectsClientWrapper {
options: SavedObjectsUpdateOptions = {}
): Promise<SavedObjectsUpdateResponse<T>> => {
if (this.isRelatedToWorkspace(type)) {
await this.validateSingleWorkspacePermissions(id, wrapperOptions.request, [
await this.validateSingleObjectPermissions(id, wrapperOptions.request, [
WorkspacePermissionMode.Management,
]);
} else {
await this.validateSingleObjectPermissions(
id,
wrapperOptions.request,
[WorkspacePermissionMode.Write],
type
);
}
return await wrapperOptions.client.update(type, id, attributes, options);
};
Expand All @@ -189,12 +205,16 @@ export class WorkspaceSavedObjectsClientWrapper {
objects: Array<SavedObjectsBulkUpdateObject<T>>,
options?: SavedObjectsBulkUpdateOptions
): Promise<SavedObjectsBulkUpdateResponse<T>> => {
const workspaceIds = objects.reduce<string[]>((acc, cur) => {
if (this.isRelatedToWorkspace(cur.type)) {
acc.push(cur.id);
const workspaceIds: string[] = [];
const nonWorkspaceObjects: Array<SavedObjectsBulkUpdateObject<T>> = [];
objects.forEach((obj) => {
if (this.isRelatedToWorkspace(obj.type)) {
workspaceIds.push(obj.id);
} else {
nonWorkspaceObjects.push(obj);
}
return acc;
}, []);
});

const permittedWorkspaceIds =
(await this.permissionControl.getPermittedWorkspaceIds(wrapperOptions.request, [
WorkspacePermissionMode.Management,
Expand All @@ -204,6 +224,18 @@ export class WorkspaceSavedObjectsClientWrapper {
throw generateWorkspacePermissionError();
}

// saved_objects
const objectsPermitted = await this.permissionControl.batchValidate(
wrapperOptions.request,
nonWorkspaceObjects.map((savedObj) => ({
...savedObj,
})),
[WorkspacePermissionMode.Write]
);
if (!objectsPermitted) {
throw generateSavedObjectsPermissionError();
}

return await wrapperOptions.client.bulkUpdate(objects, options);
};

Expand All @@ -212,7 +244,7 @@ export class WorkspaceSavedObjectsClientWrapper {
options: SavedObjectsCreateOptions = {}
): Promise<SavedObjectsBulkResponse<T>> => {
if (options.workspaces) {
await this.validateMultiWorkspacesPermissions(options.workspaces, wrapperOptions.request, [
await this.validateMultiObjectsPermissions(options.workspaces, wrapperOptions.request, [
WorkspacePermissionMode.Write,
WorkspacePermissionMode.Management,
]);
Expand All @@ -226,7 +258,7 @@ export class WorkspaceSavedObjectsClientWrapper {
options?: SavedObjectsCreateOptions
) => {
if (isWorkspacesLikeAttributes(attributes)) {
await this.validateMultiWorkspacesPermissions(
await this.validateMultiObjectsPermissions(
attributes.workspaces,
wrapperOptions.request,
WorkspacePermissionMode.Management
Expand All @@ -240,6 +272,20 @@ export class WorkspaceSavedObjectsClientWrapper {
id: string,
options: SavedObjectsBaseOptions = {}
): Promise<SavedObject<T>> => {
if (this.isRelatedToWorkspace(type)) {
await this.validateSingleObjectPermissions(id, wrapperOptions.request, [
WorkspacePermissionMode.LibraryRead,
WorkspacePermissionMode.Management,
]);
} else {
await this.validateSingleObjectPermissions(
id,
wrapperOptions.request,
[WorkspacePermissionMode.Read],
type
);
}

const objectToGet = await wrapperOptions.client.get<T>(type, id, options);
await this.validateAtLeastOnePermittedWorkspaces(
objectToGet.workspaces,
Expand All @@ -253,6 +299,38 @@ export class WorkspaceSavedObjectsClientWrapper {
objects: SavedObjectsBulkGetObject[] = [],
options: SavedObjectsBaseOptions = {}
): Promise<SavedObjectsBulkResponse<T>> => {
const workspaceIds: string[] = [];
const nonWorkspaceObjects: SavedObjectsBulkGetObject[] = [];
objects.forEach((obj) => {
if (this.isRelatedToWorkspace(obj.type)) {
workspaceIds.push(obj.id);
} else {
nonWorkspaceObjects.push(obj);
}
});

const permittedWorkspaceIds =
(await this.permissionControl.getPermittedWorkspaceIds(wrapperOptions.request, [
WorkspacePermissionMode.LibraryRead,
WorkspacePermissionMode.Management,
])) ?? [];
const workspacePermitted = workspaceIds.every((id) => permittedWorkspaceIds.includes(id));
if (!workspacePermitted) {
throw generateWorkspacePermissionError();
}

// saved_objects
const objectsPermitted = await this.permissionControl.batchValidate(
wrapperOptions.request,
nonWorkspaceObjects.map((savedObj) => ({
...savedObj,
})),
[WorkspacePermissionMode.Read]
);
if (!objectsPermitted) {
throw generateSavedObjectsPermissionError();
}

const objectToBulkGet = await wrapperOptions.client.bulkGet<T>(objects, options);
for (const object of objectToBulkGet.saved_objects) {
await this.validateAtLeastOnePermittedWorkspaces(
Expand Down Expand Up @@ -346,7 +424,7 @@ export class WorkspaceSavedObjectsClientWrapper {
options: SavedObjectsAddToWorkspacesOptions = {}
) => {
// target workspaces
await this.validateMultiWorkspacesPermissions(targetWorkspaces, wrapperOptions.request, [
await this.validateMultiObjectsPermissions(targetWorkspaces, wrapperOptions.request, [
WorkspacePermissionMode.LibraryWrite,
WorkspacePermissionMode.Management,
]);
Expand Down

0 comments on commit a1cc4f7

Please sign in to comment.