Skip to content

Commit a846cf7

Browse files
michaelolo24bkimmelelasticmachinekibanamachine
authored
[Security Solution][Resolver] New mock with cursor (#78863) (#79356)
* New mock with cursor * include next cursor Co-authored-by: Elastic Machine <[email protected]> Co-authored-by: Brent Kimmel <[email protected]> Co-authored-by: Elastic Machine <[email protected]> Co-authored-by: Kibana Machine <[email protected]>
1 parent 45fad13 commit a846cf7

File tree

2 files changed

+158
-2
lines changed

2 files changed

+158
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { DataAccessLayer } from '../../types';
8+
import {
9+
mockTreeWithNoAncestorsAndTwoChildrenAndRelatedEventsOnOrigin,
10+
firstRelatedEventID,
11+
secondRelatedEventID,
12+
} from '../../mocks/resolver_tree';
13+
import {
14+
ResolverRelatedEvents,
15+
ResolverTree,
16+
ResolverEntityIndex,
17+
SafeResolverEvent,
18+
} from '../../../../common/endpoint/types';
19+
import * as eventModel from '../../../../common/endpoint/models/event';
20+
21+
interface Metadata {
22+
/**
23+
* The `_id` of the document being analyzed.
24+
*/
25+
databaseDocumentID: string;
26+
/**
27+
* A record of entityIDs to be used in tests assertions.
28+
*/
29+
entityIDs: {
30+
/**
31+
* The entityID of the node related to the document being analyzed.
32+
*/
33+
origin: 'origin';
34+
/**
35+
* The entityID of the first child of the origin.
36+
*/
37+
firstChild: 'firstChild';
38+
/**
39+
* The entityID of the second child of the origin.
40+
*/
41+
secondChild: 'secondChild';
42+
};
43+
}
44+
45+
/**
46+
* See the other mock `noAncestorsTwoChildrenWithRelatedEventsOnOrigin` but this one
47+
* has one of the related events "after" the first (i.e. you have to call with `after` to
48+
* get the second one).
49+
*/
50+
export function noAncestorsTwoChildrenWithRelatedEventsOnOriginWithOneAfterCursor(): {
51+
dataAccessLayer: DataAccessLayer;
52+
metadata: Metadata;
53+
} {
54+
const metadata: Metadata = {
55+
databaseDocumentID: '_id',
56+
entityIDs: { origin: 'origin', firstChild: 'firstChild', secondChild: 'secondChild' },
57+
};
58+
const tree = mockTreeWithNoAncestorsAndTwoChildrenAndRelatedEventsOnOrigin({
59+
originID: metadata.entityIDs.origin,
60+
firstChildID: metadata.entityIDs.firstChild,
61+
secondChildID: metadata.entityIDs.secondChild,
62+
});
63+
64+
return {
65+
metadata,
66+
dataAccessLayer: {
67+
/**
68+
* Fetch related events for an entity ID
69+
*/
70+
async relatedEvents(entityID: string): Promise<ResolverRelatedEvents> {
71+
/**
72+
* Respond with the mocked related events when the origin's related events are fetched.
73+
**/
74+
const events = entityID === metadata.entityIDs.origin ? tree.relatedEvents.events : [];
75+
76+
return {
77+
entityID,
78+
events,
79+
nextEvent: null,
80+
};
81+
},
82+
83+
/**
84+
* Any of the origin's related events by category.
85+
* `entityID` must match the origin node's `process.entity_id`.
86+
* These are split by the `after` cursor: Calling without the cursor will
87+
* return the first event, calling with the cursor set to the id of the first event
88+
* will return the second.
89+
*/
90+
async eventsWithEntityIDAndCategory(
91+
entityID: string,
92+
category: string,
93+
after?: string
94+
): Promise<{ events: SafeResolverEvent[]; nextEvent: string | null }> {
95+
/**
96+
* For testing: This 'fakes' the behavior of one related event being `after`
97+
* a cursor for an earlier event.
98+
* @param event A `SafeResolverEvent` to filter
99+
*/
100+
function splitOnCursor(event: SafeResolverEvent) {
101+
if (typeof after === 'undefined') {
102+
return eventModel.eventID(event) === firstRelatedEventID;
103+
}
104+
if (after === firstRelatedEventID) {
105+
return eventModel.eventID(event) === secondRelatedEventID;
106+
}
107+
return false;
108+
}
109+
110+
const events =
111+
entityID === metadata.entityIDs.origin
112+
? tree.relatedEvents.events.filter(
113+
(event) =>
114+
eventModel.eventCategory(event).includes(category) && splitOnCursor(event)
115+
)
116+
: [];
117+
return {
118+
events,
119+
nextEvent: typeof after === 'undefined' ? firstRelatedEventID : null,
120+
};
121+
},
122+
123+
/**
124+
* Any of the origin's related events by event.id
125+
*/
126+
async event(eventID: string): Promise<SafeResolverEvent | null> {
127+
return (
128+
tree.relatedEvents.events.find((event) => eventModel.eventID(event) === eventID) ?? null
129+
);
130+
},
131+
132+
/**
133+
* Fetch a ResolverTree for a entityID
134+
*/
135+
async resolverTree(): Promise<ResolverTree> {
136+
return tree;
137+
},
138+
139+
/**
140+
* Get entities matching a document.
141+
*/
142+
async entities(): Promise<ResolverEntityIndex> {
143+
return [{ entity_id: metadata.entityIDs.origin }];
144+
},
145+
},
146+
};
147+
}

x-pack/plugins/security_solution/public/resolver/mocks/resolver_tree.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,15 @@ export function mockTreeWithNoProcessEvents(): ResolverTree {
307307
};
308308
}
309309

310+
/**
311+
* first ID (to check in the mock data access layer)
312+
*/
313+
export const firstRelatedEventID = 'id of first related event';
314+
/**
315+
* second ID (to check in the mock data access layer)
316+
*/
317+
export const secondRelatedEventID = 'id of second related event';
318+
310319
export function mockTreeWithNoAncestorsAndTwoChildrenAndRelatedEventsOnOrigin({
311320
originID,
312321
firstChildID,
@@ -326,14 +335,14 @@ export function mockTreeWithNoAncestorsAndTwoChildrenAndRelatedEventsOnOrigin({
326335
mockEndpointEvent({
327336
entityID: originID,
328337
parentEntityID,
329-
eventID: 'first related event',
338+
eventID: firstRelatedEventID,
330339
eventType: 'access',
331340
eventCategory: 'registry',
332341
}),
333342
mockEndpointEvent({
334343
entityID: originID,
335344
parentEntityID,
336-
eventID: 'second related event',
345+
eventID: secondRelatedEventID,
337346
eventType: 'access',
338347
eventCategory: 'registry',
339348
}),

0 commit comments

Comments
 (0)