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

[Security Solution] Comments and pins are now not allowed on unsaved timelines #178525

Conversation

janmonschke
Copy link
Contributor

@janmonschke janmonschke commented Mar 12, 2024

Summary

As described in #178182, the removal of autosave on timeline resulted in a regression in which pinned events and comments on unsaved timelines are lost.

We're making the case, that creating comments and pinned events does not make on unsaved timelines does not make sense in the first place as it either leads to loss of data or it leads to sub-optimal solutions that involve saving timelines in the background (see #178212, especially this comment #178212 (comment)).

In this PR, we're disabling commenting and pinning for unsaved timelines.

Due to the nature of this change, a couple pieces of code have been identified to be not in use anymore and have also been deleted as part of this work (82bf54d & removal of timelineVersion on notes and pins).

This PR is best reviewed commit by commit.

Checklist

Delete any items that are not applicable to this PR.

@janmonschke janmonschke added release_note:enhancement Team:Threat Hunting:Investigations Security Solution Investigations Team backport:prev-minor Backport to (8.x) the previous minor version (i.e. one version back from main) labels Mar 12, 2024
@janmonschke janmonschke requested review from a team as code owners March 12, 2024 15:27
@elasticmachine
Copy link
Contributor

Pinging @elastic/security-threat-hunting-investigations (Team:Threat Hunting:Investigations)

Copy link
Contributor

@andrew-goldstein andrew-goldstein left a comment

Choose a reason for hiding this comment

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

Consider, as an alternative to the disabled notes and pin buttons in the screenshot below:

disabled_buttons

re-enabling those buttons, and showing / focusing the save dialog for unsaved timelines:

save_timeline

@andrew-goldstein
Copy link
Contributor

Consider, as an alternative to the disabled notes and pin buttons in the screenshot below:

disabled_buttons

re-enabling those buttons, and showing / focusing the save dialog for unsaved timelines:

save_timeline

@janmonschke please consider the following proposal, which adds detail to the above:

  1. The Add note or Pin alert actions are always enabled. This preserves the current functionality, which is a call to action.

When (for example) a user clicks Add note for an Untitled timeline, the Save dialog appears, per the screenshot below:

EuiCallOut

In the screenshot above, an EuiCallOut reads:

Save timeline to continue adding a note
  1. When the user enters a title and clicks Save, the Add note is expanded and focused, per the screenshot below:

after_save

@janmonschke janmonschke added this to the 8.14 milestone Mar 18, 2024
@janmonschke
Copy link
Contributor Author

@elasticmachine merge upstream

Copy link
Contributor

@logeekal logeekal left a comment

Choose a reason for hiding this comment

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

Still doing Desk Testing. This is code review and most of the code looks good. 🚀 Thanks for additionaly cleanup as well.

But before I approve, I had some comments/questions for your review.

</TestProviders>
);

expect(screen.getByTestId('timeline-notes-button-small')).toBeDisabled();
Copy link
Contributor

Choose a reason for hiding this comment

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

nit : I think it will make sense to test if tooltip appears as expected as well.

</TestProviders>
);

expect(screen.getByTestId('pin')).toBeDisabled();
Copy link
Contributor

Choose a reason for hiding this comment

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

same comment as above here about testing the tooltip.

@@ -492,7 +496,7 @@ const TabsContentComponent: React.FC<BasicTimelineTab> = ({
<StyledEuiTab
data-test-subj={`timelineTabs-${TimelineTabs.securityAssistant}`}
onClick={setSecurityAssistantAsActiveTab}
disabled={timelineType === TimelineType.template}
disabled={isTimelineTemplate}
Copy link
Contributor

Choose a reason for hiding this comment

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

thanks for cleaning this up

@@ -1,7 +1,7 @@
openapi: 3.0.0
info:
title: Elastic Security - Timeline - Pinned Event API (https://www.elastic.co/guide/en/security/current/_pin_an_event_to_an_existing_timeline.html)
version: 8.9.0
version: 8.14.0
Copy link
Contributor

Choose a reason for hiding this comment

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

I have a question unrelated to this PR.

Additionally, I see that you have updated version from 8.9.0 to 8.14.0 now. I wonder if users on our swagger open API spec page see the version as 8.9 even though they are 8.12 ? Do you know?

@@ -18,24 +18,24 @@ export default function ({ getService }: FtrProviderContext) {
after(() => kibanaServer.savedObjects.cleanStandardList());

describe('create a note', () => {
it('should return a timelineId, timelineVersion, noteId and version', async () => {
it('should return a timelineId, noteId and version', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you also add a test to create with timelineID as null and make sure it returns appropriate message and status code?

.send({
pinnedEventId: null,
eventId: 'bv4QSGsB9v5HJNSH-7fi',
timelineId: 'testTimelineId',
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here. Could you also add a test with timelineId as null?

noteId,
note,
overrideOwner,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

One question regarding this. Why was exception clause removed. I see that neither parent not child of createNote is setting the appropriate status code. I can see 403 return code is wrong here but did you want to return default 500 status code when this kind of error occurs?

(useShallowEqualSelector as jest.Mock).mockReturnValue({
...testTimeline,
timelineType: TimelineType.template,
});

const wrapper = mount(<EventColumnView {...props} />, { wrappingComponent: TestProviders });

expect(wrapper.find('[data-test-subj="add-note"]').prop('toolTip')).toEqual(
Copy link
Contributor

Choose a reason for hiding this comment

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

🧪 Should we check here that the button is disabled as well?

(useShallowEqualSelector as jest.Mock).mockReturnValue({
...testTimeline,
timelineType: TimelineType.template,
});

const wrapper = mount(<EventColumnView {...props} />, { wrappingComponent: TestProviders });
Copy link
Contributor

Choose a reason for hiding this comment

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

Additionally, I know it is not in the scope exactly, but you can see if this file is quick to change from enzyme to RTL. Because these incremental changes are the only to get these done.

Copy link
Contributor

@logeekal logeekal left a comment

Choose a reason for hiding this comment

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

Desk Testing Completed. Almost all of it seems to be working fine. But there is one edge case that we should be cognizant about.

Let's say you have a Investigation guide in the rule. When you create timeline from the alert created from that rule, it automatically adds investigation guide as a note. So if user does not save that timeline, that note will be a ghost/orphan note in the backend.

My first thought was that note creation should fail, since there is not timeline Id but as you will see in the demo video, we are sending timelineId: timeline-1 so network request succeeds.

As much as it might be necessary to add Investigation Guide as the note, we should be able to clean that as well if an unsavedtimeline is discarded.

Alternatively, did we explore simply keeping the note/pinned Events in redux only till the timeline is saved?

Below is the video that demonstrate it.

note_creation_unsaved_timeline.mp4

@kibana-ci
Copy link
Collaborator

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] Defend Workflows Cypress Tests on Serverless #1 / User Roles for Security Complete PLI with Endpoint Complete addon for role: t3_analyst Response Actions access "before each" hook for "should have access to execute action: release" "before each" hook for "should have access to execute action: release"

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
securitySolution 5036 5033 -3

Async chunks

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

id before after diff
securitySolution 15.5MB 15.5MB -13.3KB

History

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

cc @janmonschke

@janmonschke
Copy link
Contributor Author

Closed in favor of an adjusted #178212

@janmonschke janmonschke closed this Apr 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:prev-minor Backport to (8.x) the previous minor version (i.e. one version back from main) release_note:fix Team:Threat Hunting:Investigations Security Solution Investigations Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants