Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIP] Investigate in timeline #140496

Merged
merged 16 commits into from
Sep 19, 2022

Conversation

PhilippeOberti
Copy link
Contributor

@PhilippeOberti PhilippeOberti commented Sep 12, 2022

Summary

This PR adds the Investigate in Timeline functionality to the Indicators table.

Behavior

When the user clicks on the Investigate in Timeline button in the actions column of the Indicators table or the flyout footer, the timeline view is presented with multiple entries already populated:

  • the indicator field and value pair, from the row selected (for example threat.indicator.file.hash.sha256: 'abc' )
  • the event source field and value pair, retrieved using the mapping (for example file.hash.sha256: 'abc')
    If a saved timeline was open, or the unsaved default timeline already had some values, a new unsaved timeline is created with the above pairs.

As the investigate in timeline feature is a lot more complex than the more basic add to timeline (see some of the discussions here), and since there isn't anything available from the Security Solution or the Timeline plugin to make it work out of the box (like there was for the Add to Timeline feature), the current state of this PR presents 2 approaches:

Notes:

  • I'm abandoning option links to styles and js #1 as option Change of links to styles and js #2 was approved by the Threat Hunting Investigation team.
  • This PR also changes the the url mapping to RawIndicatorFieldId.UrlFull instead of RawIndicatorFieldId.UrlOriginal (see here)
  • it seems that the threatIntelligence bundle has grown and surpassed the limit set in the knb-optimizer package. I ran the following command to update it node scripts/build_kibana_platform_plugins --update-limits
Screen.Recording.2022-09-12.at.2.18.55.PM.mov

https://github.com/elastic/security-team/issues/4558

Checklist

Delete any items that are not applicable to this PR.

- add investigate in timeline component using basic redux actions duplicated from Security Solution plugin
- investigates in timeline adds threat indicator as well as source entries using mapping
- remove first option as well as actions, selectors and types
- add new investigate in timeline hook in Security Solution plugin and pass via context to TI plugin
- replace UrlOriginal by UrlFull in the threat.indicator.name mapping
# Conflicts:
#	x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/add_to_timeline.tsx
#	x-pack/plugins/threat_intelligence/public/modules/timeline/components/add_to_timeline/styles.ts
- split InvestigateInTimeline into 2 components (one for Button display the other for ButtonIcon)
- extract most of the logic into useInvestigateInTimeline hook
- add unit and e2e tests
- remove threat.enrichments entries in the map
@PhilippeOberti PhilippeOberti marked this pull request as ready for review September 14, 2022 15:42
@PhilippeOberti PhilippeOberti requested a review from a team as a code owner September 14, 2022 15:42
@PhilippeOberti PhilippeOberti added release_note:skip Skip the PR/issue when compiling release notes 8.5 candidate Team: Protections Experience labels Sep 14, 2022
@PhilippeOberti PhilippeOberti requested a review from a team as a code owner September 15, 2022 11:55
@PhilippeOberti
Copy link
Contributor Author

@elasticmachine merge upstream

@PhilippeOberti
Copy link
Contributor Author

@elasticmachine merge upstream

Copy link
Member

@jbudz jbudz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

limits.yml

@PhilippeOberti
Copy link
Contributor Author

@elasticmachine merge upstream

