From 6c2956b5453283fd45c390ced327fc670f76d42f Mon Sep 17 00:00:00 2001 From: Souad Hadjiat Date: Wed, 3 Apr 2024 15:51:51 +0200 Subject: [PATCH] [backend] implement confirm delete --- .../opencti-graphql/src/database/utils.js | 1 + .../deleteOperation/deleteOperation-domain.ts | 39 ++++++++++++------- .../deleteOperation-resolvers.ts | 8 +--- .../deleteOperation/deleteOperation-types.ts | 6 ++- .../deleteOperation/deleteOperation.graphql | 4 +- 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/opencti-platform/opencti-graphql/src/database/utils.js b/opencti-platform/opencti-graphql/src/database/utils.js index ae7fe7f1d6030..e2831cc2d9fc4 100644 --- a/opencti-platform/opencti-graphql/src/database/utils.js +++ b/opencti-platform/opencti-graphql/src/database/utils.js @@ -36,6 +36,7 @@ export const UPDATE_OPERATION_REMOVE = 'remove'; // Entities export const INDEX_DELETED_OBJECTS = `${ES_INDEX_PREFIX}_deleted_objects`; +export const READ_INDEX_DELETED_OBJECTS = `${INDEX_DELETED_OBJECTS}*`; export const INDEX_FILES = `${ES_INDEX_PREFIX}_files`; export const READ_INDEX_FILES = `${INDEX_FILES}*`; export const INDEX_HISTORY = `${ES_INDEX_PREFIX}_history`; diff --git a/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-domain.ts b/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-domain.ts index 1cf981438ca49..8007c9880b855 100644 --- a/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-domain.ts +++ b/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-domain.ts @@ -1,27 +1,40 @@ -import type { AuthContext, AuthUser } from '../../types/user'; +import { type BasicStoreEntityDeleteOperation, ENTITY_TYPE_DELETE_OPERATION } from './deleteOperation-types'; +import { FunctionalError } from '../../config/errors'; +import { elDeleteInstances, elFindByIds } from '../../database/engine'; +import { deleteAllObjectFiles } from '../../database/file-storage'; import { listEntitiesPaginated, storeLoadById } from '../../database/middleware-loader'; +import { READ_INDEX_DELETED_OBJECTS } from '../../database/utils'; import type { QueryDeleteOperationsArgs } from '../../generated/graphql'; -import { type BasicStoreEntityDeleteOperation, ENTITY_TYPE_DELETE_OPERATION } from './deleteOperation-types'; - -export interface DeletedElement { - id: string - source_index: string -} +import type { AuthContext, AuthUser } from '../../types/user'; -export const findById = (context: AuthContext, user: AuthUser, id: string) => { +export const findById = async (context: AuthContext, user: AuthUser, id: string) => { return storeLoadById(context, user, id, ENTITY_TYPE_DELETE_OPERATION); }; -export const findAll = (context: AuthContext, user: AuthUser, args: QueryDeleteOperationsArgs) => { +export const findAll = async (context: AuthContext, user: AuthUser, args: QueryDeleteOperationsArgs) => { return listEntitiesPaginated(context, user, [ENTITY_TYPE_DELETE_OPERATION], args); }; // eslint-disable-next-line @typescript-eslint/no-unused-vars -export const restoreDelete = (context: AuthContext, user: AuthUser, id: string) => { +export const restoreDelete = async (context: AuthContext, user: AuthUser, id: string) => { throw new Error('Restore delete not implemented'); }; -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export const completeDelete = (context: AuthContext, user: AuthUser, id: string) => { - throw new Error('Complete delete not implemented'); +export const completeDelete = async (context: AuthContext, user: AuthUser, id: string) => { + const deleteOperation = await findById(context, user, id); + if (!deleteOperation) { + throw FunctionalError(`Delete operation ${id} cannot be found`); + } + const deletedElementsIds = deleteOperation.deleted_elements.map((el) => el.id); + // get deleted elements (from deleted_objects index) + const deletedElements: any[] = await elFindByIds(context, user, deletedElementsIds, { indices: READ_INDEX_DELETED_OBJECTS }) as any[]; + for (let index = 0; index < deletedElements.length; index += 1) { + const element = deletedElements[index]; + // delete files + await deleteAllObjectFiles(context, user, element); + } + // delete elements & delete operation + await elDeleteInstances([...deletedElements]); + await elDeleteInstances([deleteOperation]); + return id; }; diff --git a/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-resolvers.ts b/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-resolvers.ts index 70b65bf610f45..bc938011a9718 100644 --- a/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-resolvers.ts +++ b/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-resolvers.ts @@ -7,12 +7,8 @@ const deleteOperationResolvers: Resolvers = { deleteOperations: (_, args, context) => findAll(context, context.user, args), }, Mutation: { - deleteOperationRestore: (_, { id }, context) => { - return restoreDelete(context, context.user, id); - }, - deleteOperationConfirm: (_, { id }, context) => { - return completeDelete(context, context.user, id); - }, + deleteOperationRestore: (_, { id }, context) => restoreDelete(context, context.user, id), + deleteOperationConfirm: (_, { id }, context) => completeDelete(context, context.user, id), } }; diff --git a/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-types.ts b/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-types.ts index baa169e07c257..0ecf4b4d13109 100644 --- a/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-types.ts +++ b/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation-types.ts @@ -1,10 +1,14 @@ import type { StixObject, StixOpenctiExtensionSDO } from '../../types/stix-common'; import { STIX_EXT_OCTI } from '../../types/stix-extensions'; import type { BasicStoreEntity, StoreEntity } from '../../types/store'; -import type { DeletedElement } from './deleteOperation-domain'; export const ENTITY_TYPE_DELETE_OPERATION = 'DeleteOperation'; +export interface DeletedElement { + id: string + source_index: string +} + export interface BasicStoreEntityDeleteOperation extends BasicStoreEntity { timestamp: Date user_id: string diff --git a/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation.graphql b/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation.graphql index d4720dad0ee0c..8fbb7d7c9cdf8 100644 --- a/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation.graphql +++ b/opencti-platform/opencti-graphql/src/modules/deleteOperation/deleteOperation.graphql @@ -37,7 +37,7 @@ type DeleteOperationEdge { # Queries type Query { - deleteOperation(id: String!): DeleteOperation + deleteOperation(id: String!): DeleteOperation @auth(for: [KNOWLEDGE_KNUPDATE_KNDELETE]) deleteOperations( first: Int after: ID @@ -45,7 +45,7 @@ type Query { orderMode: OrderingMode filters: FilterGroup search: String - ): DeleteOperationConnection + ): DeleteOperationConnection @auth(for: [KNOWLEDGE_KNUPDATE_KNDELETE]) } # Mutations