Skip to content

Commit

Permalink
Working status tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathan-buttner committed Apr 30, 2021
1 parent 0d39f83 commit 8543b5b
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 42 deletions.
2 changes: 1 addition & 1 deletion x-pack/plugins/cases/common/api/cases/case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { CommentResponseRt } from './comment';
import { CasesStatusResponseRt, CaseStatusRt } from './status';
import { CaseConnectorRt, ESCaseConnector } from '../connectors';
import { SubCaseResponseRt } from './sub_case';
import { OWNER_FIELD } from '.';
import { OWNER_FIELD } from './constants';

export enum CaseType {
collection = 'collection',
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/cases/common/api/cases/comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import * as rt from 'io-ts';
import { OWNER_FIELD } from '.';
import { OWNER_FIELD } from './constants';
import { SavedObjectFindOptionsRt } from '../saved_object';

import { UserRT } from '../user';
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/cases/common/api/cases/configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as rt from 'io-ts';
import { UserRT } from '../user';
import { CaseConnectorRt, ConnectorMappingsRt, ESCaseConnector } from '../connectors';
import { OmitProp } from '../runtime_types';
import { OWNER_FIELD } from '.';
import { OWNER_FIELD } from './constants';

// TODO: we will need to add this type rt.literal('close-by-third-party')
const ClosureTypeRT = rt.union([rt.literal('close-by-user'), rt.literal('close-by-pushing')]);
Expand Down
11 changes: 11 additions & 0 deletions x-pack/plugins/cases/common/api/cases/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

/**
* The field used for authorization in various entities within cases.
*/
export const OWNER_FIELD = 'owner';
6 changes: 1 addition & 5 deletions x-pack/plugins/cases/common/api/cases/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,4 @@ export * from './comment';
export * from './status';
export * from './user_actions';
export * from './sub_case';

/**
* The field used for authorization in various entities within cases.
*/
export const OWNER_FIELD = 'owner';
export * from './constants';
2 changes: 1 addition & 1 deletion x-pack/plugins/cases/common/api/cases/user_actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import * as rt from 'io-ts';
import { OWNER_FIELD } from '.';
import { OWNER_FIELD } from './constants';

import { UserRT } from '../user';

Expand Down
6 changes: 0 additions & 6 deletions x-pack/plugins/cases/server/client/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,12 +571,6 @@ interface OwnerEntity {
id: string;
}

interface AuthFilterHelpers {
filter?: KueryNode;
ensureSavedObjectsAreAuthorized: (entities: OwnerEntity[]) => void;
logSuccessfulAuthorization: () => void;
}

/**
* Function callback for making sure the found saved objects are of the authorized owner
*/
Expand Down
16 changes: 11 additions & 5 deletions x-pack/test/case_api_integration/common/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -853,12 +853,18 @@ export const updateConfiguration = async (
return configuration;
};

export const getAllCasesStatuses = async (
supertest: st.SuperTest<supertestAsPromised.Test>,
expectedHttpCode: number = 200
): Promise<CasesStatusResponse> => {
export const getAllCasesStatuses = async ({
supertest,
expectedHttpCode = 200,
auth = { user: superUser, space: null },
}: {
supertest: st.SuperTest<supertestAsPromised.Test>;
expectedHttpCode?: number;
auth?: { user: User; space: string | null };
}): Promise<CasesStatusResponse> => {
const { body: statuses } = await supertest
.get(CASE_STATUS_URL)
.get(`${getSpaceUrlPrefix(auth.space)}${CASE_STATUS_URL}`)
.auth(auth.user.username, auth.user.password)
.set('kbn-xsrf', 'true')
.expect(expectedHttpCode);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,25 @@
*/

import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../../../../common/ftr_provider_context';
import { FtrProviderContext } from '../../../../../common/ftr_provider_context';

import { CaseStatuses } from '../../../../../../../plugins/cases/common/api';
import { postCaseReq } from '../../../../../common/lib/mock';
import { getPostCaseRequest, postCaseReq } from '../../../../../common/lib/mock';
import {
deleteCasesByESQuery,
createCase,
updateCase,
getAllCasesStatuses,
deleteAllCaseItems,
} from '../../../../../common/lib/utils';
import {
globalRead,
noKibanaPrivileges,
obsOnlyRead,
obsSecRead,
secOnly,
secOnlyRead,
superUser,
} from '../../../../../common/lib/authentication/users';

// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
Expand All @@ -24,26 +33,15 @@ export default ({ getService }: FtrProviderContext): void => {

describe('get_status', () => {
afterEach(async () => {
await deleteCasesByESQuery(es);
await deleteAllCaseItems(es);
});

it('should return case statuses', async () => {
await createCase(supertest, postCaseReq);
const inProgressCase = await createCase(supertest, postCaseReq);
const postedCase = await createCase(supertest, postCaseReq);

await updateCase({
supertest,
params: {
cases: [
{
id: postedCase.id,
version: postedCase.version,
status: CaseStatuses.closed,
},
],
},
});
const [, inProgressCase, postedCase] = await Promise.all([
createCase(supertest, postCaseReq),
createCase(supertest, postCaseReq),
createCase(supertest, postCaseReq),
]);

await updateCase({
supertest,
Expand All @@ -54,11 +52,16 @@ export default ({ getService }: FtrProviderContext): void => {
version: inProgressCase.version,
status: CaseStatuses['in-progress'],
},
{
id: postedCase.id,
version: postedCase.version,
status: CaseStatuses.closed,
},
],
},
});

const statuses = await getAllCasesStatuses(supertest);
const statuses = await getAllCasesStatuses({ supertest });

expect(statuses).to.eql({
count_open_cases: 1,
Expand All @@ -68,7 +71,101 @@ export default ({ getService }: FtrProviderContext): void => {
});

describe('rbac', () => {
// TODO:
const supertestWithoutAuth = getService('supertestWithoutAuth');

it('should return the correct status stats', async () => {
/**
* Owner: Sec
* open: 0, in-prog: 1, closed: 1
* Owner: Obs
* open: 1, in-prog: 1
*/
const [inProgressSec, closedSec, , inProgressObs] = await Promise.all([
createCase(supertestWithoutAuth, getPostCaseRequest(), 200, {
user: superUser,
space: 'space1',
}),
createCase(supertestWithoutAuth, getPostCaseRequest(), 200, {
user: superUser,
space: 'space1',
}),
createCase(
supertestWithoutAuth,
getPostCaseRequest({ owner: 'observabilityFixture' }),
200,
{ user: superUser, space: 'space1' }
),
createCase(
supertestWithoutAuth,
getPostCaseRequest({ owner: 'observabilityFixture' }),
200,
{ user: superUser, space: 'space1' }
),
]);

await updateCase({
supertest: supertestWithoutAuth,
params: {
cases: [
{
id: inProgressSec.id,
version: inProgressSec.version,
status: CaseStatuses['in-progress'],
},
{
id: closedSec.id,
version: closedSec.version,
status: CaseStatuses.closed,
},
{
id: inProgressObs.id,
version: inProgressObs.version,
status: CaseStatuses['in-progress'],
},
],
},
auth: { user: superUser, space: 'space1' },
});

for (const scenario of [
{ user: globalRead, stats: { open: 1, inProgress: 2, closed: 1 } },
{ user: superUser, stats: { open: 1, inProgress: 2, closed: 1 } },
{ user: secOnlyRead, stats: { open: 0, inProgress: 1, closed: 1 } },
{ user: obsOnlyRead, stats: { open: 1, inProgress: 1, closed: 0 } },
{ user: obsSecRead, stats: { open: 1, inProgress: 2, closed: 1 } },
]) {
const statuses = await getAllCasesStatuses({
supertest: supertestWithoutAuth,
auth: { user: scenario.user, space: 'space1' },
});

expect(statuses).to.eql({
count_open_cases: scenario.stats.open,
count_closed_cases: scenario.stats.closed,
count_in_progress_cases: scenario.stats.inProgress,
});
}
});

for (const scenario of [
{ user: noKibanaPrivileges, space: 'space1' },
{ user: secOnly, space: 'space2' },
]) {
it(`should return a 403 when retrieving the statuses when the user ${
scenario.user.username
} with role(s) ${scenario.user.roles.join()} and space ${scenario.space}`, async () => {
await createCase(supertestWithoutAuth, getPostCaseRequest(), 200, {
user: superUser,
space: scenario.space,
});

await getAllCasesStatuses({
supertest: supertestWithoutAuth,
auth: { user: scenario.user, space: scenario.space },
expectedHttpCode: 403,
});
});
}
});
});
};

0 comments on commit 8543b5b

Please sign in to comment.