Skip to content

Commit

Permalink
[SIEM] add custom reputation link (#57814)
Browse files Browse the repository at this point in the history
* add custom reputation link

* fix unit test

* add number of limitation to reputation links

* fix dependency

* apply defaultFieldRendererOverflow to reputation link

* fix unit test

* fix url template

* fix display links

* fix types

* fix for review

* update test case

* update snapshot

* add icons and tooltips

* fix style

* update test

* add external link component

* update test

* fix types

* fix style

* update snapshot

* remove useMemo

* update description

* code review

* review II

* code review

* update description

* fix unit test

* fix unit test

* fix unit test

* fix unit test

* fix types

* fix styles

* fix style

* fix style

* fix review

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
angorayc and elasticmachine authored Feb 26, 2020
1 parent 8021fd8 commit e97b451
Show file tree
Hide file tree
Showing 11 changed files with 3,876 additions and 152 deletions.
9 changes: 9 additions & 0 deletions x-pack/legacy/plugins/siem/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ export const NEWS_FEED_URL_SETTING = 'siem:newsFeedUrl';
/** The default value for News feed widget */
export const NEWS_FEED_URL_SETTING_DEFAULT = 'https://feeds.elastic.co/security-solution';

/** This Kibana Advanced Setting specifies the URLs of `IP Reputation Links`*/
export const IP_REPUTATION_LINKS_SETTING = 'siem:ipReputationLinks';

/** The default value for `IP Reputation Links` */
export const IP_REPUTATION_LINKS_SETTING_DEFAULT = `[
{ "name": "virustotal.com", "url_template": "https://www.virustotal.com/gui/search/{{ip}}" },
{ "name": "talosIntelligence.com", "url_template": "https://talosintelligence.com/reputation_center/lookup?search={{ip}}" }
]`;

/**
* Id for the signals alerting type
*/
Expand Down
15 changes: 15 additions & 0 deletions x-pack/legacy/plugins/siem/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import {
NEWS_FEED_URL_SETTING,
NEWS_FEED_URL_SETTING_DEFAULT,
SIGNALS_INDEX_KEY,
IP_REPUTATION_LINKS_SETTING,
IP_REPUTATION_LINKS_SETTING_DEFAULT,
} from './common/constants';
import { defaultIndexPattern } from './default_index_pattern';
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/utils';
Expand Down Expand Up @@ -144,6 +146,19 @@ export const siem = (kibana: any) => {
category: ['siem'],
requiresPageReload: true,
},
[IP_REPUTATION_LINKS_SETTING]: {
name: i18n.translate('xpack.siem.uiSettings.ipReputationLinks', {
defaultMessage: 'IP Reputation Links',
}),
value: IP_REPUTATION_LINKS_SETTING_DEFAULT,
type: 'json',
description: i18n.translate('xpack.siem.uiSettings.ipReputationLinksDescription', {
defaultMessage:
'Array of URL templates to build the list of reputation URLs to be displayed on the IP Details page.',
}),
category: ['siem'],
requiresPageReload: true,
},
},
mappings: savedObjectMappings,
},
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { escapeDataProviderId } from '../drag_and_drop/helpers';
import { DefaultDraggable } from '../draggables';
import { getEmptyTagValue } from '../empty_value';
import { FormattedRelativePreferenceDate } from '../formatted_date';
import { HostDetailsLink, ReputationLink, VirusTotalLink, WhoIsLink } from '../links';
import { HostDetailsLink, ReputationLink, WhoIsLink, ReputationLinkSetting } from '../links';
import { Spacer } from '../page';
import * as i18n from '../page/network/ip_overview/translations';

Expand Down Expand Up @@ -132,11 +132,7 @@ export const hostNameRenderer = (host: HostEcsFields, ipFilter?: string): React.
export const whoisRenderer = (ip: string) => <WhoIsLink domain={ip}>{i18n.VIEW_WHOIS}</WhoIsLink>;

export const reputationRenderer = (ip: string): React.ReactElement => (
<>
<VirusTotalLink link={ip}>{i18n.VIEW_VIRUS_TOTAL}</VirusTotalLink>
{', '}
<ReputationLink domain={ip}>{i18n.VIEW_TALOS_INTELLIGENCE}</ReputationLink>
</>
<ReputationLink domain={ip} direction="column" />
);

