From 532f240942376eda0ba3f7c9badc265805def83f Mon Sep 17 00:00:00 2001 From: adcoelho Date: Tue, 20 Jun 2023 12:11:59 +0200 Subject: [PATCH 1/4] Limit the category param in find cases API. Tests. --- x-pack/plugins/cases/common/constants/index.ts | 1 + .../cases/server/client/cases/find.test.ts | 11 +++++++++++ .../plugins/cases/server/client/cases/find.ts | 17 +++++++++++++++-- .../tests/common/cases/find_cases.ts | 8 +++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/cases/common/constants/index.ts b/x-pack/plugins/cases/common/constants/index.ts index 0407315328dfb..33473a9c80bfd 100644 --- a/x-pack/plugins/cases/common/constants/index.ts +++ b/x-pack/plugins/cases/common/constants/index.ts @@ -104,6 +104,7 @@ export const MAX_DOCS_PER_PAGE = 10000 as const; export const MAX_BULK_GET_ATTACHMENTS = MAX_DOCS_PER_PAGE; export const MAX_CONCURRENT_SEARCHES = 10 as const; export const MAX_BULK_GET_CASES = 1000 as const; +export const MAX_CATEGORY_FILTER_LENGTH = 100 as const; /** * Validation diff --git a/x-pack/plugins/cases/server/client/cases/find.test.ts b/x-pack/plugins/cases/server/client/cases/find.test.ts index 1e5afd2c87b36..689529f33454c 100644 --- a/x-pack/plugins/cases/server/client/cases/find.test.ts +++ b/x-pack/plugins/cases/server/client/cases/find.test.ts @@ -8,6 +8,7 @@ import { v1 as uuidv1 } from 'uuid'; import type { Case } from '../../../common/api'; +import { MAX_CATEGORY_FILTER_LENGTH } from '../../../common/constants'; import { flattenCaseSavedObject } from '../../common/utils'; import { mockCases } from '../../mocks'; import { createCasesClientMockArgs, createCasesClientMockFindRequest } from '../mocks'; @@ -103,5 +104,15 @@ describe('find', () => { 'Error: Invalid value "foobar" supplied to "searchFields"' ); }); + + it(`invalid category array with > ${MAX_CATEGORY_FILTER_LENGTH} items`, async () => { + const category = Array(MAX_CATEGORY_FILTER_LENGTH + 1).fill('foobar'); + + const findRequest = createCasesClientMockFindRequest({ category }); + + await expect(find(findRequest, clientArgs)).rejects.toThrow( + `Error: Too many categories provided. The maximum allowed is ${MAX_CATEGORY_FILTER_LENGTH}` + ); + }); }); }); diff --git a/x-pack/plugins/cases/server/client/cases/find.ts b/x-pack/plugins/cases/server/client/cases/find.ts index 8e9e68f79d66b..aa2bb36768207 100644 --- a/x-pack/plugins/cases/server/client/cases/find.ts +++ b/x-pack/plugins/cases/server/client/cases/find.ts @@ -8,6 +8,7 @@ import { isEmpty } from 'lodash'; import Boom from '@hapi/boom'; +import { MAX_CATEGORY_FILTER_LENGTH } from '../../../common/constants'; import type { CasesFindResponse, CasesFindRequest } from '../../../common/api'; import { CasesFindRequestRt, @@ -24,6 +25,16 @@ import { LICENSING_CASE_ASSIGNMENT_FEATURE } from '../../common/constants'; import type { CasesFindQueryParams } from '../types'; import { decodeOrThrow } from '../../../common/api/runtime_types'; +/** + * Throws an error if the user tries to filter by more than MAX_CATEGORY_FILTER_LENGTH categories. + */ +function throwIfCategoryParamTooLong(category?: string[] | string) { + if (Array.isArray(category) && category.length > MAX_CATEGORY_FILTER_LENGTH) + throw Boom.badRequest( + `Too many categories provided. The maximum allowed is ${MAX_CATEGORY_FILTER_LENGTH}` + ); +} + /** * Retrieves a case and optionally its comments. * @@ -44,8 +55,7 @@ export const find = async ( try { const queryParams = decodeWithExcessOrThrow(CasesFindRequestRt)(params); - const { filter: authorizationFilter, ensureSavedObjectsAreAuthorized } = - await authorization.getAuthorizationFilter(Operations.findCases); + throwIfCategoryParamTooLong(queryParams.category); /** * Assign users to a case is only available to Platinum+ @@ -63,6 +73,9 @@ export const find = async ( licensingService.notifyUsage(LICENSING_CASE_ASSIGNMENT_FEATURE); } + const { filter: authorizationFilter, ensureSavedObjectsAreAuthorized } = + await authorization.getAuthorizationFilter(Operations.findCases); + const queryArgs: CasesFindQueryParams = { tags: queryParams.tags, reporters: queryParams.reporters, diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts index 60b1e789ec775..bfea368604766 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts @@ -8,7 +8,7 @@ import { v1 as uuidv1 } from 'uuid'; import expect from '@kbn/expect'; -import { CASES_URL } from '@kbn/cases-plugin/common/constants'; +import { CASES_URL, MAX_CATEGORY_FILTER_LENGTH } from '@kbn/cases-plugin/common/constants'; import { Case, CaseSeverity, CaseStatuses, CommentType } from '@kbn/cases-plugin/common/api'; import { ALERTING_CASES_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server'; import { FtrProviderContext } from '../../../../common/ftr_provider_context'; @@ -349,6 +349,12 @@ export default ({ getService }: FtrProviderContext): void => { }); }); + it('unhappy path - 400s when bad category field supplied', async () => { + const category = Array(MAX_CATEGORY_FILTER_LENGTH + 1).fill('foobar'); + + await findCases({ supertest, query: { category }, expectedHttpCode: 400 }); + }); + describe('search and searchField', () => { beforeEach(async () => { await createCase(supertest, postCaseReq); From e5f8a7bdb63465895028ee233d3747c0f23b1198 Mon Sep 17 00:00:00 2001 From: adcoelho Date: Tue, 20 Jun 2023 13:48:36 +0200 Subject: [PATCH 2/4] Update find cases API documentation. --- .../plugins/cases/docs/openapi/bundled.json | 19 +++++++++++++++++++ .../plugins/cases/docs/openapi/bundled.yaml | 10 ++++++++++ .../paths/s@{spaceid}@api@cases@_find.yaml | 10 ++++++++++ 3 files changed, 39 insertions(+) diff --git a/x-pack/plugins/cases/docs/openapi/bundled.json b/x-pack/plugins/cases/docs/openapi/bundled.json index aee1e1aa751a5..4689e8be04f43 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.json +++ b/x-pack/plugins/cases/docs/openapi/bundled.json @@ -362,6 +362,25 @@ }, "example": "tag-1" }, + { + "name": "category", + "in": "query", + "description": "Filters the returned cases by category. Limited to 100 categories.", + "schema": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "example": "my-category" + }, { "name": "to", "in": "query", diff --git a/x-pack/plugins/cases/docs/openapi/bundled.yaml b/x-pack/plugins/cases/docs/openapi/bundled.yaml index 8b93529b76b7e..d7c0fed15e446 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.yaml +++ b/x-pack/plugins/cases/docs/openapi/bundled.yaml @@ -213,6 +213,16 @@ paths: items: type: string example: tag-1 + - name: category + in: query + description: Filters the returned cases by category. Limited to 100 categories. + schema: + oneOf: + - type: string + - type: array + items: + type: string + example: my-category - name: to in: query description: | diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml index 4ddd52db231f2..bed1182316437 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml @@ -96,6 +96,16 @@ get: items: type: string example: tag-1 + - name: category + in: query + description: Filters the returned cases by category. Limited to 100 categories. + schema: + oneOf: + - type: string + - type: array + items: + type: string + example: my-category - name: to in: query description: > From d54736d8776f6985958423536c24bda1b7175734 Mon Sep 17 00:00:00 2001 From: adcoelho Date: Tue, 20 Jun 2023 14:48:46 +0200 Subject: [PATCH 3/4] Addressing PR comments. --- x-pack/plugins/cases/server/client/cases/find.test.ts | 2 +- .../security_and_spaces/tests/common/cases/find_cases.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/cases/server/client/cases/find.test.ts b/x-pack/plugins/cases/server/client/cases/find.test.ts index 689529f33454c..968f111b58516 100644 --- a/x-pack/plugins/cases/server/client/cases/find.test.ts +++ b/x-pack/plugins/cases/server/client/cases/find.test.ts @@ -105,7 +105,7 @@ describe('find', () => { ); }); - it(`invalid category array with > ${MAX_CATEGORY_FILTER_LENGTH} items`, async () => { + it(`throws an error when the category array has ${MAX_CATEGORY_FILTER_LENGTH} items`, async () => { const category = Array(MAX_CATEGORY_FILTER_LENGTH + 1).fill('foobar'); const findRequest = createCasesClientMockFindRequest({ category }); diff --git a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts index bfea368604766..00bdaa5b25f0b 100644 --- a/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts +++ b/x-pack/test/cases_api_integration/security_and_spaces/tests/common/cases/find_cases.ts @@ -349,7 +349,7 @@ export default ({ getService }: FtrProviderContext): void => { }); }); - it('unhappy path - 400s when bad category field supplied', async () => { + it('unhappy path - 400s when more than the maximum category fields are supplied', async () => { const category = Array(MAX_CATEGORY_FILTER_LENGTH + 1).fill('foobar'); await findCases({ supertest, query: { category }, expectedHttpCode: 400 }); From b30642342c316cebb8b557bbec14d0a13c106005 Mon Sep 17 00:00:00 2001 From: lcawl Date: Tue, 20 Jun 2023 08:32:30 -0700 Subject: [PATCH 4/4] [DOCS] Sort query parameter order; generate preview docs --- .../cases/case-apis-passthru.asciidoc | 4 +- .../plugins/cases/docs/openapi/bundled.json | 38 +++++++++---------- .../plugins/cases/docs/openapi/bundled.yaml | 20 +++++----- .../paths/s@{spaceid}@api@cases@_find.yaml | 20 +++++----- 4 files changed, 42 insertions(+), 40 deletions(-) diff --git a/docs/api-generated/cases/case-apis-passthru.asciidoc b/docs/api-generated/cases/case-apis-passthru.asciidoc index d983ab1d2a099..d0e7a67c50660 100644 --- a/docs/api-generated/cases/case-apis-passthru.asciidoc +++ b/docs/api-generated/cases/case-apis-passthru.asciidoc @@ -724,7 +724,9 @@ Any modifications made to this file will be overwritten.
assignees (optional)
-
Query Parameter — Filters the returned cases by assignees. Valid values are none or unique identifiers for the user profiles. These identifiers can be found by using the suggest user profile API. default: null
defaultSearchOperator (optional)
+
Query Parameter — Filters the returned cases by assignees. Valid values are none or unique identifiers for the user profiles. These identifiers can be found by using the suggest user profile API. default: null
category (optional)
+ +
Query Parameter — Filters the returned cases by category. Limited to 100 categories. default: null
defaultSearchOperator (optional)
Query Parameter — The default operator to use for the simple_query_string. default: OR
from (optional)
diff --git a/x-pack/plugins/cases/docs/openapi/bundled.json b/x-pack/plugins/cases/docs/openapi/bundled.json index 4689e8be04f43..92dcfe5779306 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.json +++ b/x-pack/plugins/cases/docs/openapi/bundled.json @@ -236,6 +236,25 @@ ] } }, + { + "name": "category", + "in": "query", + "description": "Filters the returned cases by category. Limited to 100 categories.", + "schema": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "example": "my-category" + }, { "name": "defaultSearchOperator", "in": "query", @@ -362,25 +381,6 @@ }, "example": "tag-1" }, - { - "name": "category", - "in": "query", - "description": "Filters the returned cases by category. Limited to 100 categories.", - "schema": { - "oneOf": [ - { - "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "example": "my-category" - }, { "name": "to", "in": "query", diff --git a/x-pack/plugins/cases/docs/openapi/bundled.yaml b/x-pack/plugins/cases/docs/openapi/bundled.yaml index d7c0fed15e446..3d53916c89df8 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.yaml +++ b/x-pack/plugins/cases/docs/openapi/bundled.yaml @@ -140,6 +140,16 @@ paths: - type: array items: type: string + - name: category + in: query + description: Filters the returned cases by category. Limited to 100 categories. + schema: + oneOf: + - type: string + - type: array + items: + type: string + example: my-category - name: defaultSearchOperator in: query description: The default operator to use for the simple_query_string. @@ -213,16 +223,6 @@ paths: items: type: string example: tag-1 - - name: category - in: query - description: Filters the returned cases by category. Limited to 100 categories. - schema: - oneOf: - - type: string - - type: array - items: - type: string - example: my-category - name: to in: query description: | diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml index bed1182316437..e04fbfe020c9f 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@_find.yaml @@ -18,6 +18,16 @@ get: - type: array items: type: string + - name: category + in: query + description: Filters the returned cases by category. Limited to 100 categories. + schema: + oneOf: + - type: string + - type: array + items: + type: string + example: my-category - name: defaultSearchOperator in: query description: The default operator to use for the simple_query_string. @@ -96,16 +106,6 @@ get: items: type: string example: tag-1 - - name: category - in: query - description: Filters the returned cases by category. Limited to 100 categories. - schema: - oneOf: - - type: string - - type: array - items: - type: string - example: my-category - name: to in: query description: >