Skip to content

Commit

Permalink
[Security Solution] Untitled Timeline created when first action is to…
Browse files Browse the repository at this point in the history
… add note (elastic#78988)

* init tests

* Untitled Timeline created

* remove console

* fix from server side

* set timeline status to draft if created by saving notes

* add unit test

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
angorayc and elasticmachine committed Oct 5, 2020
1 parent f1c78b7 commit 8b65c18
Show file tree
Hide file tree
Showing 2 changed files with 240 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
/*
* 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 { AuthenticatedUser } from '../../../../security/common/model';

import { TimelineStatus, TimelineType } from '../../../common/types/timeline';

import { pickSavedTimeline } from './pick_saved_timeline';

describe('pickSavedTimeline', () => {
const mockDateNow = new Date('2020-04-03T23:00:00.000Z').valueOf();
const getMockSavedTimeline = () => ({
savedObjectId: '7af80430-03f4-11eb-9d9d-ffba20fabba8',
version: 'WzQ0ODgsMV0=',
created: 1601563413330,
createdBy: 'Elastic',
updated: 1601563454756,
updatedBy: 'Elastic',
dateRange: { start: '2020-09-30T14:42:30.094Z', end: '2020-10-01T14:42:30.094Z' },
columns: [
{ columnHeaderType: 'not-filtered', id: '@timestamp' },
{ columnHeaderType: 'not-filtered', id: 'message' },
{ columnHeaderType: 'not-filtered', id: 'event.category' },
{ columnHeaderType: 'not-filtered', id: 'event.action' },
{ columnHeaderType: 'not-filtered', id: 'host.name' },
{ columnHeaderType: 'not-filtered', id: 'source.ip' },
{ columnHeaderType: 'not-filtered', id: 'destination.ip' },
{ columnHeaderType: 'not-filtered', id: 'user.name' },
],
indexNames: [
'auditbeat-*',
'endgame-*',
'filebeat-*',
'logs-*',
'packetbeat-*',
'winlogbeat-*',
'.siem-signals-angelachuang-default',
],
description: 'hhh',
templateTimelineVersion: null,
eventType: 'all',
filters: [],
sort: { sortDirection: 'desc', columnId: '@timestamp' },
title: 'title',
kqlMode: 'filter',
timelineType: TimelineType.default,
savedQueryId: null,
kqlQuery: { filterQuery: null },
dataProviders: [],
templateTimelineId: null,
eventNotes: [],
globalNotes: [
{
noteId: '7ba7a520-03f4-11eb-9d9d-ffba20fabba8',
version: 'WzQ0ODEsMV0=',
note: '789',
timelineId: '7af80430-03f4-11eb-9d9d-ffba20fabba8',
created: 1601563414477,
createdBy: 'Elastic',
updated: 1601563414477,
updatedBy: 'Elastic',
},
],
pinnedEventIds: [],
});

beforeAll(() => {
Date = (jest.fn(() => ({
valueOf: jest.fn().mockReturnValue(mockDateNow),
})) as unknown) as DateConstructor;
});

afterAll(() => {
((Date as unknown) as jest.Mock).mockRestore();
});

describe('Set create / update time correctly ', () => {
test('Creating a timeline', () => {
const savedTimeline = getMockSavedTimeline();
const timelineId = null;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.created).toEqual(mockDateNow);
expect(result.updated).toEqual(mockDateNow);
});

test('Updating a timeline', () => {
const savedTimeline = getMockSavedTimeline();
const timelineId = savedTimeline.savedObjectId;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.created).toEqual(savedTimeline.created);
expect(result.updated).toEqual(mockDateNow);
});
});

describe('Set userInfo correctly ', () => {
test('Creating a timeline', () => {
const savedTimeline = getMockSavedTimeline();
const timelineId = null;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.createdBy).toEqual(userInfo.username);
expect(result.updatedBy).toEqual(userInfo.username);
});

test('Updating a timeline', () => {
const savedTimeline = getMockSavedTimeline();
const timelineId = savedTimeline.savedObjectId;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.createdBy).toEqual(savedTimeline.createdBy);
expect(result.updatedBy).toEqual(userInfo.username);
});
});

describe('Set status correctly ', () => {
test('Creating a timeline with title', () => {
const savedTimeline = getMockSavedTimeline();
const timelineId = null;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.status).toEqual(TimelineStatus.active);
});

test('Creating a timeline without title', () => {
const savedTimeline = { ...getMockSavedTimeline(), title: null };
const timelineId = null;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.status).toEqual(TimelineStatus.draft);
});

test('Updating a timeline with a new title', () => {
const savedTimeline = getMockSavedTimeline();
const timelineId = savedTimeline.savedObjectId;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.status).toEqual(TimelineStatus.active);
});

test('Updating a timeline without title', () => {
const savedTimeline = getMockSavedTimeline();
const timelineId = savedTimeline.savedObjectId;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.status).toEqual(TimelineStatus.active);
});

test('Updating an immutable timeline with a new title', () => {
const savedTimeline = { ...getMockSavedTimeline(), status: TimelineStatus.immutable };
const timelineId = savedTimeline.savedObjectId;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.status).toEqual(TimelineStatus.immutable);
});

test('Creating a draft timeline with title', () => {
const savedTimeline = { ...getMockSavedTimeline(), status: TimelineStatus.draft };
const timelineId = null;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.status).toEqual(TimelineStatus.active);
});

test('Creating a draft timeline without title', () => {
const savedTimeline = {
...getMockSavedTimeline(),
title: null,
status: TimelineStatus.draft,
};
const timelineId = null;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.status).toEqual(TimelineStatus.draft);
});

test('Updating an untitled draft timeline with a title', () => {
const savedTimeline = { ...getMockSavedTimeline(), status: TimelineStatus.draft };
const timelineId = savedTimeline.savedObjectId;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.status).toEqual(TimelineStatus.active);
});

test('Updating a draft timeline with a new title', () => {
const savedTimeline = { ...getMockSavedTimeline(), status: TimelineStatus.draft };
const timelineId = savedTimeline.savedObjectId;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.status).toEqual(TimelineStatus.active);
});

test('Updating a draft timeline without title', () => {
const savedTimeline = { ...getMockSavedTimeline(), status: TimelineStatus.draft };
const timelineId = savedTimeline.savedObjectId;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.status).toEqual(TimelineStatus.active);
});
});

test('Set timelineType correctly ', () => {
const savedTimeline = getMockSavedTimeline();
const timelineId = null;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.timelineType).toEqual(TimelineType.default);
expect(result.status).toEqual(TimelineStatus.active);
expect(result.templateTimelineId).toBeNull();
expect(result.templateTimelineVersion).toBeNull();
});

test('Set excludedRowRendererIds correctly ', () => {
const savedTimeline = getMockSavedTimeline();
const timelineId = null;
const userInfo = { username: 'elastic' } as AuthenticatedUser;
const result = pickSavedTimeline(timelineId, savedTimeline, userInfo);

expect(result.excludedRowRendererIds).toEqual([]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const pickSavedTimeline = (
savedTimeline.updatedBy = userInfo?.username ?? UNAUTHENTICATED_USER;
}

if (savedTimeline.status === TimelineStatus.draft) {
if (savedTimeline.status === TimelineStatus.draft || savedTimeline.status == null) {
savedTimeline.status = !isEmpty(savedTimeline.title)
? TimelineStatus.active
: TimelineStatus.draft;
Expand Down

0 comments on commit 8b65c18

Please sign in to comment.