Skip to content

Commit

Permalink
[backend] add background task handling in draft
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremyCloarec committed Nov 12, 2024
1 parent e2ed5d2 commit 19941e4
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -284,14 +284,14 @@ const authorizedMembersForTask = (user, scope) => {
};

export const createListTask = async (context, user, input) => {
if (getDraftContext(context, user)) throw new Error('Cannot create background task in draft');
const { actions, ids, scope } = input;
await checkActionValidity(context, user, input, scope, TASK_TYPE_LIST);
const task = createDefaultTask(user, input, TASK_TYPE_LIST, ids.length, scope);
const listTask = {
...task,
actions,
task_ids: ids,
draft_context: getDraftContext(context, user),
};
await publishUserAction({
user,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ export const createRuleTask = async (context, user, ruleDefinition, input) => {
};

export const createQueryTask = async (context, user, input) => {
if (getDraftContext(context, user)) throw new Error('Cannot create background task in draft');
const { actions, filters, excluded_ids = [], search = null, scope } = input;
await checkActionValidity(context, user, input, scope, TASK_TYPE_QUERY);
const queryData = await executeTaskQuery(context, user, filters, search, scope);
Expand All @@ -136,6 +135,7 @@ export const createQueryTask = async (context, user, input) => {
const queryTask = {
...task,
actions,
draft_context: getDraftContext(context, user),
task_filters: filters,
task_search: search,
task_excluded_ids: excluded_ids,
Expand Down
20 changes: 16 additions & 4 deletions opencti-platform/opencti-graphql/src/manager/taskManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import { deleteFile } from '../database/file-storage';
import { checkUserIsAdminOnDashboard } from '../modules/publicDashboard/publicDashboard-utils';
import { organizationDelete } from '../modules/organization/organization-domain';
import { ENTITY_TYPE_IDENTITY_ORGANIZATION } from '../modules/organization/organization-types';
import { getDraftContext } from '../utils/draftContext';

// Task manager responsible to execute long manual tasks
// Each API will start is task manager.
Expand Down Expand Up @@ -498,9 +499,11 @@ const executeProcessing = async (context, user, job, scope) => {
await executeDelete(context, user, element, scope);
}
if (type === ACTION_TYPE_COMPLETE_DELETE) {
if (getDraftContext(context, user)) throw FunctionalError('Cannot execute complete delete task in draft');
await executeCompleteDelete(context, user, element);
}
if (type === ACTION_TYPE_RESTORE) {
if (getDraftContext(context, user)) throw FunctionalError('Cannot execute restore task in draft');
await executeRestore(context, user, element);
}
if (type === ACTION_TYPE_ADD) {
Expand All @@ -522,24 +525,31 @@ const executeProcessing = async (context, user, job, scope) => {
await executeEnrichment(context, user, actionContext, element);
}
if (type === ACTION_TYPE_RULE_APPLY) {
if (getDraftContext(context, user)) throw FunctionalError('Cannot execute rule apply task in draft');
await executeRuleApply(context, user, actionContext, element);
}
if (type === ACTION_TYPE_RULE_CLEAR) {
if (getDraftContext(context, user)) throw FunctionalError('Cannot execute rule clear task in draft');
await executeRuleClean(context, user, actionContext, element);
}
if (type === ACTION_TYPE_RULE_ELEMENT_RESCAN) {
if (getDraftContext(context, user)) throw FunctionalError('Cannot execute rule element rescan task in draft');
await executeRuleElementRescan(context, user, actionContext, element);
}
if (type === ACTION_TYPE_SHARE) {
if (getDraftContext(context, user)) throw FunctionalError('Cannot execute share task in draft');
await executeShare(context, user, actionContext, element);
}
if (type === ACTION_TYPE_UNSHARE) {
if (getDraftContext(context, user)) throw FunctionalError('Cannot execute unshare task in draft');
await executeUnshare(context, user, actionContext, element);
}
if (type === ACTION_TYPE_SHARE_MULTIPLE) {
if (getDraftContext(context, user)) throw FunctionalError('Cannot execute share multiple task in draft');
await executeShareMultiple(context, user, actionContext, element);
}
if (type === ACTION_TYPE_UNSHARE_MULTIPLE) {
if (getDraftContext(context, user)) throw FunctionalError('Cannot execute unshare multiple task in draft');
await executeUnshareMultiple(context, user, actionContext, element);
}
} catch (err) {
Expand Down Expand Up @@ -578,6 +588,8 @@ export const taskHandler = async () => {
return;
}
// endregion
const draftID = task.draft_context ?? '';
const fullContext = { ...context, draft_context: draftID };
const startPatch = { last_execution_date: now() };
await updateTask(context, task.id, startPatch);
// Fetch the user responsible for the task
Expand All @@ -586,20 +598,20 @@ export const taskHandler = async () => {
logApp.debug(`[OPENCTI-MODULE][TASK-MANAGER] Executing job using userId:${rawUser.id}, for task ${task.internal_id}`);
let jobToExecute;
if (isQueryTask) {
jobToExecute = await computeQueryTaskElements(context, user, task);
jobToExecute = await computeQueryTaskElements(fullContext, user, task);
}
if (isListTask) {
jobToExecute = await computeListTaskElements(context, user, task);
jobToExecute = await computeListTaskElements(fullContext, user, task);
}
if (isRuleTask) {
jobToExecute = await computeRuleTaskElements(context, user, task);
jobToExecute = await computeRuleTaskElements(fullContext, user, task);
}
// Process the elements (empty = end of execution)
const processingElements = jobToExecute.elements;
logApp.debug(`[OPENCTI-MODULE][TASK-MANAGER] Found ${processingElements.length} element(s) to process.`);
if (processingElements.length > 0) {
lock.signal.throwIfAborted();
const errors = await executeProcessing(context, user, jobToExecute, task.scope);
const errors = await executeProcessing(fullContext, user, jobToExecute, task.scope);
await appendTaskErrors(task, errors);
}
// Update the task
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as R from 'ramda';
import { type AttributeDefinition, authorizedMembers, createdAt, creators, errors, id, updatedAt } from '../../schema/attribute-definition';
import { type AttributeDefinition, authorizedMembers, createdAt, creators, draftContext, errors, id, updatedAt } from '../../schema/attribute-definition';
import { schemaAttributesDefinition } from '../../schema/schema-attributes';
import {
ENTITY_TYPE_ACTIVITY,
Expand Down Expand Up @@ -312,7 +312,7 @@ const internalObjectsAttributes: { [k: string]: Array<AttributeDefinition> } = {
{ name: 'otp_qr', label: 'OTP QR', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: false },
{ name: 'otp_activated', label: '2FA state', type: 'boolean', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: false },
{ name: 'default_dashboard', label: 'Default dashboard', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: true },
{ name: 'draft_context', label: 'Current draft context', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: true, featureFlag: 'DRAFT_WORKSPACE' },
draftContext,
{ name: 'default_time_field', label: 'Default time field', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: true },
{ name: 'account_status', label: 'Account status', type: 'string', format: 'short', mandatoryType: 'external', editDefault: true, multiple: false, upsert: false, isFilterable: true },
{ name: 'account_lock_after_date', label: 'User account expiration date', type: 'date', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: true },
Expand Down Expand Up @@ -496,6 +496,7 @@ const internalObjectsAttributes: { [k: string]: Array<AttributeDefinition> } = {
{ name: 'enable', label: 'Is enabled', type: 'boolean', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: true },
{ name: 'completed', label: 'Completed', type: 'boolean', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: true },
{ name: 'initiator_id', label: 'Initiator', type: 'string', format: 'short', mandatoryType: 'internal', editDefault: false, multiple: false, upsert: false, isFilterable: false },
draftContext,
{ name: 'task_filters', label: 'Task filters', type: 'string', format: 'json', mandatoryType: 'external', editDefault: false, multiple: false, upsert: false, isFilterable: false },
{ name: 'task_search', label: 'Search', type: 'string', format: 'short', mandatoryType: 'external', editDefault: false, multiple: false, upsert: false, isFilterable: true },
{ name: 'task_position', label: 'Position', type: 'string', format: 'short', mandatoryType: 'no', editDefault: false, multiple: false, upsert: false, isFilterable: true },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,20 @@ export const draftIds: AttributeDefinition = {
featureFlag: 'DRAFT_WORKSPACE'
};

export const draftContext: AttributeDefinition = {
name: 'draft_context',
label: 'Current draft context',
type: 'string',
format: 'short',
update: false,
mandatoryType: 'no',
multiple: false,
editDefault: false,
upsert: false,
isFilterable: false,
featureFlag: 'DRAFT_WORKSPACE'
};

export const draftChange: AttributeDefinition = {
name: 'draft_change',
label: 'Draft change',
Expand Down

0 comments on commit 19941e4

Please sign in to comment.