-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Security Solution] Comments and pins are now not allowed on unsaved timelines #178525
Conversation
Requests without `timelineId` will now also fail on the server.
Pinging @elastic/security-threat-hunting-investigations (Team:Threat Hunting:Investigations) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@janmonschke please consider the following proposal, which adds detail to the above:
When (for example) a user clicks In the screenshot above, an EuiCallOut reads:
|
@elasticmachine merge upstream |
There was a problem hiding this 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(); |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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} |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 () => { |
There was a problem hiding this comment.
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', |
There was a problem hiding this comment.
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, | ||
}); |
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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 }); |
There was a problem hiding this comment.
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.
There was a problem hiding this 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
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]Module Count
Async chunks
History
To update your PR or re-run it, just comment with: cc @janmonschke |
Closed in favor of an adjusted #178212 |
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.