Skip to content

Commit

Permalink
[Cases] Restrict searchFields, sortField and remove rootSearchFields …
Browse files Browse the repository at this point in the history
…from find_cases API (#162245)

## Summary

This PR modifies` find_cases API` with below changes
- [x] Restrict `searchFields` only to the `title` and the `description`
- [x] Restrict `sortField` to: `title`, `category`, `createdAt`,
`updatedAt`, `status`, and `severity`
- [x] Remove `rootSearchFields`

### Checklist

Delete any items that are not applicable to this PR.

- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

### For maintainers

- [x] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
js-jankisalvi and kibanamachine authored Jul 24, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 800f8dd commit 0af4e7e
Showing 14 changed files with 176 additions and 162 deletions.
60 changes: 57 additions & 3 deletions x-pack/plugins/cases/common/api/cases/case.test.ts
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
* 2.0.
*/

import { PathReporter } from 'io-ts/lib/PathReporter';
import { ConnectorTypes } from '../../types/domain/connector/v1';
import {
RelatedCaseInfoRt,
@@ -25,6 +26,8 @@ import {
CasesRt,
CasesFindResponseRt,
CaseResolveResponseRt,
CasesFindRequestSearchFieldsRt,
CasesFindRequestSortFieldsRt,
} from './case';
import { CommentType } from './comment';
import { CaseStatuses } from './status';
@@ -336,11 +339,10 @@ describe('Case', () => {
page: '1',
perPage: '10',
search: 'search text',
searchFields: 'closed_by.username',
rootSearchFields: ['_id'],
searchFields: ['title', 'description'],
to: '1w',
sortOrder: 'desc',
sortField: 'created_at',
sortField: 'createdAt',
owner: 'cases',
};

@@ -361,6 +363,58 @@ describe('Case', () => {
right: { ...defaultRequest, page: 1, perPage: 10 },
});
});

const searchFields = Object.keys(CasesFindRequestSearchFieldsRt.keys);

it.each(searchFields)('succeeds with %s as searchFields', (field) => {
const query = CasesFindRequestRt.decode({ ...defaultRequest, searchFields: field });

expect(query).toStrictEqual({
_tag: 'Right',
right: { ...defaultRequest, searchFields: field, page: 1, perPage: 10 },
});
});

const sortFields = Object.keys(CasesFindRequestSortFieldsRt.keys);

it.each(sortFields)('succeeds with %s as sortField', (sortField) => {
const query = CasesFindRequestRt.decode({ ...defaultRequest, sortField });

expect(query).toStrictEqual({
_tag: 'Right',
right: { ...defaultRequest, sortField, page: 1, perPage: 10 },
});
});

it('removes rootSearchField when passed', () => {
expect(
PathReporter.report(
CasesFindRequestRt.decode({ ...defaultRequest, rootSearchField: ['foobar'] })
)
).toContain('No errors!');
});

describe('errors', () => {
it('throws error when invalid searchField passed', () => {
expect(
PathReporter.report(
CasesFindRequestRt.decode({ ...defaultRequest, searchFields: 'foobar' })
)
).not.toContain('No errors!');
});

it('throws error when invalid sortField passed', () => {
expect(
PathReporter.report(CasesFindRequestRt.decode({ ...defaultRequest, sortField: 'foobar' }))
).not.toContain('No errors!');
});

it('succeeds when valid parameters passed', () => {
expect(PathReporter.report(CasesFindRequestRt.decode(defaultRequest))).toContain(
'No errors!'
);
});
});
});