const securitySolutionContext: SecuritySolutionPluginContext = {
getFiltersGlobalComponent: () => FiltersGlobal,
getPageWrapper: () => SecuritySolutionPageWrapper,
licenseService,
sourcererDataView: sourcererDataView as unknown as SourcererDataView,
getSecuritySolutionStore: securitySolutionStore,
getUseInvestigateInTimeline: useInvestigateInTimeline,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@lgestc
Copy link
Contributor

lgestc commented Sep 19, 2022

LGTM!

@maxcold
Copy link
Contributor

maxcold commented Sep 19, 2022

@elasticmachine merge upstream

Copy link
Contributor

@maxcold maxcold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall code looks good and the feature works as expect, good job! There are some small comments and suggestions

export const ACTION_INVESTIGATE_IN_TIMELINE = i18n.translate(
'xpack.securitySolution.threatIntelligence.investigateInTimelineTitle',
{
defaultMessage: 'Investigate in timeline',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember talking with UX writer they mentioned that they always use Timeline capitalized and it's the only feature that behaves this way, let's change to Investigate in Timeline

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though I don't see where this defaultMeassage appears, I'd expect it to show up as a tooltip on the action icon, but it's not there. Btw about tooltips, I see that our expand icon has a tooltip "View Details", but Investigate in Timeline icon doesn't have a tooltip. I think we should add it, but it can be in a separate PR if it's not a one-lines somewhere

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point. I've added the tooltip here as well as in every other places in the plugin I could find

const { filterManager: activeFilterManager } = useDeepEqualSelector((state) =>
getManageTimeline(state, TimelineId.active ?? '')
);
const filterManager = useMemo(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity what this filterManager does and what is the logic behind filterManagerBackup?

onOpen={setExpanded}
isOpen={Boolean(expanded && expanded._id === indicator._id)}
/>
<div css={styles.rowActionsDiv}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can EUI flex components be used here, eg EuiFlexGroup?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup done, good cleanup I could delete the styles.ts file entirely


return (
<EuiButton onClick={onClick} fill {...props}>
Investigate in Timeline
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be translated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup thanks, I went through the plugin and added a few more as well

}

return (
<div css={styles.inlineFlex}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same question about using flex components from EUI https://elastic.github.io/eui/#/layout/flex

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, style.ts deleted!


const { key, value } = getIndicatorFieldAndValue(indicator, RawIndicatorFieldId.Name);

if (!value || value === EMPTY_VALUE || !key) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we repeat this peace of logic in many places, I think we should at least move it to a utility function, ideally think about a model of our Indicator and about methods of this model. The best illustration of why it's bad to repeat business logic even if it's super simple is in indicator_value_actions.tsx where we have !key || value === EMPTY_VALUE || !key which is incorrect

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I extracted it, looks much better to me that way, thanks!

- add EuiTooltip for all EuiButtonIcon
- add missing translations
- replace css with EuiFlexGroup where possible
- extract fieldValueValid logic
* @returns true if correct, false if not
*/
export const fieldAndValueValid = (field: string | null, value: string | null): boolean =>
value != null && value !== '' && value !== EMPTY_VALUE && field != null && field !== '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any partucular reason to do value != null && value !== '' instead of !value. Also not sure why non-strict comparison with null. I'd vote for a simpler version

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I was confused for a sec... !value will not work with empty strings, but !!value will. It's cleaned up now! :)

@kibana-ci
Copy link
Collaborator

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] Security Solution Tests #2 / Alerts detection rules table auto-refresh should disable auto refresh when any rule selected and enable it after rules unselected
  • [job] [logs] Security Solution Tests #1 / Cases Creates a new case with timeline and opens the timeline

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
securitySolution 3076 3077 +1
threatIntelligence 167 198 +31
total +32

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
threatIntelligence 3 4 +1

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
securitySolution 6.4MB 6.4MB +1.2KB
threatIntelligence 70.8KB 72.6KB +1.9KB
total +3.1KB

Public APIs missing exports

Total count of every type that is part of your API that should be exported but is not. This will cause broken links in the API documentation system. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats exports for more detailed information.

id before after diff
threatIntelligence 2 3 +1

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
securitySolution 261.2KB 261.2KB +42.0B
threatIntelligence 13.4KB 28.6KB +15.2KB
total +15.3KB
Unknown metric groups

API count

id before after diff
threatIntelligence 17 20 +3

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@PhilippeOberti PhilippeOberti merged commit 3099159 into elastic:main Sep 19, 2022
@PhilippeOberti PhilippeOberti deleted the investigate-in-timeline branch September 19, 2022 18:28
@kibanamachine kibanamachine added v8.5.0 backport:skip This commit does not require backporting labels Sep 19, 2022
@maxcold maxcold added Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. release_note:feature Makes this part of the condensed release notes and removed release_note:skip Skip the PR/issue when compiling release notes labels Sep 28, 2022
@elasticmachine
Copy link
Contributor

Pinging @elastic/security-solution (Team: SecuritySolution)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
8.5 candidate backport:skip This commit does not require backporting release_note:feature Makes this part of the condensed release notes Team: Protections Experience Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. v8.5.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants