Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const getAddPrepackagedThreatMatchRulesSchemaMock = (): AddPrepackagedRul
rule_id: 'rule-1',
version: 1,
threat_query: '*:*',
threat_index: 'list-index',
threat_index: ['list-index'],
threat_mapping: [
{
entries: [
Expand Down Expand Up @@ -118,7 +118,7 @@ export const getAddPrepackagedThreatMatchRulesSchemaDecodedMock = (): AddPrepack
exceptions_list: [],
rule_id: 'rule-1',
threat_query: '*:*',
threat_index: 'list-index',
threat_index: ['list-index'],
threat_mapping: [
{
entries: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import {
threat_query,
threat_filters,
threat_mapping,
threat_language,
} from '../types/threat_mapping';

import {
Expand Down Expand Up @@ -128,6 +129,7 @@ export const addPrepackagedRulesSchema = t.intersection([
threat_mapping, // defaults to "undefined" if not set during decode
threat_query, // defaults to "undefined" if not set during decode
threat_index, // defaults to "undefined" if not set during decode
threat_language, // defaults "undefined" if not set during decode
})
),
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const getCreateThreatMatchRulesSchemaMock = (ruleId = 'rule-1'): CreateRu
language: 'kuery',
rule_id: ruleId,
threat_query: '*:*',
threat_index: 'list-index',
threat_index: ['list-index'],
threat_mapping: [
{
entries: [
Expand Down Expand Up @@ -124,7 +124,7 @@ export const getCreateThreatMatchRulesSchemaDecodedMock = (): CreateRulesSchemaD
exceptions_list: [],
rule_id: 'rule-1',
threat_query: '*:*',
threat_index: 'list-index',
threat_index: ['list-index'],
threat_mapping: [
{
entries: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import {
threat_query,
threat_filters,
threat_mapping,
threat_language,
} from '../types/threat_mapping';

import {
Expand Down Expand Up @@ -124,6 +125,7 @@ export const createRulesSchema = t.intersection([
threat_query, // defaults to "undefined" if not set during decode
threat_filters, // defaults to "undefined" if not set during decode
threat_index, // defaults to "undefined" if not set during decode
threat_language, // defaults "undefined" if not set during decode
})
),
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const getImportThreatMatchRulesSchemaMock = (ruleId = 'rule-1'): ImportRu
risk_score: 55,
language: 'kuery',
rule_id: ruleId,
threat_index: 'index-123',
threat_index: ['index-123'],
threat_mapping: [{ entries: [{ field: 'host.name', type: 'mapping', value: 'host.name' }] }],
threat_query: '*:*',
threat_filters: [
Expand Down Expand Up @@ -136,7 +136,7 @@ export const getImportThreatMatchRulesSchemaDecodedMock = (): ImportRulesSchemaD
rule_id: 'rule-1',
immutable: false,
threat_query: '*:*',
threat_index: 'index-123',
threat_index: ['index-123'],
threat_mapping: [
{
entries: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import {
threat_query,
threat_filters,
threat_mapping,
threat_language,
} from '../types/threat_mapping';

import {
Expand Down Expand Up @@ -147,6 +148,7 @@ export const importRulesSchema = t.intersection([
threat_mapping, // defaults to "undefined" if not set during decode
threat_query, // defaults to "undefined" if not set during decode
threat_index, // defaults to "undefined" if not set during decode
threat_language, // defaults "undefined" if not set during decode
})
),
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ import {
severity_mapping,
event_category_override,
} from '../common/schemas';
import {
threat_index,
threat_query,
threat_filters,
threat_mapping,
threat_language,
} from '../types/threat_mapping';
import { listArrayOrUndefined } from '../types/lists';

/**
Expand Down Expand Up @@ -97,6 +104,11 @@ export const patchRulesSchema = t.exact(
note,
version,
exceptions_list: listArrayOrUndefined,
threat_index,
threat_query,
threat_filters,
threat_mapping,
threat_language,
})
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ import {
SeverityMapping,
event_category_override,
} from '../common/schemas';
import {
threat_index,
threat_query,
threat_filters,
threat_mapping,
threat_language,
} from '../types/threat_mapping';

import {
DefaultStringArray,
Expand Down Expand Up @@ -122,6 +129,11 @@ export const updateRulesSchema = t.intersection([
note, // defaults to "undefined" if not set during decode
version, // defaults to "undefined" if not set during decode
exceptions_list: DefaultListArray, // defaults to empty array if not set during decode
threat_mapping, // defaults to "undefined" if not set during decode
threat_query, // defaults to "undefined" if not set during decode
threat_filters, // defaults to "undefined" if not set during decode
threat_index, // defaults to "undefined" if not set during decode
threat_language, // defaults "undefined" if not set during decode
})
),
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export const getThreatMatchingSchemaMock = (anchorDate: string = ANCHOR_DATE): R
return {
...getRulesSchemaMock(anchorDate),
type: 'threat_match',
threat_index: 'index-123',
threat_index: ['index-123'],
threat_mapping: [{ entries: [{ field: 'host.name', type: 'mapping', value: 'host.name' }] }],
threat_query: '*:*',
threat_filters: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ describe('rules_schema', () => {
const message = pipe(checked, foldLeftRight);

expect(getPaths(left(message.errors))).toEqual([
'invalid keys "threat_index,threat_mapping,[{"entries":[{"field":"host.name","type":"mapping","value":"host.name"}]}],threat_query,threat_filters,[{"bool":{"must":[{"query_string":{"query":"host.name: linux","analyze_wildcard":true,"time_zone":"Zulu"}}],"filter":[],"should":[],"must_not":[]}}]"',
'invalid keys "threat_index,["index-123"],threat_mapping,[{"entries":[{"field":"host.name","type":"mapping","value":"host.name"}]}],threat_query,threat_filters,[{"bool":{"must":[{"query_string":{"query":"host.name: linux","analyze_wildcard":true,"time_zone":"Zulu"}}],"filter":[],"should":[],"must_not":[]}}]"',
]);
expect(message.schema).toEqual({});
});
Expand Down Expand Up @@ -764,7 +764,7 @@ describe('rules_schema', () => {

test('should return 5 fields for a rule of type "threat_match"', () => {
const fields = addThreatMatchFields({ type: 'threat_match' });
expect(fields.length).toEqual(5);
expect(fields.length).toEqual(6);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import {
threat_query,
threat_filters,
threat_mapping,
threat_language,
} from '../types/threat_mapping';

import { DefaultListArray } from '../types/lists_default_array';
Expand Down Expand Up @@ -144,6 +145,7 @@ export const dependentRulesSchema = t.partial({
threat_index,
threat_query,
threat_mapping,
threat_language,
});

/**
Expand Down Expand Up @@ -277,6 +279,7 @@ export const addThreatMatchFields = (typeAndTimelineOnly: TypeAndTimelineOnly):
t.exact(t.type({ threat_query: dependentRulesSchema.props.threat_query })),
t.exact(t.type({ threat_index: dependentRulesSchema.props.threat_index })),
t.exact(t.type({ threat_mapping: dependentRulesSchema.props.threat_mapping })),
t.exact(t.partial({ threat_language: dependentRulesSchema.props.threat_language })),
t.exact(t.partial({ threat_filters: dependentRulesSchema.props.threat_filters })),
t.exact(t.partial({ saved_id: dependentRulesSchema.props.saved_id })),
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ export * from './positive_integer';
export * from './positive_integer_greater_than_zero';
export * from './references_default_array';
export * from './risk_score';
export * from './threat_mapping';
export * from './uuid';
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
/* eslint-disable @typescript-eslint/naming-convention */

import * as t from 'io-ts';
import { language } from '../common/schemas';
import { NonEmptyString } from './non_empty_string';

export const threat_query = t.string;
Expand All @@ -19,29 +20,38 @@ export type ThreatFilters = t.TypeOf<typeof threat_filters>;
export const threatFiltersOrUndefined = t.union([threat_filters, t.undefined]);
export type ThreatFiltersOrUndefined = t.TypeOf<typeof threatFiltersOrUndefined>;

export const threatMappingEntries = t.array(
t.exact(
t.type({
field: NonEmptyString,
type: t.keyof({ mapping: null }),
value: NonEmptyString,
})
)
export const threatMapEntry = t.exact(
t.type({
field: NonEmptyString,
type: t.keyof({ mapping: null }),
value: NonEmptyString,
})
);

export type ThreatMapEntry = t.TypeOf<typeof threatMapEntry>;

export const threatMappingEntries = t.array(threatMapEntry);
export type ThreatMappingEntries = t.TypeOf<typeof threatMappingEntries>;

export const threat_mapping = t.array(
t.exact(
t.type({
entries: threatMappingEntries,
})
)
export const threatMap = t.exact(
t.type({
entries: threatMappingEntries,
})
);
export type ThreatMap = t.TypeOf<typeof threatMap>;

export const threat_mapping = t.array(threatMap);
export type ThreatMapping = t.TypeOf<typeof threat_mapping>;

export const threatMappingOrUndefined = t.union([threat_mapping, t.undefined]);
export type ThreatMappingOrUndefined = t.TypeOf<typeof threatMappingOrUndefined>;

export const threat_index = t.string;
export const threat_index = t.array(t.string);
export type ThreatIndex = t.TypeOf<typeof threat_index>;
export const threatIndexOrUndefined = t.union([threat_index, t.undefined]);
export type ThreatIndexOrUndefined = t.TypeOf<typeof threatIndexOrUndefined>;

export const threat_language = t.union([language, t.undefined]);
export type ThreatLanguage = t.TypeOf<typeof threat_language>;
export const threatLanguageOrUndefined = t.union([threat_language, t.undefined]);
export type ThreatLanguageOrUndefined = t.TypeOf<typeof threatLanguageOrUndefined>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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.
*/

import React from 'react';
import { ThemeProvider } from 'styled-components';
import { mount } from 'enzyme';
import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';

import { AndBadgeComponent } from './and_badge';

describe('AndBadgeComponent', () => {
test('it renders entryItemIndexItemEntryFirstRowAndBadge for very first item', () => {
const wrapper = mount(
<ThemeProvider theme={() => ({ eui: euiLightVars, darkMode: false })}>
<AndBadgeComponent entriesLength={2} entryItemIndex={0} />
</ThemeProvider>
);

expect(wrapper.find('[data-test-subj="entryItemEntryFirstRowAndBadge"]').exists()).toBeTruthy();
});

test('it renders entryItemEntryInvisibleAndBadge if "entriesLength" is 1 or less', () => {
const wrapper = mount(
<ThemeProvider theme={() => ({ eui: euiLightVars, darkMode: false })}>
<AndBadgeComponent entriesLength={1} entryItemIndex={0} />
</ThemeProvider>
);

expect(
wrapper.find('[data-test-subj="entryItemEntryInvisibleAndBadge"]').exists()
).toBeTruthy();
});

test('it renders regular "and" badge if item is not the first one and includes more than one entry', () => {
const wrapper = mount(
<ThemeProvider theme={() => ({ eui: euiLightVars, darkMode: false })}>
<AndBadgeComponent entriesLength={2} entryItemIndex={1} />
</ThemeProvider>
);

expect(wrapper.find('[data-test-subj="entryItemEntryAndBadge"]').exists()).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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.
*/

import React from 'react';
import { EuiFlexItem } from '@elastic/eui';
import styled from 'styled-components';

import { AndOrBadge } from '../and_or_badge';

const MyInvisibleAndBadge = styled(EuiFlexItem)`
visibility: hidden;
`;

const MyFirstRowContainer = styled(EuiFlexItem)`
padding-top: 20px;
`;

interface AndBadgeProps {
entriesLength: number;
entryItemIndex: number;
}

export const AndBadgeComponent = React.memo<AndBadgeProps>(({ entriesLength, entryItemIndex }) => {
const badge = <AndOrBadge includeAntennas type="and" />;

if (entriesLength > 1 && entryItemIndex === 0) {
return (
<MyFirstRowContainer grow={false} data-test-subj="entryItemEntryFirstRowAndBadge">
{badge}
</MyFirstRowContainer>
);
} else if (entriesLength <= 1) {
return (
<MyInvisibleAndBadge grow={false} data-test-subj="entryItemEntryInvisibleAndBadge">
{badge}
</MyInvisibleAndBadge>
);
} else {
return (
<EuiFlexItem grow={false} data-test-subj="entryItemEntryAndBadge">
{badge}
</EuiFlexItem>
);
}
});

AndBadgeComponent.displayName = 'AndBadge';
Loading