"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.ListClient = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _securitysolutionEsUtils = require("@kbn/securitysolution-es-utils"); var _items = require("../items"); var _list_item_policy = _interopRequireDefault(require("../items/list_item_policy.json")); var _list_policy = _interopRequireDefault(require("./list_policy.json")); var _create_list_if_it_does_not_exist = require("./create_list_if_it_does_not_exist"); var _ = require("."); /* * 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. */ /** * Class for use for value lists are are associated with exception lists. * See {@link https://www.elastic.co/guide/en/security/current/lists-api-create-container.html} */ class ListClient { /** Kibana space id the value lists are part of */ /** User creating, modifying, deleting, or updating a value list */ /** Configuration for determining things such as maximum sizes */ /** The elastic search client to do the queries with */ /** * Constructs the value list * @param options * @param options.spaceId Kibana space id the value lists are part of * @param options.user The user associated with the value list * @param options.config Configuration for determining things such as maximum sizes * @param options.esClient The elastic search client to do the queries with */ constructor({ spaceId: _spaceId, user: _user, config: _config, esClient: _esClient }) { (0, _defineProperty2.default)(this, "spaceId", void 0); (0, _defineProperty2.default)(this, "user", void 0); (0, _defineProperty2.default)(this, "config", void 0); (0, _defineProperty2.default)(this, "esClient", void 0); /** * Returns the list index name * @returns The list index name */ (0, _defineProperty2.default)(this, "getListIndex", () => { const { spaceId, config: { listIndex: listsIndexName } } = this; return (0, _.getListIndex)({ listsIndexName, spaceId }); }); /** * Returns the list item index name * @returns The list item index name */ (0, _defineProperty2.default)(this, "getListItemIndex", () => { const { spaceId, config: { listItemIndex: listsItemsIndexName } } = this; return (0, _items.getListItemIndex)({ listsItemsIndexName, spaceId }); }); /** * Given a list id, this will return the list container * @param options * @param options.id The id of the list * @returns The List container if found, otherwise null */ (0, _defineProperty2.default)(this, "getList", async ({ id }) => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _.getList)({ esClient, id, listIndex }); }); /** * Creates a list, if given at least the "name", "description", "type", and "version" * See {@link https://www.elastic.co/guide/en/security/current/lists-api-create-container.html} * for more information around formats of the deserializer and serializer * @param options * @param options.id The id of the list to create or "undefined" if you want an "id" to be auto-created for you * @param options.deserializer A custom deserializer for the list. Optionally, you an define this as handle bars. See online docs for more information. * @param options.immutable Set this to true if this is a list that is "immutable"/"pre-packaged". * @param options.serializer Determines how uploaded list item values are parsed. By default, list items are parsed using named regex groups. See online docs for more information. * @param options.name The name of the list * @param options.description The description of the list * @param options.type The type of list such as "boolean", "double", "text", "keyword", etc... * @param options.meta Additional meta data to associate with the list as an object of "key/value" pairs * @param options.version Version number of the list, typically this should be 1 unless you are re-creating a list you deleted or something unusual. * @returns The list created */ (0, _defineProperty2.default)(this, "createList", async ({ id, deserializer, immutable, serializer, name, description, type, meta, version }) => { const { esClient, user } = this; const listIndex = this.getListIndex(); return (0, _.createList)({ description, deserializer, esClient, id, immutable, listIndex, meta, name, serializer, type, user, version }); }); /** * Creates a list, if given at least the "name", "description", "type", and "version" * See {@link https://www.elastic.co/guide/en/security/current/lists-api-create-container.html} * for more information around formats of the deserializer and serializer. * This will create the list if it does not exist. If the list exists, this will ignore creating * anything and just return the existing list. * @param options * @param options.id The id of the list to create or "undefined" if you want an "id" to be auto-created for you * @param options.deserializer A custom deserializer for the list. Optionally, you an define this as handle bars. See online docs for more information. * @param options.immutable Set this to true if this is a list that is "immutable"/"pre-packaged". * @param options.serializer Determines how uploaded list item values are parsed. By default, list items are parsed using named regex groups. See online docs for more information. * @param options.name The name of the list * @param options.description The description of the list * @param options.type The type of list such as "boolean", "double", "text", "keyword", etc... * @param options.meta Additional meta data to associate with the list as an object of "key/value" pairs * @param options.version Version number of the list, typically this should be 1 unless you are re-creating a list you deleted or something unusual. * @returns The list created */ (0, _defineProperty2.default)(this, "createListIfItDoesNotExist", async ({ id, deserializer, serializer, name, description, immutable, type, meta, version }) => { const { esClient, user } = this; const listIndex = this.getListIndex(); return (0, _create_list_if_it_does_not_exist.createListIfItDoesNotExist)({ description, deserializer, esClient, id, immutable, listIndex, meta, name, serializer, type, user, version }); }); /** * True if the list index exists, otherwise false * @returns True if the list index exists, otherwise false */ (0, _defineProperty2.default)(this, "getListIndexExists", async () => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _securitysolutionEsUtils.getBootstrapIndexExists)(esClient, listIndex); }); /** * True if the list index item exists, otherwise false * @returns True if the list item index exists, otherwise false */ (0, _defineProperty2.default)(this, "getListItemIndexExists", async () => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _securitysolutionEsUtils.getBootstrapIndexExists)(esClient, listItemIndex); }); /** * Creates the list boot strap index for ILM policies. * @returns The contents of the bootstrap response from Elasticsearch */ (0, _defineProperty2.default)(this, "createListBootStrapIndex", async () => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _securitysolutionEsUtils.createBootstrapIndex)(esClient, listIndex); }); /** * Creates the list item boot strap index for ILM policies. * @returns The contents of the bootstrap response from Elasticsearch */ (0, _defineProperty2.default)(this, "createListItemBootStrapIndex", async () => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _securitysolutionEsUtils.createBootstrapIndex)(esClient, listItemIndex); }); /** * Returns true if the list policy for ILM exists, otherwise false * @returns True if the list policy for ILM exists, otherwise false. */ (0, _defineProperty2.default)(this, "getListPolicyExists", async () => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _securitysolutionEsUtils.getPolicyExists)(esClient, listIndex); }); /** * Returns true if the list item policy for ILM exists, otherwise false * @returns True if the list item policy for ILM exists, otherwise false. */ (0, _defineProperty2.default)(this, "getListItemPolicyExists", async () => { const { esClient } = this; const listsItemIndex = this.getListItemIndex(); return (0, _securitysolutionEsUtils.getPolicyExists)(esClient, listsItemIndex); }); /** * Returns true if the list template for ILM exists, otherwise false * @returns True if the list template for ILM exists, otherwise false. */ (0, _defineProperty2.default)(this, "getListTemplateExists", async () => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _securitysolutionEsUtils.getIndexTemplateExists)(esClient, listIndex); }); /** * Returns true if the list item template for ILM exists, otherwise false * @returns True if the list item template for ILM exists, otherwise false. */ (0, _defineProperty2.default)(this, "getListItemTemplateExists", async () => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _securitysolutionEsUtils.getIndexTemplateExists)(esClient, listItemIndex); }); /** * Returns true if the list template for ILM exists, otherwise false * @returns True if the list template for ILM exists, otherwise false. */ (0, _defineProperty2.default)(this, "getLegacyListTemplateExists", async () => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _securitysolutionEsUtils.getTemplateExists)(esClient, listIndex); }); /** * Returns true if the list item template for ILM exists, otherwise false * @returns True if the list item template for ILM exists, otherwise false. */ (0, _defineProperty2.default)(this, "getLegacyListItemTemplateExists", async () => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _securitysolutionEsUtils.getTemplateExists)(esClient, listItemIndex); }); /** * Returns the list template for ILM. * @returns The contents of the list template for ILM. */ (0, _defineProperty2.default)(this, "getListTemplate", () => { const listIndex = this.getListIndex(); return (0, _.getListTemplate)(listIndex); }); /** * Returns the list item template for ILM. * @returns The contents of the list item template for ILM. */ (0, _defineProperty2.default)(this, "getListItemTemplate", () => { const listItemIndex = this.getListItemIndex(); return (0, _items.getListItemTemplate)(listItemIndex); }); /** * Sets the list template for ILM. * @returns The contents of the list template for ILM. */ (0, _defineProperty2.default)(this, "setListTemplate", async () => { const { esClient } = this; const template = this.getListTemplate(); const listIndex = this.getListIndex(); return (0, _securitysolutionEsUtils.setIndexTemplate)(esClient, listIndex, template); }); /** * Sets the list item template for ILM. * @returns The contents of the list item template for ILM. */ (0, _defineProperty2.default)(this, "setListItemTemplate", async () => { const { esClient } = this; const template = this.getListItemTemplate(); const listItemIndex = this.getListItemIndex(); return (0, _securitysolutionEsUtils.setIndexTemplate)(esClient, listItemIndex, template); }); /** * Sets the list policy * @returns The contents of the list policy set */ (0, _defineProperty2.default)(this, "setListPolicy", async () => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _securitysolutionEsUtils.setPolicy)(esClient, listIndex, _list_policy.default); }); /** * Sets the list item policy * @returns The contents of the list policy set */ (0, _defineProperty2.default)(this, "setListItemPolicy", async () => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _securitysolutionEsUtils.setPolicy)(esClient, listItemIndex, _list_item_policy.default); }); /** * Deletes the list index * @returns True if the list index was deleted, otherwise false */ (0, _defineProperty2.default)(this, "deleteListIndex", async () => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _securitysolutionEsUtils.deleteAllIndex)(esClient, `${listIndex}-*`); }); /** * Deletes the list item index * @returns True if the list item index was deleted, otherwise false */ (0, _defineProperty2.default)(this, "deleteListItemIndex", async () => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _securitysolutionEsUtils.deleteAllIndex)(esClient, `${listItemIndex}-*`); }); /** * Deletes the list policy * @returns The contents of the list policy */ (0, _defineProperty2.default)(this, "deleteListPolicy", async () => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _securitysolutionEsUtils.deletePolicy)(esClient, listIndex); }); /** * Deletes the list item policy * @returns The contents of the list item policy */ (0, _defineProperty2.default)(this, "deleteListItemPolicy", async () => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _securitysolutionEsUtils.deletePolicy)(esClient, listItemIndex); }); /** * Deletes the list template * @returns The contents of the list template */ (0, _defineProperty2.default)(this, "deleteListTemplate", async () => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _securitysolutionEsUtils.deleteIndexTemplate)(esClient, listIndex); }); /** * Deletes the list item template * @returns The contents of the list item template */ (0, _defineProperty2.default)(this, "deleteListItemTemplate", async () => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _securitysolutionEsUtils.deleteIndexTemplate)(esClient, listItemIndex); }); /** * Deletes the list boot strap index for ILM policies. * @returns The contents of the bootstrap response from Elasticsearch */ (0, _defineProperty2.default)(this, "deleteLegacyListTemplate", async () => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _securitysolutionEsUtils.deleteTemplate)(esClient, listIndex); }); /** * Delete the list item boot strap index for ILM policies. * @returns The contents of the bootstrap response from Elasticsearch */ (0, _defineProperty2.default)(this, "deleteLegacyListItemTemplate", async () => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _securitysolutionEsUtils.deleteTemplate)(esClient, listItemIndex); }); /** * Given a list item id, this will delete the single list item * @returns The list item if found, otherwise null */ (0, _defineProperty2.default)(this, "deleteListItem", async ({ id }) => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _items.deleteListItem)({ esClient, id, listItemIndex }); }); /** * Given a list value, this will delete all list items that have that value * @param options * @param options.listId The "list_id"/list container to delete from * @param options.value The value to delete the list items by * @param options.type The type of list such as "boolean", "double", "text", "keyword", etc... * @returns The list items deleted. */ (0, _defineProperty2.default)(this, "deleteListItemByValue", async ({ listId, value, type }) => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _items.deleteListItemByValue)({ esClient, listId, listItemIndex, type, value }); }); /** * Given a list id, this will delete the list from the id * @param options * @param options.id The id of the list to delete * @returns The list deleted if found, otherwise null */ (0, _defineProperty2.default)(this, "deleteList", async ({ id }) => { const { esClient } = this; const listIndex = this.getListIndex(); const listItemIndex = this.getListItemIndex(); return (0, _.deleteList)({ esClient, id, listIndex, listItemIndex }); }); /** * Exports list items to a stream * @param options * @param options.stringToAppend Optional string to append at the end of each item such as a newline "\n". If undefined is passed, no string is appended. * @param options.listId The list id to export all the item from * @param options.stream The stream to push the export into */ (0, _defineProperty2.default)(this, "exportListItemsToStream", ({ stringToAppend, listId, stream }) => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); (0, _items.exportListItemsToStream)({ esClient, listId, listItemIndex, stream, stringToAppend }); }); /** * Imports list items to a stream. If the list already exists, this will append the list items to the existing list. * If the list does not exist, this will auto-create the list and then add the items to that list. * See {@link https://www.elastic.co/guide/en/security/current/lists-api-create-container.html} * for more information around formats of the deserializer and serializer. * @param options * @param options.deserializer A custom deserializer for the list. Optionally, you an define this as handle bars. See online docs for more information. * @param options.serializer Determines how uploaded list item values are parsed. By default, list items are parsed using named regex groups. See online docs for more information. * @param options.type The type of list such as "boolean", "double", "text", "keyword", etc... * @param options.stream The stream to pull the import from * @param options.meta Additional meta data to associate with the list items as an object of "key/value" pairs. You can set this to "undefined" for no meta values. * @param options.version Version number of the list, typically this should be 1 unless you are re-creating a list you deleted or something unusual. */ (0, _defineProperty2.default)(this, "importListItemsToStream", async ({ deserializer, serializer, type, listId, stream, meta, version }) => { const { esClient, user, config } = this; const listItemIndex = this.getListItemIndex(); const listIndex = this.getListIndex(); return (0, _items.importListItemsToStream)({ config, deserializer, esClient, listId, listIndex, listItemIndex, meta, serializer, stream, type, user, version }); }); /** * Returns all list items found by value. * @param options * @param options.listId The list id to search for the list item by value. * @param options.value The list value to find the list item by. * @param options.type The type of list such as "boolean", "double", "text", "keyword", etc... * @returns The list items by value found. */ (0, _defineProperty2.default)(this, "getListItemByValue", async ({ listId, value, type }) => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _items.getListItemByValue)({ esClient, listId, listItemIndex, type, value }); }); /** * Creates a list item given at least "value", "type", and a "listId" where "listId" is the parent container that this list * item belongs to. * See {@link https://www.elastic.co/guide/en/security/current/lists-api-create-container.html} * for more information around formats of the deserializer and serializer. * @param options * @param options.id Optional Elasticsearch id, if none is given an autogenerated one will be used. * @param options.deserializer A custom deserializer for the list. Optionally, you an define this as handle bars. See online docs for more information. * @param options.serializer Determines how uploaded list item values are parsed. By default, list items are parsed using named regex groups. See online docs for more information. * @param options.listId The "list_id" this list item belongs to. * @param options.value The value of the list item. * @param options.type The type of list such as "boolean", "double", "text", "keyword", etc... * @param options.meta Additional meta data to associate with the list items as an object of "key/value" pairs. You can set this to "undefined" for no meta values. */ (0, _defineProperty2.default)(this, "createListItem", async ({ id, deserializer, serializer, listId, value, type, meta }) => { const { esClient, user } = this; const listItemIndex = this.getListItemIndex(); return (0, _items.createListItem)({ deserializer, esClient, id, listId, listItemIndex, meta, serializer, type, user, value }); }); /** * Updates a list item's value given the id of the list item. * See {@link https://www.elastic.co/guide/en/elasticsearch/reference/current/optimistic-concurrency-control.html} * for more information around optimistic concurrency control. * @param options * @param options._version This is the version, useful for optimistic concurrency control. * @param options.id id of the list to replace the list item with. * @param options.value The value of the list item to replace. * @param options.meta Additional meta data to associate with the list items as an object of "key/value" pairs. You can set this to "undefined" to not update meta values. */ (0, _defineProperty2.default)(this, "updateListItem", async ({ _version, id, value, meta }) => { const { esClient, user } = this; const listItemIndex = this.getListItemIndex(); return (0, _items.updateListItem)({ _version, esClient, id, listItemIndex, meta, user, value }); }); /** * Updates a list container's value given the id of the list. * See {@link https://www.elastic.co/guide/en/elasticsearch/reference/current/optimistic-concurrency-control.html} * for more information around optimistic concurrency control. * @param options * @param options._version This is the version, useful for optimistic concurrency control. * @param options.id id of the list to replace the list container data with. * @param options.name The new name, or "undefined" if this should not be updated. * @param options.description The new description, or "undefined" if this should not be updated. * @param options.meta Additional meta data to associate with the list items as an object of "key/value" pairs. You can set this to "undefined" to not update meta values. * @param options.version Updates the version of the list. */ (0, _defineProperty2.default)(this, "updateList", async ({ _version, id, name, description, meta, version }) => { const { esClient, user } = this; const listIndex = this.getListIndex(); return (0, _.updateList)({ _version, description, esClient, id, listIndex, meta, name, user, version }); }); /** * Given a list item id, this returns the list item if it exists, otherwise "null". * @param options * @param options.id The id of the list item to get. * @returns The list item found if it exists, otherwise "null". */ (0, _defineProperty2.default)(this, "getListItem", async ({ id }) => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _items.getListItem)({ esClient, id, listItemIndex }); }); /** * Given a list item value, this returns all list items found with that value. * @param options * @param options.type The type of list such as "boolean", "double", "text", "keyword", etc... * @param options.listId The id of the list container to search for list items. * @param options.value The value to search for list items based off. * @returns All list items that match the value sent in. */ (0, _defineProperty2.default)(this, "getListItemByValues", async ({ type, listId, value }) => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _items.getListItemByValues)({ esClient, listId, listItemIndex, type, value }); }); /** * Given a list item value, this search for all list items found with that value. * @param options * @param options.type The type of list such as "boolean", "double", "text", "keyword", etc... * @param options.listId The id of the list container to search for list items. * @param options.value The value to search for list items based off. * @returns All list items that match the value sent in. */ (0, _defineProperty2.default)(this, "searchListItemByValues", async ({ type, listId, value }) => { const { esClient } = this; const listItemIndex = this.getListItemIndex(); return (0, _items.searchListItemByValues)({ esClient, listId, listItemIndex, type, value }); }); /** * Finds lists based on a filter passed in. This is a bit complicated as it existed before * PIT (Point in Time) and other mechanisms. This uses an older way of doing "hops" and * accepting a "currentIndexPosition" which acts like a pointer to where the search should continue. * @param options * @param options.filter A KQL string filter to find lists. * @param options.currentIndexPosition The current index position to search from. * @param options.perPage How many per page to return. * @param options.sortField Which field to sort on, "undefined" for no sort field * @param options.sortOrder "asc" or "desc" to sort, otherwise "undefined" if there is no sort order * @param options.searchAfter array of search_after terms, otherwise "undefined" if there is no search_after * @returns All lists found based on the passed in filter. */ (0, _defineProperty2.default)(this, "findList", async ({ filter, currentIndexPosition, perPage, page, sortField, sortOrder, searchAfter, runtimeMappings }) => { const { esClient } = this; const listIndex = this.getListIndex(); return (0, _.findList)({ currentIndexPosition, esClient, filter, listIndex, page, perPage, runtimeMappings, searchAfter, sortField, sortOrder }); }); /** * Finds list items based on a filter passed in. This is a bit complicated as it existed before * PIT (Point in Time) and other mechanisms. This uses an older way of doing "hops" and * accepting a "currentIndexPosition" which acts like a pointer to where the search should continue. * @param options * @param options.listId The list id to search for the list items * @param options.filter A KQL string filter to find list items. * @param options.currentIndexPosition The current index position to search from. * @param options.perPage How many per page to return. * @param options.page The current page number for the current find * @param options.sortField Which field to sort on, "undefined" for no sort field * @param options.sortOrder "asc" or "desc" to sort, otherwise "undefined" if there is no sort order * @param options.searchAfter array of search_after terms, otherwise "undefined" if there is no search_after * @returns All list items found based on the passed in filter. */ (0, _defineProperty2.default)(this, "findListItem", async ({ listId, filter, currentIndexPosition, perPage, page, runtimeMappings, sortField, sortOrder, searchAfter }) => { const { esClient } = this; const listIndex = this.getListIndex(); const listItemIndex = this.getListItemIndex(); return (0, _items.findListItem)({ currentIndexPosition, esClient, filter, listId, listIndex, listItemIndex, page, perPage, runtimeMappings, searchAfter, sortField, sortOrder }); }); (0, _defineProperty2.default)(this, "findAllListItems", async ({ listId, filter, sortField, sortOrder }) => { const { esClient } = this; const listIndex = this.getListIndex(); const listItemIndex = this.getListItemIndex(); return (0, _items.findAllListItems)({ esClient, filter, listId, listIndex, listItemIndex, sortField, sortOrder }); }); this.spaceId = _spaceId; this.user = _user; this.config = _config; this.esClient = _esClient; } } exports.ListClient = ListClient;