Skip to content

Commit

Permalink
[backend] validation now returns a work
Browse files Browse the repository at this point in the history
  • Loading branch information
JeremyCloarec committed Nov 5, 2024
1 parent 4125922 commit d1e6fa9
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8710,7 +8710,7 @@ type Mutation {
supportPackageForceZip(input: SupportPackageForceZipInput!): SupportPackage
supportPackageDelete(id: ID!): ID
draftWorkspaceAdd(input: DraftWorkspaceAddInput!): DraftWorkspace
draftWorkspaceValidate(id: ID!): String
draftWorkspaceValidate(id: ID!): Work
draftWorkspaceDelete(id: ID!): ID
}

Expand Down
4 changes: 2 additions & 2 deletions opencti-platform/opencti-graphql/src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13296,7 +13296,7 @@ export type Mutation = {
deleteOperationRestore?: Maybe<Scalars['ID']['output']>;
draftWorkspaceAdd?: Maybe<DraftWorkspace>;
draftWorkspaceDelete?: Maybe<Scalars['ID']['output']>;
draftWorkspaceValidate?: Maybe<Scalars['String']['output']>;
draftWorkspaceValidate?: Maybe<Work>;
entitySettingsFieldPatch?: Maybe<Array<Maybe<EntitySetting>>>;
eventAdd?: Maybe<Event>;
eventContextClean?: Maybe<Event>;
Expand Down Expand Up @@ -36244,7 +36244,7 @@ export type MutationResolvers<ContextType = any, ParentType extends ResolversPar
deleteOperationRestore?: Resolver<Maybe<ResolversTypes['ID']>, ParentType, ContextType, RequireFields<MutationDeleteOperationRestoreArgs, 'id'>>;
draftWorkspaceAdd?: Resolver<Maybe<ResolversTypes['DraftWorkspace']>, ParentType, ContextType, RequireFields<MutationDraftWorkspaceAddArgs, 'input'>>;
draftWorkspaceDelete?: Resolver<Maybe<ResolversTypes['ID']>, ParentType, ContextType, RequireFields<MutationDraftWorkspaceDeleteArgs, 'id'>>;
draftWorkspaceValidate?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType, RequireFields<MutationDraftWorkspaceValidateArgs, 'id'>>;
draftWorkspaceValidate?: Resolver<Maybe<ResolversTypes['Work']>, ParentType, ContextType, RequireFields<MutationDraftWorkspaceValidateArgs, 'id'>>;
entitySettingsFieldPatch?: Resolver<Maybe<Array<Maybe<ResolversTypes['EntitySetting']>>>, ParentType, ContextType, RequireFields<MutationEntitySettingsFieldPatchArgs, 'ids' | 'input'>>;
eventAdd?: Resolver<Maybe<ResolversTypes['Event']>, ParentType, ContextType, RequireFields<MutationEventAddArgs, 'input'>>;
eventContextClean?: Resolver<Maybe<ResolversTypes['Event']>, ParentType, ContextType, RequireFields<MutationEventContextCleanArgs, 'id'>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,8 @@ export const deleteDraftWorkspace = async (context: AuthContext, user: AuthUser,
return id;
};

export const validateDraftWorkspace = async (context: AuthContext, user: AuthUser, draft_id: string) => {
const draftWorkspace = await findById(context, user, draft_id);
if (!draftWorkspace) {
throw FunctionalError(`Draft workspace ${draft_id} cannot be found`, draft_id);
}
export const buildDraftValidationBundle = async (context: AuthContext, user: AuthUser, draft_id: string) => {
const contextInDraft = { ...context, draft_context: draft_id };
const contextOutOfDraft = { ...context, draft_context: '' };
const includeDeleteOption = { includeDeletedElements: true };
// We start by listing all elements currently in this draft context
const draftEntities = await elList(contextInDraft, user, READ_INDEX_DRAFT_OBJECTS, includeDeleteOption);
Expand Down Expand Up @@ -135,17 +130,26 @@ export const validateDraftWorkspace = async (context: AuthContext, user: AuthUse
// };
// const updateStixEntities = await Promise.all(updatedEntities.map(async (e) => convertUpdatedEntityToStix(e)).filter((e) => e));

const stixBundle = buildStixBundle([...createStixEntities, ...deleteStixEntitiesModified, ...deletedRefsBundle, ...updateStixEntities]);
return buildStixBundle([...createStixEntities, ...deleteStixEntitiesModified, ...deletedRefsBundle, ...updateStixEntities]);
};

export const validateDraftWorkspace = async (context: AuthContext, user: AuthUser, draft_id: string) => {
const draftWorkspace = await findById(context, user, draft_id);
if (!draftWorkspace) {
throw FunctionalError(`Draft workspace ${draft_id} cannot be found`, draft_id);
}
const stixBundle = await buildDraftValidationBundle(context, user, draft_id);
const jsonBundle = JSON.stringify(stixBundle);
const content = Buffer.from(jsonBundle, 'utf-8').toString('base64');

const contextOutOfDraft = { ...context, draft_context: '' };
const work: any = await createWork(contextOutOfDraft, SYSTEM_USER, DRAFT_VALIDATION_CONNECTOR, `Draft validation ${draftWorkspace.name} (${draft_id})`, DRAFT_VALIDATION_CONNECTOR.internal_id, { receivedTime: now() });
if (stixBundle.objects.length === 1) {
// Only add explicit expectation if the worker will not split anything
await updateExpectationsNumber(contextOutOfDraft, context.user, work.id, stixBundle.objects.length);
}
await pushToWorkerForConnector(DRAFT_VALIDATION_CONNECTOR.id, { type: 'bundle', applicant_id: user.internal_id, content, update: true, work_id: work.id });
await deleteDraftWorkspace({ ...context, draft_context: '' }, user, draft_id);
await deleteDraftWorkspace(contextOutOfDraft, user, draft_id);

return jsonBundle;
return work;
};
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@ input DraftWorkspaceAddInput {

type Mutation {
draftWorkspaceAdd(input: DraftWorkspaceAddInput!): DraftWorkspace @auth(for: [KNOWLEDGE])
draftWorkspaceValidate(id: ID!): String @auth(for: [KNOWLEDGE])
draftWorkspaceValidate(id: ID!): Work @auth(for: [KNOWLEDGE_KNUPDATE_KNDELETE])
draftWorkspaceDelete(id: ID!): ID @auth(for: [KNOWLEDGE])
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { expect, it, describe } from 'vitest';
import gql from 'graphql-tag';
import { adminQuery, queryAsAdmin } from '../../utils/testQuery';
import { ADMIN_USER, adminQuery, queryAsAdmin, testContext } from '../../utils/testQuery';
import { MARKING_TLP_RED } from '../../../src/schema/identifier';
import { buildDraftValidationBundle } from '../../../src/modules/draftWorkspace/draftWorkspace-domain';
import { DRAFT_VALIDATION_CONNECTOR_ID } from '../../../src/modules/draftWorkspace/draftWorkspace-connector';

const CREATE_DRAFT_WORKSPACE_QUERY = gql`
mutation DraftWorkspaceAdd($input: DraftWorkspaceAddInput!) {
Expand All @@ -21,7 +23,13 @@ const DELETE_DRAFT_WORKSPACE_QUERY = gql`

const VALIDATE_DRAFT_WORKSPACE_QUERY = gql`
mutation DraftWorkspaceValidate($id: ID!) {
draftWorkspaceValidate(id: $id)
draftWorkspaceValidate(id: $id) {
id
name
connector {
id
}
}
}
`;

Expand Down Expand Up @@ -240,7 +248,9 @@ describe('Drafts workspace resolver testing', () => {
variables: { input: { name: draftName } },
});
expect(createdDraft.data?.draftWorkspaceAdd).toBeDefined();
addedDraftId = createdDraft.data?.draftWorkspaceAdd.id; await modifyAdminDraftContext(addedDraftId);
addedDraftId = createdDraft.data?.draftWorkspaceAdd.id;
addedDraftName = createdDraft.data?.draftWorkspaceAdd.name;
await modifyAdminDraftContext(addedDraftId);

// Create a report in the draft
const REPORT_TO_CREATE = {
Expand All @@ -254,15 +264,19 @@ describe('Drafts workspace resolver testing', () => {
const report = await adminQuery({ query: CREATE_REPORT_QUERY, variables: REPORT_TO_CREATE });
const reportStandardId = report.data.reportAdd.standard_id;

// Validate draft, verify bundle result and that draft was correctly deleted
// Verify that validation bundle contains report
const bundleData = await buildDraftValidationBundle(testContext, ADMIN_USER, addedDraftId);
expect(bundleData.objects.length).toEqual(1);
expect(bundleData.objects[0].id).toEqual(reportStandardId);

// Validate draft, verify work result and that draft was correctly deleted
const validateResult = await queryAsAdmin({
query: VALIDATE_DRAFT_WORKSPACE_QUERY,
variables: { id: addedDraftId },
});
expect(validateResult.data?.draftWorkspaceValidate).toBeDefined();
const bundleData = JSON.parse(validateResult.data?.draftWorkspaceValidate);
expect(bundleData.objects.length).toEqual(1);
expect(bundleData.objects[0].id).toEqual(reportStandardId);
expect(validateResult.data?.draftWorkspaceValidate.name).toEqual(`Draft validation ${addedDraftName} (${addedDraftId})`);
expect(validateResult.data?.draftWorkspaceValidate.connector.id).toEqual(DRAFT_VALIDATION_CONNECTOR_ID);
const { data } = await queryAsAdmin({
query: LIST_DRAFT_WORKSPACES_QUERY,
});
Expand Down

0 comments on commit d1e6fa9

Please sign in to comment.