describe('CasesByAlertIDRequestRt', () => {
42 changes: 13 additions & 29 deletions x-pack/plugins/cases/common/api/cases/case.ts
Original file line number Diff line number Diff line change
@@ -205,32 +205,19 @@ export const CasePostRequestRt = rt.intersection([
),
]);

const CasesFindRequestSearchFieldsRt = rt.keyof({
'closed_by.username': null,
'closed_by.full_name': null,
'closed_by.email': null,
'closed_by.profile_uid': null,
'created_by.username': null,
'created_by.full_name': null,
'created_by.email': null,
'created_by.profile_uid': null,
export const CasesFindRequestSearchFieldsRt = rt.keyof({
description: null,
'connector.name': null,
'connector.type': null,
'external_service.pushed_by.username': null,
'external_service.pushed_by.full_name': null,
'external_service.pushed_by.email': null,
'external_service.pushed_by.profile_uid': null,
'external_service.connector_name': null,
'external_service.external_id': null,
'external_service.external_title': null,
'external_service.external_url': null,
title: null,
'title.keyword': null,
'updated_by.username': null,
'updated_by.full_name': null,
'updated_by.email': null,
'updated_by.profile_uid': null,
});

export const CasesFindRequestSortFieldsRt = rt.keyof({
title: null,
category: null,
createdAt: null,
updatedAt: null,
closedAt: null,
status: null,
severity: null,
});

export const CasesFindRequestRt = rt.intersection([
@@ -307,15 +294,11 @@ export const CasesFindRequestRt = rt.intersection([
rt.array(CasesFindRequestSearchFieldsRt),
CasesFindRequestSearchFieldsRt,
]),
/**
* The root fields to perform the simple_query_string parsed query against
*/
rootSearchFields: rt.array(rt.string),
/**
* The field to use for sorting the found objects.
*
*/
sortField: rt.string,
sortField: CasesFindRequestSortFieldsRt,
/**
* The order to sort by
*/
@@ -551,6 +534,7 @@ export type Cases = rt.TypeOf<typeof CasesRt>;
export type CasesDeleteRequest = rt.TypeOf<typeof CasesDeleteRequestRt>;
export type CasesByAlertIDRequest = rt.TypeOf<typeof CasesByAlertIDRequestRt>;
export type CasesFindRequest = rt.TypeOf<typeof CasesFindRequestRt>;
export type CasesFindRequestSortFields = rt.TypeOf<typeof CasesFindRequestSortFieldsRt>;
export type CasesFindResponse = rt.TypeOf<typeof CasesFindResponseRt>;
export type CasePatchRequest = rt.TypeOf<typeof CasePatchRequestRt>;
export type CasesPatchRequest = rt.TypeOf<typeof CasesPatchRequestRt>;
62 changes: 22 additions & 40 deletions x-pack/plugins/cases/docs/openapi/bundled.json
Original file line number Diff line number Diff line change
@@ -12,18 +12,26 @@
"url": "https://www.elastic.co/licensing/elastic-license"
}
},
"tags": [
{
"name": "cases",
"description": "Case APIs enable you to open and track issues."
}
],
"servers": [
{
"url": "http://localhost:5601",
"description": "local"
}
],
"security": [
{
"basicAuth": []
},
{
"apiKeyAuth": []
}
],
"tags": [
{
"name": "cases",
"description": "Case APIs enable you to open and track issues."
}
],
"paths": {
"/api/cases": {
"post": {
@@ -3977,7 +3985,12 @@
"type": "string",
"enum": [
"createdAt",
"updatedAt"
"updatedAt",
"closedAt",
"title",
"category",
"status",
"severity"
],
"default": "createdAt"
},
@@ -5286,31 +5299,8 @@
"type": "string",
"description": "The fields to perform the `simple_query_string` parsed query against.",
"enum": [
"closed_by.username",
"closed_by.full_name",
"closed_by.email",
"closed_by.profile_uid",
"created_by.username",
"created_by.full_name",
"created_by.email",
"created_by.profile_uid",
"description",
"connector.name",
"connector.type",
"external_service.pushed_by.username",
"external_service.pushed_by.full_name",
"external_service.pushed_by.email",
"external_service.pushed_by.profile_uid",
"external_service.connector_name",
"external_service.external_id",
"external_service.external_title",
"external_service.external_url",
"title",
"title.keyword",
"updated_by.username",
"updated_by.full_name",
"updated_by.email",
"updated_by.profile_uid"
"title"
]
},
"closure_types": {
@@ -7151,13 +7141,5 @@
]
}
}
},
"security": [
{
"basicAuth": []
},
{
"apiKeyAuth": []
}
]
}
}
40 changes: 11 additions & 29 deletions x-pack/plugins/cases/docs/openapi/bundled.yaml
Original file line number Diff line number Diff line change
@@ -8,12 +8,15 @@ info:
license:
name: Elastic License 2.0
url: https://www.elastic.co/licensing/elastic-license
tags:
- name: cases
description: Case APIs enable you to open and track issues.
servers:
- url: http://localhost:5601
description: local
security:
- basicAuth: []
- apiKeyAuth: []
tags:
- name: cases
description: Case APIs enable you to open and track issues.
paths:
/api/cases:
post:
@@ -2427,6 +2430,11 @@ components:
enum:
- createdAt
- updatedAt
- closedAt
- title
- category
- status
- severity
default: createdAt
example: updatedAt
sort_order:
@@ -3392,31 +3400,8 @@ components:
type: string
description: The fields to perform the `simple_query_string` parsed query against.
enum:
- closed_by.username
- closed_by.full_name
- closed_by.email
- closed_by.profile_uid
- created_by.username
- created_by.full_name
- created_by.email
- created_by.profile_uid
- description
- connector.name
- connector.type
- external_service.pushed_by.username
- external_service.pushed_by.full_name
- external_service.pushed_by.email
- external_service.pushed_by.profile_uid
- external_service.connector_name
- external_service.external_id
- external_service.external_title
- external_service.external_url
- title
- title.keyword
- updated_by.username
- updated_by.full_name
- updated_by.email
- updated_by.profile_uid
closure_types:
type: string
description: Indicates whether a case is automatically closed when it is pushed to external systems (`close-by-pushing`) or not automatically closed (`close-by-user`).
@@ -4768,6 +4753,3 @@ components:
isPreconfigured: false
isDeprecated: false
referencedByCount: 0
security:
- basicAuth: []
- apiKeyAuth: []
Original file line number Diff line number Diff line change
@@ -1,28 +1,5 @@
type: string
description: The fields to perform the `simple_query_string` parsed query against.
enum:
- closed_by.username
- closed_by.full_name
- closed_by.email
- closed_by.profile_uid
- created_by.username
- created_by.full_name
- created_by.email
- created_by.profile_uid
- description
- connector.name
- connector.type
- external_service.pushed_by.username
- external_service.pushed_by.full_name
- external_service.pushed_by.email
- external_service.pushed_by.profile_uid
- external_service.connector_name
- external_service.external_id
- external_service.external_title
- external_service.external_url
- title
- title.keyword
- updated_by.username
- updated_by.full_name
- updated_by.email
- updated_by.profile_uid
Original file line number Diff line number Diff line change
@@ -6,5 +6,10 @@ schema:
enum:
- createdAt
- updatedAt
- closedAt
- title
- category
- status
- severity
default: createdAt
example: updatedAt
Loading

0 comments on commit 0af4e7e

Please sign in to comment.