"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.camelToSentenceCase = camelToSentenceCase; exports.conditionCombinationInvalid = conditionCombinationInvalid; exports.getDefaultResponseByType = getDefaultResponseByType; exports.getDefaultSelectorByType = getDefaultSelectorByType; exports.getRestrictedValuesForCondition = getRestrictedValuesForCondition; exports.getSelectorConditions = getSelectorConditions; exports.getSelectorTypeIcon = getSelectorTypeIcon; exports.getTotalsByType = getTotalsByType; exports.selectorsIncludeConditionsForFIMOperationsUsingSlashStarStar = selectorsIncludeConditionsForFIMOperationsUsingSlashStarStar; exports.validateBlockRestrictions = validateBlockRestrictions; exports.validateMaxSelectorsAndResponses = validateMaxSelectorsAndResponses; exports.validateStringValuesForCondition = validateStringValuesForCondition; var _lodash = require("lodash"); var _i18n = require("@kbn/i18n"); var _translations = require("../components/control_general_view/translations"); var _types = require("../types"); var _constants = require("./constants"); /* * 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. */ function getSelectorTypeIcon(type) { switch (type) { case 'process': return 'gear'; case 'file': default: return 'document'; } } function camelToSentenceCase(prop) { const sentence = prop.replace(/([A-Z])/g, ' $1').toLowerCase(); return sentence[0].toUpperCase() + sentence.slice(1); } function conditionCombinationInvalid(addedConditions, condition) { const options = _types.SelectorConditionsMap[condition]; const invalid = addedConditions.find(added => { var _options$not; return options === null || options === void 0 ? void 0 : (_options$not = options.not) === null || _options$not === void 0 ? void 0 : _options$not.includes(added); }); return !!invalid; } function getTotalsByType(selectors, responses) { const totalsByType = { process: 0, file: 0 }; selectors.forEach(selector => { totalsByType[selector.type]++; }); responses.forEach(response => { totalsByType[response.type]++; }); return totalsByType; } function selectorUsesFIM(selector) { return selector && (!selector.operation || selector.operation.length === 0 || selector.operation.some(r => _constants.FIM_OPERATIONS.indexOf(r) >= 0)); } function selectorsIncludeConditionsForFIMOperations(selectors, conditions, selectorNames, requireForAll) { const result = selectorNames && selectorNames.reduce((prev, cur) => { const selector = selectors.find(s => s.name === cur); const usesFIM = selectorUsesFIM(selector); const hasAllConditions = !usesFIM || !!(selector && conditions.reduce((p, c) => { return p && selector.hasOwnProperty(c); }, true)); if (requireForAll) { return prev && hasAllConditions; } else { return prev || hasAllConditions; } }, requireForAll); return !!result; } function selectorsIncludeConditionsForFIMOperationsUsingSlashStarStar(selectors, selectorNames) { const result = selectorNames && selectorNames.reduce((prev, cur) => { var _selector$targetFileP; const selector = selectors.find(s => s.name === cur); const usesFIM = selectorUsesFIM(selector); return prev || !!(usesFIM && selector !== null && selector !== void 0 && (_selector$targetFileP = selector.targetFilePath) !== null && _selector$targetFileP !== void 0 && _selector$targetFileP.includes('/**')); }, false); return !!result; } function validateBlockRestrictions(selectors, responses) { const errors = []; responses.forEach(response => { var _response$actions; if ((_response$actions = response.actions) !== null && _response$actions !== void 0 && _response$actions.includes('block')) { // check if any selectors are using FIM operations // and verify that targetFilePath is specfied in all 'match' selectors // or at least one 'exclude' selector const excludeUsesTargetFilePath = selectorsIncludeConditionsForFIMOperations(selectors, ['targetFilePath'], response.exclude); const matchSelectorsAllUsingTargetFilePath = selectorsIncludeConditionsForFIMOperations(selectors, ['targetFilePath'], response.match, true); if (!(matchSelectorsAllUsingTargetFilePath || excludeUsesTargetFilePath)) { errors.push(_translations.errorBlockActionRequiresTargetFilePath); } } }); return errors; } function validateMaxSelectorsAndResponses(selectors, responses) { const errors = []; const totalsByType = getTotalsByType(selectors, responses); // check selectors + responses doesn't exceed MAX_SELECTORS_AND_RESPONSES_PER_TYPE Object.values(totalsByType).forEach(count => { if (count > _constants.MAX_SELECTORS_AND_RESPONSES_PER_TYPE) { errors.push(_i18n.i18n.translate('xpack.cloudDefend.errorMaxSelectorsResponsesExceeded', { defaultMessage: 'You cannot exceed {max} selectors + responses for a given type e.g file, process', values: { max: _constants.MAX_SELECTORS_AND_RESPONSES_PER_TYPE } })); } }); return errors; } function validateStringValuesForCondition(condition, values) { const errors = []; const maxValueBytes = _types.SelectorConditionsMap[condition].maxValueBytes || _constants.MAX_CONDITION_VALUE_LENGTH_BYTES; const { pattern, patternError } = _types.SelectorConditionsMap[condition]; values === null || values === void 0 ? void 0 : values.forEach(value => { if ((value === null || value === void 0 ? void 0 : value.length) === 0) { errors.push(_i18n.i18n.translate('xpack.cloudDefend.errorGenericEmptyValue', { defaultMessage: '"{condition}" values cannot be empty', values: { condition } })); } else if (pattern && !new RegExp(pattern).test(value)) { if (patternError) { errors.push(patternError); } else { errors.push(_i18n.i18n.translate('xpack.cloudDefend.errorGenericRegexFailure', { defaultMessage: '"{condition}" values must match the pattern: /{pattern}/', values: { condition, pattern } })); } } const bytes = new Blob([value]).size; if (bytes > maxValueBytes) { errors.push(_i18n.i18n.translate('xpack.cloudDefend.errorMaxValueBytesExceeded', { defaultMessage: '"{condition}" values cannot exceed {maxValueBytes} bytes', values: { condition, maxValueBytes } })); } }); return (0, _lodash.uniq)(errors); } function getRestrictedValuesForCondition(type, condition) { var _options$values; const options = _types.SelectorConditionsMap[condition]; if (Array.isArray(options.values)) { return options.values; } if (options !== null && options !== void 0 && (_options$values = options.values) !== null && _options$values !== void 0 && _options$values[type]) { return options.values[type]; } } function getSelectorConditions(type) { const allConditions = Object.keys(_types.SelectorConditionsMap); return allConditions.filter(key => { const options = _types.SelectorConditionsMap[key]; return !options.selectorType || options.selectorType === type; }); } function getDefaultSelectorByType(type) { switch (type) { case 'process': return JSON.parse(JSON.stringify(_types.DefaultProcessSelector)); case 'file': default: return JSON.parse(JSON.stringify(_types.DefaultFileSelector)); } } function getDefaultResponseByType(type) { switch (type) { case 'process': return { ..._types.DefaultProcessResponse }; case 'file': default: return { ..._types.DefaultFileResponse }; } }