Skip to content

Commit 6795f2c

Browse files
[backend] validate date inputs format in validateInputAgainstSchema (#10881)
1 parent 89047ca commit 6795f2c

File tree

5 files changed

+33
-7
lines changed

5 files changed

+33
-7
lines changed

opencti-platform/opencti-graphql/src/manager/ingestionManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ export const processTaxiiResponse = async (context: AuthContext, ingestion: Basi
431431
// Reset the pagination cursor, and update date
432432
const state = {
433433
current_state_cursor: undefined,
434-
added_after_start: addedLastHeader ? utcDate(addedLastHeader) : utcDate(),
434+
added_after_start: addedLastHeader ? utcDate(addedLastHeader).toISOString() : now(),
435435
last_execution_date: now()
436436
};
437437
const ingestionUpdate = await patchTaxiiIngestion(context, SYSTEM_USER, ingestion.internal_id, state);
@@ -529,7 +529,7 @@ export const processCsvLines = async (
529529
await reportExpectation(context, ingestionUser, work.id);// csv file ends = 1 operation done.
530530

531531
logApp.info(`[OPENCTI-MODULE] INGESTION Csv - Sent: ${bundleCount} bundles for ${objectsInBundleCount} objects.`);
532-
const state = { current_state_hash: hashedIncomingData, added_after_start: utcDate(addedLast), last_execution_date: now() };
532+
const state = { current_state_hash: hashedIncomingData, added_after_start: utcDate(addedLast).toISOString(), last_execution_date: now() };
533533
await patchCsvIngestion(context, SYSTEM_USER, ingestion.internal_id, state);
534534
await updateBuiltInConnectorInfo(context, ingestion.user_id, ingestion.id, { state });
535535
}

opencti-platform/opencti-graphql/src/modules/ingestion/ingestion-taxii-domain.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { Moment } from 'moment/moment';
21
import { type BasicStoreEntityIngestionTaxii, ENTITY_TYPE_INGESTION_TAXII } from './ingestion-types';
32
import { createEntity, deleteElementById, patchAttribute, updateAttribute } from '../../database/middleware';
43
import { listAllEntities, listEntitiesPaginated, storeLoadById } from '../../database/middleware-loader';
@@ -51,7 +50,7 @@ export const addIngestion = async (context: AuthContext, user: AuthUser, input:
5150
export interface TaxiiIngestionPatch {
5251
current_state_cursor?: string | undefined,
5352
last_execution_date?: string,
54-
added_after_start?: Moment,
53+
added_after_start?: string,
5554
}
5655

5756
export const patchTaxiiIngestion = async (context: AuthContext, user: AuthUser, id: string, patch: TaxiiIngestionPatch) => {

opencti-platform/opencti-graphql/src/schema/schema-attributes.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as R from 'ramda';
2+
import { GraphQLDateTime } from 'graphql-scalars';
23
import { RULE_PREFIX } from './general';
34
import { FunctionalError, UnsupportedError } from '../config/errors';
45
import type { AttributeDefinition, AttrType, ComplexAttributeWithMappings, MappingDefinition } from './attribute-definition';
@@ -20,7 +21,7 @@ export const depsKeysRegister = {
2021
// -- Utilities to manipulate AttributeDefinitions --
2122

2223
const isMandatoryAttributeDefinition = (schemaDef: AttributeDefinition) => schemaDef.mandatoryType === 'external' || schemaDef.mandatoryType === 'internal';
23-
24+
const isDateAttributeDefinition = (schemaDef: AttributeDefinition) => schemaDef.type === 'date';
2425
const isNonFlatObjectAttributeDefinition = (schemaDef: AttributeDefinition) : schemaDef is ComplexAttributeWithMappings => { // handy typeguard
2526
return schemaDef.type === 'object' && schemaDef.format !== 'flat';
2627
};
@@ -301,6 +302,13 @@ const validateInputAgainstSchema = (input: any, schemaDef: AttributeDefinition)
301302
if (isMandatory && R.isNil(input)) {
302303
throw FunctionalError(`Validation against schema failed on attribute [${schemaDef.name}]: this mandatory field cannot be nil`);
303304
}
305+
if (isDateAttributeDefinition(schemaDef) && !R.isNil(input)) {
306+
try {
307+
GraphQLDateTime.parseValue(input);
308+
} catch {
309+
throw FunctionalError(`Validation against schema failed on attribute [${schemaDef.name}]: this date field is not in a valid format`);
310+
}
311+
}
304312

305313
if (isNonFlatObjectAttributeDefinition(schemaDef)) {
306314
if (!isMandatory && R.isNil(input)) {

opencti-platform/opencti-graphql/tests/02-integration/02-resolvers/ingestion-csv-test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import gql from 'graphql-tag';
33
import { ADMIN_USER, queryAsAdmin, testContext, USER_PARTICIPATE } from '../../utils/testQuery';
44
import { queryAsAdminWithSuccess, queryAsUserIsExpectedForbidden } from '../../utils/testQueryHelper';
55
import { patchCsvIngestion } from '../../../src/modules/ingestion/ingestion-csv-domain';
6-
import { utcDate } from '../../../src/utils/format';
6+
import { now } from '../../../src/utils/format';
77
import { SYSTEM_USER } from '../../../src/utils/access';
88

99
describe('CSV ingestion resolver standard behavior', () => {
@@ -156,7 +156,7 @@ describe('CSV ingestion resolver standard behavior', () => {
156156

157157
it('should reset state of CSV feeds ingester', async () => {
158158
// shortcut to set a hash that is defined
159-
const patch = { current_state_hash: 'bbbbbbbbbbbbbbbbbb', added_after_start: utcDate() };
159+
const patch = { current_state_hash: 'bbbbbbbbbbbbbbbbbb', added_after_start: now() };
160160
const result = await patchCsvIngestion(testContext, SYSTEM_USER, singleColumnCsvFeedIngesterId, patch);
161161
expect(result.current_state_hash).toBe('bbbbbbbbbbbbbbbbbb');
162162

opencti-platform/opencti-graphql/tests/02-integration/02-resolvers/report-test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,25 @@ describe('Report resolver standard behavior', () => {
337337
});
338338
expect(queryResult.data.reportEdit.fieldPatch.name).toEqual('Report - test');
339339
});
340+
it('should update report with invalid published date fail', async () => {
341+
const UPDATE_QUERY = gql`
342+
mutation ReportEdit($id: ID!, $input: [EditInput]!) {
343+
reportEdit(id: $id) {
344+
fieldPatch(input: $input) {
345+
id
346+
name
347+
description
348+
published
349+
}
350+
}
351+
}
352+
`;
353+
const queryResult = await queryAsAdmin({
354+
query: UPDATE_QUERY,
355+
variables: { id: reportInternalId, input: { key: 'published', value: ['2025-02-01'] } },
356+
});
357+
expect(queryResult.errors).toBeDefined();
358+
});
340359
it('should context patch report', async () => {
341360
const CONTEXT_PATCH_QUERY = gql`
342361
mutation ReportEdit($id: ID!, $input: EditContext) {

0 commit comments

Comments
 (0)