From 5b67ec932e16b2e7817f73322687b4670f993975 Mon Sep 17 00:00:00 2001 From: Angelique Date: Thu, 31 Oct 2024 10:05:23 +0100 Subject: [PATCH 1/2] [backend] Taxii feed cursor should be reset when data from is changed on UI (#8463) --- .../02-resolvers/ingestion-taxii-test.ts | 51 ++++++++++++++----- .../tests/utils/testQueryHelper.ts | 9 ++++ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/opencti-platform/opencti-graphql/tests/02-integration/02-resolvers/ingestion-taxii-test.ts b/opencti-platform/opencti-graphql/tests/02-integration/02-resolvers/ingestion-taxii-test.ts index 04f1b649fefb..94b225a2cec8 100644 --- a/opencti-platform/opencti-graphql/tests/02-integration/02-resolvers/ingestion-taxii-test.ts +++ b/opencti-platform/opencti-graphql/tests/02-integration/02-resolvers/ingestion-taxii-test.ts @@ -3,7 +3,9 @@ import gql from 'graphql-tag'; import type { GraphQLFormattedError } from 'graphql/error'; import { queryAsAdminWithSuccess } from '../../utils/testQueryHelper'; import { IngestionAuthType, TaxiiVersion } from '../../../src/generated/graphql'; -import { queryAsAdmin } from '../../utils/testQuery'; +import { ADMIN_USER, queryAsAdmin, testContext } from '../../utils/testQuery'; +import { now, utcDate } from '../../../src/utils/format'; +import { patchTaxiiIngestion } from '../../../src/modules/ingestion/ingestion-taxii-domain'; describe('TAXII ingestion resolver standard behavior', () => { let createdTaxiiIngesterId: string; @@ -20,14 +22,14 @@ describe('TAXII ingestion resolver standard behavior', () => { }; const ingesterQueryResult = await queryAsAdminWithSuccess({ query: gql` - mutation createTaxiiIngester($input: IngestionTaxiiAddInput!) { - ingestionTaxiiAdd(input: $input) { - id - entity_type - ingestion_running - } - }, - `, + mutation createTaxiiIngester($input: IngestionTaxiiAddInput!) { + ingestionTaxiiAdd(input: $input) { + id + entity_type + ingestion_running + } + }, + `, variables: INGESTER_TO_CREATE }); expect(ingesterQueryResult.data?.ingestionTaxiiAdd.id).toBeDefined(); @@ -52,6 +54,29 @@ describe('TAXII ingestion resolver standard behavior', () => { expect(ingesterQueryResult.data?.ingestionTaxiiFieldPatch.authentication_value).toEqual('username:P@ssw0rd!'); }); + it('should change date reset cursor', async () => { + // shortcut to set a cursor that is defined + const state = { current_state_cursor: 'aaaaaaaaaaaaaaaaaaa', last_execution_date: now() }; + const result = await patchTaxiiIngestion(testContext, ADMIN_USER, createdTaxiiIngesterId, state); + expect(result.current_state_cursor).toBe('aaaaaaaaaaaaaaaaaaa'); + + const ingesterChangeDateResult = await queryAsAdminWithSuccess({ + query: gql` + mutation ingestionTaxiiFieldPatch($id: ID!, $input: [EditInput!]!) { + ingestionTaxiiFieldPatch(id: $id, input: $input) { + id + current_state_cursor + added_after_start + } + } + `, + variables: { id: createdTaxiiIngesterId, input: [{ key: 'added_after_start', value: [now()] }] } + }); + console.log('ingesterChangeDateResult:', { result: ingesterChangeDateResult.data?.ingestionTaxiiFieldPatch }); + expect(ingesterChangeDateResult.data?.ingestionTaxiiFieldPatch.id).toBeDefined(); + expect(ingesterChangeDateResult.data?.ingestionTaxiiFieldPatch.current_state_cursor).not.toBeDefined(); + }); + it('should edit a TAXII ingester with : in authentication value be refused', async () => { const ingesterQueryResult = await queryAsAdmin({ query: gql` @@ -75,10 +100,10 @@ describe('TAXII ingestion resolver standard behavior', () => { it('should delete a TAXII ingester', async () => { const ingesterQueryResult = await queryAsAdminWithSuccess({ query: gql` - mutation deleteTaxiiIngester($id: ID!) { - ingestionTaxiiDelete(id: $id) - } - `, + mutation deleteTaxiiIngester($id: ID!) { + ingestionTaxiiDelete(id: $id) + } + `, variables: { id: createdTaxiiIngesterId } }); expect(ingesterQueryResult.data?.ingestionTaxiiDelete).toEqual(createdTaxiiIngesterId); diff --git a/opencti-platform/opencti-graphql/tests/utils/testQueryHelper.ts b/opencti-platform/opencti-graphql/tests/utils/testQueryHelper.ts index 9722263a87d8..b3f880143458 100644 --- a/opencti-platform/opencti-graphql/tests/utils/testQueryHelper.ts +++ b/opencti-platform/opencti-graphql/tests/utils/testQueryHelper.ts @@ -21,6 +21,9 @@ export const queryAsAdminWithSuccess = async (request: { query: any, variables: variables: request.variables, }); expect(requestResult, `Something is wrong with this query: ${request.query}`).toBeDefined(); + if (requestResult.errors) { + logApp.info('Unexpected error; requestResult:', { requestResult }); + } expect(requestResult.errors, `This errors should not be there: ${requestResult.errors}`).toBeUndefined(); return requestResult; }; @@ -31,6 +34,9 @@ export const adminQueryWithSuccess = async (request: { query: any, variables: an variables: request.variables, }); expect(requestResult, `Something is wrong with this query: ${request.query}`).toBeDefined(); + if (requestResult.errors) { + logApp.info('Unexpected error; requestResult:', { requestResult }); + } expect(requestResult.errors, `This errors should not be there: ${requestResult.errors}`).toBeUndefined(); return requestResult; }; @@ -43,6 +49,9 @@ export const adminQueryWithSuccess = async (request: { query: any, variables: an export const queryAsUserWithSuccess = async (client: AxiosInstance, request: { query: any, variables: any }) => { const requestResult = await executeInternalQuery(client, print(request.query), request.variables); expect(requestResult, `Something is wrong with this query: ${request.query}`).toBeDefined(); + if (requestResult.errors) { + logApp.info('Unexpected error; requestResult:', { requestResult }); + } expect(requestResult.errors, `This errors should not be there: ${JSON.stringify(requestResult.errors)}`).toBeUndefined(); return requestResult; }; From 84a8e1945d54f1c2885202df0980456095845efe Mon Sep 17 00:00:00 2001 From: Angelique Date: Thu, 31 Oct 2024 10:43:56 +0100 Subject: [PATCH 2/2] Reset cursor state when date is changed by user --- opencti-platform/opencti-graphql/config/test.json | 3 +++ .../src/modules/ingestion/ingestion-taxii-domain.ts | 6 ++++++ .../02-resolvers/ingestion-taxii-test.ts | 12 +++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/opencti-platform/opencti-graphql/config/test.json b/opencti-platform/opencti-graphql/config/test.json index fa159c23982f..e7d78c93191f 100644 --- a/opencti-platform/opencti-graphql/config/test.json +++ b/opencti-platform/opencti-graphql/config/test.json @@ -93,6 +93,9 @@ "enabled": true, "interval": 6000000 }, + "ingestion_manager": { + "enabled": false + }, "providers": { "local": { "strategy": "LocalStrategy" diff --git a/opencti-platform/opencti-graphql/src/modules/ingestion/ingestion-taxii-domain.ts b/opencti-platform/opencti-graphql/src/modules/ingestion/ingestion-taxii-domain.ts index 76bece33304a..1357d72cdd6d 100644 --- a/opencti-platform/opencti-graphql/src/modules/ingestion/ingestion-taxii-domain.ts +++ b/opencti-platform/opencti-graphql/src/modules/ingestion/ingestion-taxii-domain.ts @@ -60,6 +60,7 @@ export const ingestionEditField = async (context: AuthContext, user: AuthUser, i verifyIngestionAuthenticationContent(ingestionConfiguration.authentication_type, authenticationValueField.value[0]); } } + const { element } = await updateAttribute(context, user, ingestionId, ENTITY_TYPE_INGESTION_TAXII, input); await registerConnectorForIngestion(context, { id: element.id, @@ -68,6 +69,11 @@ export const ingestionEditField = async (context: AuthContext, user: AuthUser, i is_running: element.ingestion_running ?? false, connector_user_id: element.user_id }); + + if (input.some(((editInput) => editInput.key === 'added_after_start'))) { + await patchTaxiiIngestion(context, user, ingestionId, { current_state_cursor: undefined }); + } + await publishUserAction({ user, event_type: 'mutation', diff --git a/opencti-platform/opencti-graphql/tests/02-integration/02-resolvers/ingestion-taxii-test.ts b/opencti-platform/opencti-graphql/tests/02-integration/02-resolvers/ingestion-taxii-test.ts index 94b225a2cec8..12c669a715c1 100644 --- a/opencti-platform/opencti-graphql/tests/02-integration/02-resolvers/ingestion-taxii-test.ts +++ b/opencti-platform/opencti-graphql/tests/02-integration/02-resolvers/ingestion-taxii-test.ts @@ -4,8 +4,8 @@ import type { GraphQLFormattedError } from 'graphql/error'; import { queryAsAdminWithSuccess } from '../../utils/testQueryHelper'; import { IngestionAuthType, TaxiiVersion } from '../../../src/generated/graphql'; import { ADMIN_USER, queryAsAdmin, testContext } from '../../utils/testQuery'; -import { now, utcDate } from '../../../src/utils/format'; -import { patchTaxiiIngestion } from '../../../src/modules/ingestion/ingestion-taxii-domain'; +import { now } from '../../../src/utils/format'; +import { findById as findIngestionById, patchTaxiiIngestion } from '../../../src/modules/ingestion/ingestion-taxii-domain'; describe('TAXII ingestion resolver standard behavior', () => { let createdTaxiiIngesterId: string; @@ -54,7 +54,7 @@ describe('TAXII ingestion resolver standard behavior', () => { expect(ingesterQueryResult.data?.ingestionTaxiiFieldPatch.authentication_value).toEqual('username:P@ssw0rd!'); }); - it('should change date reset cursor', async () => { + it('should reset cursor when a user change the start date', async () => { // shortcut to set a cursor that is defined const state = { current_state_cursor: 'aaaaaaaaaaaaaaaaaaa', last_execution_date: now() }; const result = await patchTaxiiIngestion(testContext, ADMIN_USER, createdTaxiiIngesterId, state); @@ -72,9 +72,11 @@ describe('TAXII ingestion resolver standard behavior', () => { `, variables: { id: createdTaxiiIngesterId, input: [{ key: 'added_after_start', value: [now()] }] } }); - console.log('ingesterChangeDateResult:', { result: ingesterChangeDateResult.data?.ingestionTaxiiFieldPatch }); expect(ingesterChangeDateResult.data?.ingestionTaxiiFieldPatch.id).toBeDefined(); - expect(ingesterChangeDateResult.data?.ingestionTaxiiFieldPatch.current_state_cursor).not.toBeDefined(); + + const ingestionState = await findIngestionById(testContext, ADMIN_USER, createdTaxiiIngesterId); + expect(ingestionState.id).toBeDefined(); + expect(ingestionState.current_state_cursor).not.toBeDefined(); }); it('should edit a TAXII ingester with : in authentication value be refused', async () => {