Skip to content

Commit

Permalink
ensureSavedObjectsAreAuthorized for getTags & getReporters
Browse files Browse the repository at this point in the history
  • Loading branch information
cnasikas committed Apr 23, 2021
1 parent 157e834 commit 4d6fbe7
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 82 deletions.
62 changes: 55 additions & 7 deletions x-pack/plugins/cases/server/client/cases/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,42 @@ export async function getTags(
fold(throwErrors(Boom.badRequest), identity)
);

const { filter: authorizationFilter } = await getAuthorizationFilter({
const {
filter: authorizationFilter,
ensureSavedObjectsAreAuthorized,
logSuccessfulAuthorization,
} = await getAuthorizationFilter({
authorization: auth,
operation: Operations.findCases,
auditLogger,
});

const filter = combineAuthorizedAndOwnerFilter(queryParams.owner, authorizationFilter);

// TODO: ensureSavedObjectsAreAuthorized + logSuccessfulAuthorization if possible
return await caseService.getTags({
const cases = await caseService.getTags({
soClient,
filter,
});

const tags = new Set<string>();
const mappedCases: Array<{
owner: string;
id: string;
}> = [];

// Gather all necessary information in one pass
cases.saved_objects.forEach((theCase) => {
theCase.attributes.tags.forEach((tag) => tags.add(tag));
mappedCases.push({
id: theCase.id,
owner: theCase.attributes.owner,
});
});

ensureSavedObjectsAreAuthorized(mappedCases);
logSuccessfulAuthorization();

return [...tags.values()];
} catch (error) {
throw createCaseError({ message: `Failed to get tags: ${error}`, error, logger });
}
Expand All @@ -179,21 +202,46 @@ export async function getReporters(
fold(throwErrors(Boom.badRequest), identity)
);

const { filter: authorizationFilter } = await getAuthorizationFilter({
const {
filter: authorizationFilter,
ensureSavedObjectsAreAuthorized,
logSuccessfulAuthorization,
} = await getAuthorizationFilter({
authorization: auth,
operation: Operations.getReporters,
auditLogger,
});

const filter = combineAuthorizedAndOwnerFilter(queryParams.owner, authorizationFilter);

// TODO: ensureSavedObjectsAreAuthorized + logSuccessfulAuthorization if possible
const reporters = await caseService.getReporters({
const cases = await caseService.getReporters({
soClient,
filter,
});

return UsersRt.encode(reporters);
const reporters = new Map<string, User>();
const mappedCases: Array<{
owner: string;
id: string;
}> = [];

// Gather all necessary information in one pass
cases.saved_objects.forEach((theCase) => {
const user = theCase.attributes.created_by;
if (user.username != null) {
reporters.set(user.username, user);
}

mappedCases.push({
id: theCase.id,
owner: theCase.attributes.owner,
});
});

ensureSavedObjectsAreAuthorized(mappedCases);
logSuccessfulAuthorization();

return UsersRt.encode([...reporters.values()]);
} catch (error) {
throw createCaseError({ message: `Failed to get reporters: ${error}`, error, logger });
}
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/cases/server/client/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export const combineAuthorizedAndOwnerFilter = (

return authorizationFilter != null && ownerFilter != null
? combineFilterWithAuthorizationFilter(ownerFilter, authorizationFilter)
: ownerFilter ?? undefined;
: authorizationFilter ?? ownerFilter ?? undefined;
};

/**
Expand Down
44 changes: 39 additions & 5 deletions x-pack/plugins/cases/server/services/cases/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import {
SUB_CASE_SAVED_OBJECT,
} from '../../../common/constants';
import { readReporters } from './read_reporters';
import { readTags } from './read_tags';
import { ClientArgs } from '..';

interface PushedArgs {
Expand Down Expand Up @@ -916,19 +915,54 @@ export class CaseService {
}
}

public async getReporters({ soClient, filter }: GetReportersArgs) {
public async getReporters({
soClient,
filter,
}: GetReportersArgs): Promise<SavedObjectsFindResponse<ESCaseAttributes>> {
try {
this.log.debug(`Attempting to GET all reporters`);
return await readReporters({ soClient, filter });
const firstReporters = await soClient.find({
type: CASE_SAVED_OBJECT,
fields: ['created_by', 'owner'],
page: 1,
perPage: 1,
filter: cloneDeep(filter),
});

return await soClient.find<ESCaseAttributes>({
type: CASE_SAVED_OBJECT,
fields: ['created_by', 'owner'],
page: 1,
perPage: firstReporters.total,
filter: cloneDeep(filter),
});
} catch (error) {
this.log.error(`Error on GET all reporters: ${error}`);
throw error;
}
}
public async getTags({ soClient, filter }: GetTagsArgs) {

public async getTags({
soClient,
filter,
}: GetTagsArgs): Promise<SavedObjectsFindResponse<ESCaseAttributes>> {
try {
this.log.debug(`Attempting to GET all cases`);
return await readTags({ soClient, filter });
const firstTags = await soClient.find({
type: CASE_SAVED_OBJECT,
fields: ['tags', 'owner'],
page: 1,
perPage: 1,
filter: cloneDeep(filter),
});

return await soClient.find<ESCaseAttributes>({
type: CASE_SAVED_OBJECT,
fields: ['tags', 'owner'],
page: 1,
perPage: firstTags.total,
filter: cloneDeep(filter),
});
} catch (error) {
this.log.error(`Error on GET cases: ${error}`);
throw error;
Expand Down
68 changes: 0 additions & 68 deletions x-pack/plugins/cases/server/services/cases/read_tags.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ export default ({ getService }: FtrProviderContext): void => {
expect(reporters).to.eql([defaultUser]);
});

it('should return unique reporters', async () => {
await createCase(supertest, getPostCaseRequest());
await createCase(supertest, getPostCaseRequest());
const reporters = await getReporters({ supertest: supertestWithoutAuth });

expect(reporters).to.eql([defaultUser]);
});

describe('rbac', () => {
it('User: security solution only - should read the correct reporters', async () => {
await createCase(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,16 @@ export default ({ getService }: FtrProviderContext): void => {
expect(tags).to.eql(['defacement', 'unique']);
});

it('should return unique tags', async () => {
await createCase(supertest, getPostCaseRequest());
await createCase(supertest, getPostCaseRequest());

const tags = await getTags({ supertest });
expect(tags).to.eql(['defacement']);
});

describe('rbac', () => {
it('User: security solution only - should read the correct tags', async () => {
it('should read the correct tags', async () => {
await createCase(
supertestWithoutAuth,
getPostCaseRequest({ owner: 'securitySolutionFixture', tags: ['sec'] }),
Expand Down

0 comments on commit 4d6fbe7

Please sign in to comment.