interface DefaultFieldRendererProps {
Expand All @@ -148,73 +144,78 @@ interface DefaultFieldRendererProps {
moreMaxHeight?: string;
}

type OverflowRenderer = (item: string | ReputationLinkSetting) => JSX.Element;

// TODO: This causes breaks between elements until the ticket below is fixed
// https://github.com/elastic/ingest-dev/issues/474
export const DefaultFieldRenderer = React.memo<DefaultFieldRendererProps>(
({
attrName,
displayCount = 1,
idPrefix,
moreMaxHeight = DEFAULT_MORE_MAX_HEIGHT,
render,
rowItems,
}) => {
if (rowItems != null && rowItems.length > 0) {
const draggables = rowItems.slice(0, displayCount).map((rowItem, index) => {
const id = escapeDataProviderId(
`default-field-renderer-default-draggable-${idPrefix}-${attrName}-${rowItem}`
);
return (
<EuiFlexItem key={id} grow={false}>
{index !== 0 && (
<>
{','}
<Spacer />
</>
)}
export const DefaultFieldRendererComponent: React.FC<DefaultFieldRendererProps> = ({
attrName,
displayCount = 1,
idPrefix,
moreMaxHeight = DEFAULT_MORE_MAX_HEIGHT,
render,
rowItems,
}) => {
if (rowItems != null && rowItems.length > 0) {
const draggables = rowItems.slice(0, displayCount).map((rowItem, index) => {
const id = escapeDataProviderId(
`default-field-renderer-default-draggable-${idPrefix}-${attrName}-${rowItem}`
);
return (
<EuiFlexItem key={id} grow={false}>
{index !== 0 && (
<>
{','}
<Spacer />
</>
)}
{typeof rowItem === 'string' && (
<DefaultDraggable id={id} field={attrName} value={rowItem}>
{render ? render(rowItem) : rowItem}
</DefaultDraggable>
</EuiFlexItem>
);
});

return draggables.length > 0 ? (
<DraggableContainerFlexGroup alignItems="center" gutterSize="none" component="span">
{draggables}{' '}
{
<DefaultFieldRendererOverflow
rowItems={rowItems}
idPrefix={idPrefix}
render={render}
overflowIndexStart={displayCount}
moreMaxHeight={moreMaxHeight}
/>
}
</DraggableContainerFlexGroup>
) : (
getEmptyTagValue()
)}
</EuiFlexItem>
);
} else {
return getEmptyTagValue();
}
});

return draggables.length > 0 ? (
<DraggableContainerFlexGroup alignItems="center" gutterSize="none" component="span">
<EuiFlexItem grow={false}>{draggables} </EuiFlexItem>
<EuiFlexItem grow={false}>
<DefaultFieldRendererOverflow
rowItems={rowItems}
idPrefix={idPrefix}
render={render as OverflowRenderer}
overflowIndexStart={displayCount}
moreMaxHeight={moreMaxHeight}
/>
</EuiFlexItem>
</DraggableContainerFlexGroup>
) : (
getEmptyTagValue()
);
} else {
return getEmptyTagValue();
}
);
};

export const DefaultFieldRenderer = React.memo(DefaultFieldRendererComponent);

DefaultFieldRenderer.displayName = 'DefaultFieldRenderer';

type RowItemTypes = string | ReputationLinkSetting;
interface DefaultFieldRendererOverflowProps {
rowItems: string[];
rowItems: string[] | ReputationLinkSetting[];
idPrefix: string;
render?: (item: string) => React.ReactNode;
render?: (item: RowItemTypes) => React.ReactNode;
overflowIndexStart?: number;
moreMaxHeight: string;
}

interface MoreContainerProps {
idPrefix: string;
render?: (item: string) => React.ReactNode;
rowItems: string[];
render?: (item: RowItemTypes) => React.ReactNode;
rowItems: RowItemTypes[];
moreMaxHeight: string;
overflowIndexStart: number;
}
Expand Down
Loading

0 comments on commit e97b451

Please sign in to comment.