Skip to content

Commit

Permalink
[Security Solution][Resolver] New mock with cursor (#78863) (#79356)
Browse files Browse the repository at this point in the history
* New mock with cursor

* include next cursor

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Brent Kimmel <bkimmel@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
4 people authored Oct 5, 2020
1 parent 45fad13 commit a846cf7
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* 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 { DataAccessLayer } from '../../types';
import {
mockTreeWithNoAncestorsAndTwoChildrenAndRelatedEventsOnOrigin,
firstRelatedEventID,
secondRelatedEventID,
} from '../../mocks/resolver_tree';
import {
ResolverRelatedEvents,
ResolverTree,
ResolverEntityIndex,
SafeResolverEvent,
} from '../../../../common/endpoint/types';
import * as eventModel from '../../../../common/endpoint/models/event';

interface Metadata {
/**
* The `_id` of the document being analyzed.
*/
databaseDocumentID: string;
/**
* A record of entityIDs to be used in tests assertions.
*/
entityIDs: {
/**
* The entityID of the node related to the document being analyzed.
*/
origin: 'origin';
/**
* The entityID of the first child of the origin.
*/
firstChild: 'firstChild';
/**
* The entityID of the second child of the origin.
*/
secondChild: 'secondChild';
};
}

/**
* See the other mock `noAncestorsTwoChildrenWithRelatedEventsOnOrigin` but this one
* has one of the related events "after" the first (i.e. you have to call with `after` to
* get the second one).
*/
export function noAncestorsTwoChildrenWithRelatedEventsOnOriginWithOneAfterCursor(): {
dataAccessLayer: DataAccessLayer;
metadata: Metadata;
} {
const metadata: Metadata = {
databaseDocumentID: '_id',
entityIDs: { origin: 'origin', firstChild: 'firstChild', secondChild: 'secondChild' },
};
const tree = mockTreeWithNoAncestorsAndTwoChildrenAndRelatedEventsOnOrigin({
originID: metadata.entityIDs.origin,
firstChildID: metadata.entityIDs.firstChild,
secondChildID: metadata.entityIDs.secondChild,
});

return {
metadata,
dataAccessLayer: {
/**
* Fetch related events for an entity ID
*/
async relatedEvents(entityID: string): Promise<ResolverRelatedEvents> {
/**
* Respond with the mocked related events when the origin's related events are fetched.
**/
const events = entityID === metadata.entityIDs.origin ? tree.relatedEvents.events : [];

return {
entityID,
events,
nextEvent: null,
};
},

/**
* Any of the origin's related events by category.
* `entityID` must match the origin node's `process.entity_id`.
* These are split by the `after` cursor: Calling without the cursor will
* return the first event, calling with the cursor set to the id of the first event
* will return the second.
*/
async eventsWithEntityIDAndCategory(
entityID: string,
category: string,
after?: string
): Promise<{ events: SafeResolverEvent[]; nextEvent: string | null }> {
/**
* For testing: This 'fakes' the behavior of one related event being `after`
* a cursor for an earlier event.
* @param event A `SafeResolverEvent` to filter
*/
function splitOnCursor(event: SafeResolverEvent) {
if (typeof after === 'undefined') {
return eventModel.eventID(event) === firstRelatedEventID;
}
if (after === firstRelatedEventID) {
return eventModel.eventID(event) === secondRelatedEventID;
}
return false;
}

const events =
entityID === metadata.entityIDs.origin
? tree.relatedEvents.events.filter(
(event) =>
eventModel.eventCategory(event).includes(category) && splitOnCursor(event)
)
: [];
return {
events,
nextEvent: typeof after === 'undefined' ? firstRelatedEventID : null,
};
},

/**
* Any of the origin's related events by event.id
*/
async event(eventID: string): Promise<SafeResolverEvent | null> {
return (
tree.relatedEvents.events.find((event) => eventModel.eventID(event) === eventID) ?? null
);
},

/**
* Fetch a ResolverTree for a entityID
*/
async resolverTree(): Promise<ResolverTree> {
return tree;
},

/**
* Get entities matching a document.
*/
async entities(): Promise<ResolverEntityIndex> {
return [{ entity_id: metadata.entityIDs.origin }];
},
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,15 @@ export function mockTreeWithNoProcessEvents(): ResolverTree {
};
}

/**
* first ID (to check in the mock data access layer)
*/
export const firstRelatedEventID = 'id of first related event';
/**
* second ID (to check in the mock data access layer)
*/
export const secondRelatedEventID = 'id of second related event';

export function mockTreeWithNoAncestorsAndTwoChildrenAndRelatedEventsOnOrigin({
originID,
firstChildID,
Expand All @@ -326,14 +335,14 @@ export function mockTreeWithNoAncestorsAndTwoChildrenAndRelatedEventsOnOrigin({
mockEndpointEvent({
entityID: originID,
parentEntityID,
eventID: 'first related event',
eventID: firstRelatedEventID,
eventType: 'access',
eventCategory: 'registry',
}),
mockEndpointEvent({
entityID: originID,
parentEntityID,
eventID: 'second related event',
eventID: secondRelatedEventID,
eventType: 'access',
eventCategory: 'registry',
}),
Expand Down

0 comments on commit a846cf7

Please sign in to comment.