Skip to content

Commit

Permalink
Merge branch 'master' into add-endpoint-list-creation
Browse files Browse the repository at this point in the history
  • Loading branch information
elasticmachine authored Jul 15, 2020
2 parents fb40648 + 3984ffa commit 6966e92
Show file tree
Hide file tree
Showing 26 changed files with 2,764 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from '../../common/schemas';

import { getExceptionListClient } from './utils/get_exception_list_client';
import { endpointDisallowedFields } from './endpoint_disallowed_fields';

export const createExceptionListItemRoute = (router: IRouter): void => {
router.post(
Expand Down Expand Up @@ -70,6 +71,22 @@ export const createExceptionListItemRoute = (router: IRouter): void => {
statusCode: 409,
});
} else {
if (exceptionList.type === 'endpoint') {
for (const entry of entries) {
if (entry.type === 'list') {
return siemResponse.error({
body: `cannot add exception item with entry of type "list" to endpoint exception list`,
statusCode: 400,
});
}
if (endpointDisallowedFields.includes(entry.field)) {
return siemResponse.error({
body: `cannot add endpoint exception item on field ${entry.field}`,
statusCode: 400,
});
}
}
}
const createdList = await exceptionLists.createExceptionListItem({
_tags,
comments,
Expand Down
13 changes: 13 additions & 0 deletions x-pack/plugins/lists/server/routes/endpoint_disallowed_fields.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export const endpointDisallowedFields = [
'file.Ext.quarantine_path',
'file.Ext.quarantine_result',
'process.entity_id',
'process.parent.entity_id',
'process.ancestry',
];
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const NO_LEGEND_DATA: LegendItem[] = [];
export const AlertsHistogramPanel = memo<AlertsHistogramPanelProps>(
({
chartHeight,
defaultStackByOption = alertsHistogramOptions[0],
defaultStackByOption = alertsHistogramOptions[8], // signal.rule.name
deleteQuery,
filters,
headerChildren,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
*/

import { FormattedMessage } from '@kbn/i18n/react';
import { EuiText, EuiLink } from '@elastic/eui';
import { EuiLink } from '@elastic/eui';
import styled from 'styled-components';
import React from 'react';

import { ML_TYPE_DESCRIPTION } from './translations';
Expand All @@ -15,11 +16,15 @@ interface MlCardDescriptionProps {
hasValidLicense?: boolean;
}

const SmallText = styled.span`
font-size: ${({ theme }) => theme.eui.euiFontSizeS};
`;

const MlCardDescriptionComponent: React.FC<MlCardDescriptionProps> = ({
subscriptionUrl,
hasValidLicense = false,
}) => (
<EuiText size="s">
<SmallText>
{hasValidLicense ? (
ML_TYPE_DESCRIPTION
) : (
Expand All @@ -38,7 +43,7 @@ const MlCardDescriptionComponent: React.FC<MlCardDescriptionProps> = ({
}}
/>
)}
</EuiText>
</SmallText>
);

MlCardDescriptionComponent.displayName = 'MlCardDescriptionComponent';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const stepAboutDefaultValue: AboutStepRule = {
author: [],
name: '',
description: '',
isAssociatedToEndpointList: false,
isBuildingBlock: false,
isNew: true,
severity: { value: 'low', mapping: [] },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ describe('StepAboutRuleComponent', () => {
await wait();
const expected: Omit<AboutStepRule, 'isNew'> = {
author: [],
isAssociatedToEndpointList: false,
isBuildingBlock: false,
license: '',
ruleNameOverride: '',
Expand Down Expand Up @@ -223,6 +224,7 @@ describe('StepAboutRuleComponent', () => {
await wait();
const expected: Omit<AboutStepRule, 'isNew'> = {
author: [],
isAssociatedToEndpointList: false,
isBuildingBlock: false,
license: '',
ruleNameOverride: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,20 @@ const StepAboutRuleComponent: FC<StepAboutRuleProps> = ({
}}
/>
<EuiSpacer size="l" />
<EuiFormRow label={I18n.BUILDING_BLOCK} isInvalid={false} fullWidth>
<EuiFormRow label={I18n.GLOBAL_ENDPOINT_EXCEPTION_LIST} fullWidth>
<CommonUseField
path="isAssociatedToEndpointList"
componentProps={{
idAria: 'detectionEngineStepAboutRuleAssociatedToEndpointList',
'data-test-subj': 'detectionEngineStepAboutRuleAssociatedToEndpointList',
euiFieldProps: {
fullWidth: true,
isDisabled: isLoading,
},
}}
/>
</EuiFormRow>
<EuiFormRow label={I18n.BUILDING_BLOCK} fullWidth>
<CommonUseField
path="isBuildingBlock"
componentProps={{
Expand All @@ -291,7 +304,6 @@ const StepAboutRuleComponent: FC<StepAboutRuleProps> = ({
euiFieldProps: {
fullWidth: true,
isDisabled: isLoading,
placeholder: '',
},
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ export const schema: FormSchema = {
),
labelAppend: OptionalFieldLabel,
},
isAssociatedToEndpointList: {
type: FIELD_TYPES.CHECKBOX,
label: i18n.translate(
'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAssociatedToEndpointListLabel',
{
defaultMessage: 'Associate rule to Global Endpoint Exception List',
}
),
labelAppend: OptionalFieldLabel,
},
severity: {
value: {
type: FIELD_TYPES.SUPER_SELECT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ export const ADD_FALSE_POSITIVE = i18n.translate(
defaultMessage: 'Add false positive example',
}
);

export const GLOBAL_ENDPOINT_EXCEPTION_LIST = i18n.translate(
'xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.endpointExceptionListLabel',
{
defaultMessage: 'Global endpoint exception list',
}
);

export const BUILDING_BLOCK = i18n.translate(
'xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.buildingBlockLabel',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import { TestProviders } from '../../../common/mock';
import { ValueListsModal } from './modal';
import { waitForUpdates } from '../../../common/utils/test_utils';

describe('ValueListsModal', () => {
// TODO: These are occasionally timing out
describe.skip('ValueListsModal', () => {
it('renders nothing if showModal is false', () => {
const container = mount(
<TestProviders>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export const mockRuleWithEverything = (id: string): Rule => ({
export const mockAboutStepRule = (isNew = false): AboutStepRule => ({
isNew,
author: ['Elastic'],
isAssociatedToEndpointList: false,
isBuildingBlock: false,
timestampOverride: '',
ruleNameOverride: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export const formatAboutStepData = (aboutStepData: AboutStepRule): AboutStepRule
riskScore,
severity,
threat,
isAssociatedToEndpointList,
isBuildingBlock,
isNew,
note,
Expand All @@ -163,6 +164,13 @@ export const formatAboutStepData = (aboutStepData: AboutStepRule): AboutStepRule
const resp = {
author: author.filter((item) => !isEmpty(item)),
...(isBuildingBlock ? { building_block_type: 'default' } : {}),
...(isAssociatedToEndpointList
? {
exceptions_list: [
{ id: 'endpoint_list', namespace_type: 'agnostic', type: 'endpoint' },
] as AboutStepRuleJson['exceptions_list'],
}
: {}),
false_positives: falsePositives.filter((item) => !isEmpty(item)),
references: references.filter((item) => !isEmpty(item)),
risk_score: riskScore.value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,12 @@ describe('rule helpers', () => {
title: 'Titled timeline',
},
};
const aboutRuleStepData = {

const aboutRuleStepData: AboutStepRule = {
author: [],
description: '24/7',
falsePositives: ['test'],
isAssociatedToEndpointList: false,
isBuildingBlock: false,
isNew: false,
license: 'Elastic License',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export const getAboutStepsData = (rule: Rule, detailsView: boolean): AboutStepRu
const {
author,
building_block_type: buildingBlockType,
exceptions_list: exceptionsList,
license,
risk_score_mapping: riskScoreMapping,
rule_name_override: ruleNameOverride,
Expand All @@ -138,6 +139,7 @@ export const getAboutStepsData = (rule: Rule, detailsView: boolean): AboutStepRu
return {
isNew: false,
author,
isAssociatedToEndpointList: exceptionsList?.some(({ id }) => id === 'endpoint_list') ?? false,
isBuildingBlock: buildingBlockType !== undefined,
license: license ?? '',
ruleNameOverride: ruleNameOverride ?? '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
SeverityMapping,
TimestampOverride,
} from '../../../../../common/detection_engine/schemas/common/schemas';
import { List } from '../../../../../common/detection_engine/schemas/types';

export interface EuiBasicTableSortTypes {
field: string;
Expand Down Expand Up @@ -65,6 +66,7 @@ export interface AboutStepRule extends StepRuleData {
author: string[];
name: string;
description: string;
isAssociatedToEndpointList: boolean;
isBuildingBlock: boolean;
severity: AboutStepSeverity;
riskScore: AboutStepRiskScore;
Expand Down Expand Up @@ -136,6 +138,7 @@ export interface DefineStepRuleJson {
export interface AboutStepRuleJson {
author: Author;
building_block_type?: BuildingBlockType;
exceptions_list?: List[];
name: string;
description: string;
license: License;
Expand Down
2 changes: 1 addition & 1 deletion x-pack/test/api_integration/apis/fleet/agent_flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function (providerContext: FtrProviderContext) {
const supertestWithoutAuth = getSupertestWithoutAuth(providerContext);
const esClient = getService('es');

describe.skip('fleet_agent_flow', () => {
describe('fleet_agent_flow', () => {
before(async () => {
await esArchiver.load('empty_kibana');
});
Expand Down
4 changes: 1 addition & 3 deletions x-pack/test/api_integration/apis/fleet/agents/enroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ export default function (providerContext: FtrProviderContext) {
let apiKey: { id: string; api_key: string };
let kibanaVersion: string;

// Temporarily skipped to promote snapshot
// Re-enabled in https://github.com/elastic/kibana/pull/71727
describe.skip('fleet_agents_enroll', () => {
describe('fleet_agents_enroll', () => {
before(async () => {
await esArchiver.loadIfNeeded('fleet/agents');

Expand Down
4 changes: 3 additions & 1 deletion x-pack/test/api_integration/apis/fleet/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
*/

export default function loadTests({ loadTestFile }) {
describe('Fleet Endpoints', () => {
// Temporarily skipped to promote snapshot
// Re-enabled in https://github.com/elastic/kibana/pull/71727
describe.skip('Fleet Endpoints', () => {
loadTestFile(require.resolve('./setup'));
loadTestFile(require.resolve('./delete_agent'));
loadTestFile(require.resolve('./list_agent'));
Expand Down
4 changes: 1 addition & 3 deletions x-pack/test/api_integration/apis/fleet/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const es = getService('es');

// Temporarily skipped to promote snapshot
// Re-enabled in https://github.com/elastic/kibana/pull/71727
describe.skip('fleet_setup', () => {
describe('fleet_setup', () => {
beforeEach(async () => {
try {
await es.security.deleteUser({
Expand Down
4 changes: 1 addition & 3 deletions x-pack/test/api_integration/apis/fleet/unenroll_agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ export default function (providerContext: FtrProviderContext) {
const supertest = getService('supertest');
const esClient = getService('es');

// Temporarily skipped to promote snapshot
// Re-enabled in https://github.com/elastic/kibana/pull/71727
describe.skip('fleet_unenroll_agent', () => {
describe('fleet_unenroll_agent', () => {
let accessAPIKeyId: string;
let outputAPIKeyId: string;
before(async () => {
Expand Down
1 change: 1 addition & 0 deletions x-pack/test/api_integration/apis/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ export default function ({ loadTestFile }) {
loadTestFile(require.resolve('./transform'));
loadTestFile(require.resolve('./endpoint'));
loadTestFile(require.resolve('./ingest_manager'));
loadTestFile(require.resolve('./lists'));
});
}
Loading

0 comments on commit 6966e92

Please sign in to comment.