import expect from '@kbn/expect' ; import { entityIDSafeVersion , timestampAsDateSafeVersion , } from '../../../../plugins/security_solution/common/endpoint/models/event' ; import { eventsIndexPattern } from '../../../../plugins/security_solution/common/endpoint/constants' ; import { ResolverEntityIndex , ResolverNode , } from '../../../../plugins/security_solution/common/endpoint/types' ; import { FtrProviderContext } from '../../ftr_provider_context' ; import { EndpointDocGenerator , Event , } from '../../../../plugins/security_solution/common/endpoint/generate_data' ; import { InsertedEvents , processEventsIndex } from '../../services/resolver' ; import { createAncestryArray , schemaWithAncestry } from './common' ; export default function ( { getService } ) { const supertest = getService ( 'supertest' ) ; const resolver = getService ( 'resolverGenerator' ) ; const generator = new EndpointDocGenerator ( 'resolver' ) ; const setEntityIDEmptyString = ( event ) => { if ( event . process ?. entity_id ) { event . process . entity_id = '' ; } } ; describe ( 'Resolver handling of entity ids' , ( ) => { describe ( 'entity api' , ( ) => { let origin ; let genData ; before ( async ( ) => { origin = generator . generateEvent ( { parentEntityID : 'a' , eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( processEventsIndex ) , } ) ; setEntityIDEmptyString ( origin ) ; genData = await resolver . insertEvents ( [ origin ] , processEventsIndex ) ; } ) ; after ( async ( ) => { await resolver . deleteData ( genData ) ; } ) ; it ( 'excludes events that have an empty entity_id field' , async ( ) => { const { body } = await supertest . get ( `/api/endpoint/resolver/entity?_id=${ genData . eventsInfo [ 0 ] . _id }&indices=${ eventsIndexPattern }&indices=${ eventsIndexPattern }` ) ; expect ( body ) . to . be . empty ( ) ; } ) ; } ) ; describe ( 'children' , ( ) => { let origin ; let childNoEntityID ; let childWithEntityID ; let events ; let genData ; before ( async ( ) => { origin = generator . generateEvent ( { entityID : 'a' , eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( processEventsIndex ) , } ) ; childNoEntityID = generator . generateEvent ( { parentEntityID : entityIDSafeVersion ( origin ) , ancestry : createAncestryArray ( [ origin ] ) , eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( processEventsIndex ) , } ) ; setEntityIDEmptyString ( childNoEntityID ) ; childWithEntityID = generator . generateEvent ( { entityID : 'b' , parentEntityID : entityIDSafeVersion ( origin ) , ancestry : createAncestryArray ( [ origin ] ) , eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( processEventsIndex ) , } ) ; events = [ origin , childNoEntityID , childWithEntityID ] ; genData = await resolver . insertEvents ( events , processEventsIndex ) ; } ) ; after ( async ( ) => { await resolver . deleteData ( genData ) ; } ) ; it ( 'does not find children without a process entity_id' , async ( ) => { const { body } = await supertest . post ( '/api/endpoint/resolver/tree' ) . set ( 'kbn-xsrf' , 'xxx' ) . send ( { descendants : 100 , ancestors : 0 , schema : schemaWithAncestry , nodes : [ origin . process ?. entity_id ] , timeRange : { from : timestampAsDateSafeVersion ( origin ) ?. toISOString ( ) , to : timestampAsDateSafeVersion ( childWithEntityID ) ?. toISOString ( ) , } , indexPatterns : [ 'logs-*' ] , } ) . expect ( 200 ) ; expect ( body . length ) . to . be ( 1 ) ; expect ( body [ 0 ] . id ) . to . be ( childWithEntityID . process ?. entity_id ) ; } ) ; } ) ; describe ( 'ancestors' , ( ) => { let origin ; let ancestor1 ; let ancestor2 ; let ancestorNoEntityID ; let events ; let genData ; before ( async ( ) => { ancestor2 = generator . generateEvent ( { entityID : '2' , eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( processEventsIndex ) , } ) ; ancestor1 = generator . generateEvent ( { entityID : '1' , parentEntityID : entityIDSafeVersion ( ancestor2 ) , ancestry : createAncestryArray ( [ ancestor2 ] ) , eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( processEventsIndex ) , } ) ; ancestorNoEntityID = generator . generateEvent ( { ancestry : createAncestryArray ( [ ancestor2 ] ) , eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( processEventsIndex ) , } ) ; setEntityIDEmptyString ( ancestorNoEntityID ) ; origin = generator . generateEvent ( { entityID : 'a' , parentEntityID : entityIDSafeVersion ( ancestor1 ) , ancestry : [ '' , ... createAncestryArray ( [ ancestor2 ] ) ] , eventsDataStream : EndpointDocGenerator . createDataStreamFromIndex ( processEventsIndex ) , } ) ; events = [ origin , ancestor1 , ancestor2 , ancestorNoEntityID ] ; genData = await resolver . insertEvents ( events , processEventsIndex ) ; } ) ; after ( async ( ) => { await resolver . deleteData ( genData ) ; } ) ; it ( 'does not query for ancestors that have an empty string for the entity_id' , async ( ) => { const hasID = ( nodes , id ) : boolean => { if ( ! id ) { return false ; } return nodes . find ( ( node ) => node . id === id ) !== undefined ; } ; const { body } = await supertest . post ( '/api/endpoint/resolver/tree' ) . set ( 'kbn-xsrf' , 'xxx' ) . send ( { descendants : 0 , ancestors : 10 , schema : schemaWithAncestry , nodes : [ origin . process ?. entity_id ] , timeRange : { from : timestampAsDateSafeVersion ( ancestor2 ) ?. toISOString ( ) , to : timestampAsDateSafeVersion ( origin ) ?. toISOString ( ) , } , indexPatterns : [ 'logs-*' ] , } ) . expect ( 200 ) ; expect ( body . length ) . to . be ( 2 ) ; expect ( hasID ( body , entityIDSafeVersion ( origin ) ) ) . to . be ( true ) ; expect ( hasID ( body , entityIDSafeVersion ( ancestor2 ) ) ) . to . be ( true ) ; } ) ; } ) ; } ) ; }