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][Analyzer] Make all analyzer apis have time range as optional #142536

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ export const validateEvents = {
afterEvent: schema.maybe(schema.string()),
}),
body: schema.object({
timeRange: schema.object({
from: schema.string(),
to: schema.string(),
}),
timeRange: schema.maybe(
schema.object({
from: schema.string(),
to: schema.string(),
})
),
indexPatterns: schema.arrayOf(schema.string()),
filter: schema.maybe(schema.string()),
entityType: schema.maybe(schema.string()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ describe('Analyze events view for alerts', () => {
waitForAlertsToPopulate();
});

it('should render analyzer when button is clicked', () => {
it('should render when button is clicked', () => {
openAnalyzerForFirstAlertInTimeline();
cy.get(ANALYZER_NODE).first().should('be.visible');
});

it(`should render an analyzer view and display
it(`should display
a toast indicating the date range of found events when a time range has 0 events in it`, () => {
const dateContainingZeroEvents = 'Jul 27, 2022 @ 00:00:00.000';
setStartDate(dateContainingZeroEvents);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ import type {
ResolverSchema,
} from '../../../common/endpoint/types';

function getRangeFilter(timeRange: TimeRange | undefined) {
return timeRange
? {
timeRange: {
from: timeRange.from,
to: timeRange.to,
},
}
: [];
}

/**
* The data access layer for resolver. All communication with the Kibana server is done through this object. This object is provided to Resolver. In tests, a mock data access layer can be used instead.
*/
Expand All @@ -34,7 +45,7 @@ export function dataAccessLayerFactory(
indexPatterns,
}: {
entityID: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<ResolverRelatedEvents> {
const response: ResolverPaginatedEvents = await context.services.http.post(
Expand All @@ -43,10 +54,7 @@ export function dataAccessLayerFactory(
query: {},
body: JSON.stringify({
indexPatterns,
timeRange: {
from: timeRange.from,
to: timeRange.to,
},
...getRangeFilter(timeRange),
filter: JSON.stringify({
bool: {
filter: [
Expand Down Expand Up @@ -76,16 +84,13 @@ export function dataAccessLayerFactory(
entityID: string;
category: string;
after?: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<ResolverPaginatedEvents> {
const commonFields = {
query: { afterEvent: after, limit: 25 },
body: {
timeRange: {
from: timeRange.from,
to: timeRange.to,
},
...getRangeFilter(timeRange),
indexPatterns,
},
};
Expand Down Expand Up @@ -127,30 +132,28 @@ export function dataAccessLayerFactory(
limit,
}: {
ids: string[];
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
limit: number;
}): Promise<SafeResolverEvent[]> {
const response: ResolverPaginatedEvents = await context.services.http.post(
'/api/endpoint/resolver/events',
{
query: { limit },
body: JSON.stringify({
timeRange: {
from: timeRange.from,
to: timeRange.to,
const query = {
query: { limit },
body: JSON.stringify({
indexPatterns,
...getRangeFilter(timeRange),
filter: JSON.stringify({
bool: {
filter: [
{ terms: { 'process.entity_id': ids } },
{ term: { 'event.category': 'process' } },
],
},
indexPatterns,
filter: JSON.stringify({
bool: {
filter: [
{ terms: { 'process.entity_id': ids } },
{ term: { 'event.category': 'process' } },
],
},
}),
}),
}
}),
};
const response: ResolverPaginatedEvents = await context.services.http.post(
'/api/endpoint/resolver/events',
query
);
return response.events;
},
Expand All @@ -172,7 +175,7 @@ export function dataAccessLayerFactory(
eventTimestamp: string;
eventID?: string | number;
winlogRecordID: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<SafeResolverEvent | null> {
/** @description - eventID isn't provided by winlog. This can be removed once runtime fields are available */
Expand Down Expand Up @@ -200,10 +203,7 @@ export function dataAccessLayerFactory(
query: { limit: 1 },
body: JSON.stringify({
indexPatterns,
timeRange: {
from: timeRange.from,
to: timeRange.to,
},
...getRangeFilter(timeRange),
filter: JSON.stringify(filter),
}),
}
Expand All @@ -217,10 +217,7 @@ export function dataAccessLayerFactory(
query: { limit: 1 },
body: JSON.stringify({
indexPatterns,
timeRange: {
from: timeRange.from,
to: timeRange.to,
},
...getRangeFilter(timeRange),
entityType: 'alertDetail',
eventID,
}),
Expand Down Expand Up @@ -250,7 +247,7 @@ export function dataAccessLayerFactory(
}: {
dataId: string;
schema: ResolverSchema;
timeRange: TimeRange;
timeRange?: TimeRange;
indices: string[];
ancestors: number;
descendants: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function generateTreeWithDAL(
indexPatterns,
}: {
entityID: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<ResolverRelatedEvents> {
const node = allNodes.get(entityID);
Expand All @@ -88,7 +88,7 @@ export function generateTreeWithDAL(
entityID: string;
category: string;
after?: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<{ events: SafeResolverEvent[]; nextEvent: string | null }> {
const node = allNodes.get(entityID);
Expand Down Expand Up @@ -119,7 +119,7 @@ export function generateTreeWithDAL(
eventCategory: string[];
eventTimestamp: string;
eventID?: string | number;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<SafeResolverEvent | null> {
return null;
Expand All @@ -135,7 +135,7 @@ export function generateTreeWithDAL(
limit,
}: {
ids: string[];
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
limit: number;
}): Promise<SafeResolverEvent[]> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export function noAncestorsTwoChildren(): { dataAccessLayer: DataAccessLayer; me
indexPatterns,
}: {
entityID: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<ResolverRelatedEvents> {
return Promise.resolve({
Expand All @@ -83,7 +83,7 @@ export function noAncestorsTwoChildren(): { dataAccessLayer: DataAccessLayer; me
entityID: string;
category: string;
after?: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<{
events: SafeResolverEvent[];
Expand All @@ -110,7 +110,7 @@ export function noAncestorsTwoChildren(): { dataAccessLayer: DataAccessLayer; me
eventTimestamp: string;
eventID?: string | number;
winlogRecordID: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<SafeResolverEvent | null> {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function noAncestorsTwoChildenInIndexCalledAwesomeIndex(): {
indexPatterns,
}: {
entityID: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<ResolverRelatedEvents> {
return Promise.resolve({
Expand All @@ -90,7 +90,7 @@ export function noAncestorsTwoChildenInIndexCalledAwesomeIndex(): {
entityID: string;
category: string;
after?: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<{
events: SafeResolverEvent[];
Expand Down Expand Up @@ -121,7 +121,7 @@ export function noAncestorsTwoChildenInIndexCalledAwesomeIndex(): {
eventTimestamp: string;
eventID?: string | number;
winlogRecordID: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<SafeResolverEvent | null> {
return mockEndpointEvent({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export function noAncestorsTwoChildrenWithRelatedEventsOnOrigin(): {
indexPatterns,
}: {
entityID: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<ResolverRelatedEvents> {
/**
Expand Down Expand Up @@ -97,7 +97,7 @@ export function noAncestorsTwoChildrenWithRelatedEventsOnOrigin(): {
entityID: string;
category: string;
after?: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<{ events: SafeResolverEvent[]; nextEvent: string | null }> {
const events =
Expand Down Expand Up @@ -129,7 +129,7 @@ export function noAncestorsTwoChildrenWithRelatedEventsOnOrigin(): {
eventTimestamp: string;
eventID?: string | number;
winlogRecordID: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<SafeResolverEvent | null> {
return relatedEvents.events.find((event) => eventModel.eventID(event) === eventID) ?? null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function oneNodeWithPaginatedEvents(): {
indexPatterns,
}: {
entityID: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<ResolverRelatedEvents> {
/**
Expand Down Expand Up @@ -86,7 +86,7 @@ export function oneNodeWithPaginatedEvents(): {
entityID: string;
category: string;
after?: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<{ events: SafeResolverEvent[]; nextEvent: string | null }> {
let events: SafeResolverEvent[] = [];
Expand Down Expand Up @@ -121,7 +121,7 @@ export function oneNodeWithPaginatedEvents(): {
eventTimestamp: string;
eventID?: string | number;
winlogRecordID: string;
timeRange: TimeRange;
timeRange?: TimeRange;
indexPatterns: string[];
}): Promise<SafeResolverEvent | null> {
return mockTree.events.find((event) => eventModel.eventID(event) === eventID) ?? null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ export function CurrentRelatedEventFetcher(
api.dispatch({
type: 'appRequestedCurrentRelatedEventData',
});
const timeRangeFilters = selectors.timeRangeFilters(state);

const detectedBounds = selectors.detectedBounds(state);
const timeRangeFilters =
detectedBounds !== undefined ? undefined : selectors.timeRangeFilters(state);
let result: SafeResolverEvent | null = null;
try {
result = await dataAccessLayer.event({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ export function NodeDataFetcher(

let results: SafeResolverEvent[] | undefined;
try {
const timeRangeFilters = selectors.timeRangeFilters(state);
const detectedBounds = selectors.detectedBounds(state);
const timeRangeFilters =
detectedBounds !== undefined ? undefined : selectors.timeRangeFilters(state);
results = await dataAccessLayer.nodeData({
ids: Array.from(newIDsToRequest),
timeRange: timeRangeFilters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ export function RelatedEventsFetcher(
const indices = selectors.eventIndices(state);

const oldParams = last;
const timeRangeFilters = selectors.timeRangeFilters(state);
const detectedBounds = selectors.detectedBounds(state);
const timeRangeFilters =
detectedBounds !== undefined ? undefined : selectors.timeRangeFilters(state);
// Update this each time before fetching data (or even if we don't fetch data) so that subsequent actions that call this (concurrently) will have up to date info.
last = newParams;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ export function ResolverTreeFetcher(
descendants: descendantsRequestAmount(),
});
if (unboundedTree.length > 0) {
const timestamps = unboundedTree.map((event) =>
firstNonNullValue(event.data['@timestamp'])
);
const timestamps = unboundedTree
.map((event) => firstNonNullValue(event.data['@timestamp']))
.sort();
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we expect unboundedTree to potentially contain thousands of entries?

const oldestTimestamp = timestamps[0];
const newestTimestamp = timestamps.slice(-1);
api.dispatch({
Expand Down
Loading