Skip to content

Commit

Permalink
[backend] WIP: test (#8333)
Browse files Browse the repository at this point in the history
  • Loading branch information
marieflorescontact committed Sep 30, 2024
1 parent b023c60 commit 13a5b8e
Show file tree
Hide file tree
Showing 8 changed files with 448 additions and 11 deletions.
20 changes: 16 additions & 4 deletions opencti-platform/opencti-graphql/src/database/stix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ import {
RELATION_USES,
RELATION_VARIANT_OF
} from '../schema/stixCoreRelationship';
import { isStixRefRelationship } from '../schema/stixRefRelationship';
import { isStixRefRelationship, RELATION_GRANTED_TO } from '../schema/stixRefRelationship';
import { ABSTRACT_STIX_CYBER_OBSERVABLE, ENTITY_TYPE_THREAT_ACTOR } from '../schema/general';
import { ENTITY_TYPE_EVENT } from '../modules/event/event-types';
import { ENTITY_TYPE_NARRATIVE } from '../modules/narrative/narrative-types';
Expand All @@ -89,6 +89,7 @@ import { FunctionalError, UnsupportedError } from '../config/errors';
import { ENTITY_TYPE_THREAT_ACTOR_INDIVIDUAL } from '../modules/threatActorIndividual/threatActorIndividual-types';
import { ENTITY_TYPE_IDENTITY_ORGANIZATION } from '../modules/organization/organization-types';
import { ENTITY_TYPE_INDICATOR } from '../modules/indicator/indicator-types';
import { logApp } from '../config/conf';

const MAX_TRANSIENT_STIX_IDS = 200;
export const STIX_SPEC_VERSION = '2.1';
Expand Down Expand Up @@ -267,7 +268,8 @@ export const stixCoreRelationshipsMapping: RelationshipMappings = {
{ name: RELATION_PART_OF, type: REL_NEW }
],
[`${ENTITY_TYPE_IDENTITY_INDIVIDUAL}_${ENTITY_TYPE_IDENTITY_ORGANIZATION}`]: [
{ name: RELATION_PART_OF, type: REL_NEW }
{ name: RELATION_PART_OF, type: REL_NEW },
{ name: RELATION_GRANTED_TO, type: REL_BUILT_IN }
],
[`${ENTITY_TYPE_IDENTITY_INDIVIDUAL}_${ENTITY_TYPE_LOCATION_POSITION}`]: [
{ name: RELATION_LOCATED_AT, type: REL_BUILT_IN }
Expand Down Expand Up @@ -307,10 +309,14 @@ export const stixCoreRelationshipsMapping: RelationshipMappings = {
[`${ENTITY_TYPE_IDENTITY_SECTOR}_${ENTITY_TYPE_LOCATION_REGION}`]: [
{ name: RELATION_LOCATED_AT, type: REL_BUILT_IN }
],
[`${ENTITY_TYPE_IDENTITY_SECTOR}_${ENTITY_TYPE_IDENTITY_ORGANIZATION}`]: [
{ name: RELATION_GRANTED_TO, type: REL_BUILT_IN }
],
// endregion
// region SYSTEM
[`${ENTITY_TYPE_IDENTITY_SYSTEM}_${ENTITY_TYPE_IDENTITY_ORGANIZATION}`]: [
{ name: RELATION_BELONGS_TO, type: REL_EXTENDED }
{ name: RELATION_BELONGS_TO, type: REL_EXTENDED },
{ name: RELATION_GRANTED_TO, type: REL_BUILT_IN }
],
[`${ENTITY_TYPE_IDENTITY_SYSTEM}_${ENTITY_TYPE_LOCATION_POSITION}`]: [
{ name: RELATION_LOCATED_AT, type: REL_BUILT_IN }
Expand Down Expand Up @@ -1171,14 +1177,20 @@ export const isRelationBuiltin = (instance: StoreRelation): boolean => {
};

export const checkRelationshipRef = (fromType: string, toType: string, relationshipType: string) => {
const relationRefs = schemaRelationsRefDefinition.getRelationsRef(fromType).filter((rel) => rel.databaseName === relationshipType);
logApp.info(`ANGIE checkRelationshipRef - from:${fromType}, to:${toType}, relationshipType:${relationshipType}`);
const relationRefs = schemaRelationsRefDefinition.getRelationsRef(fromType).filter((rel) => {
logApp.info(`ANGIE checkRelationshipRef - ${rel.databaseName} ?? ${relationshipType}`);
return rel.databaseName === relationshipType;
});
logApp.info(`ANGIE checkRelationshipRef - relationRefs.length:${relationRefs.length}`);
if (relationRefs.length === 0) {
throw FunctionalError('The relationship is not allowed', { type: relationshipType, from: fromType, to: toType });
}
if (relationRefs.length > 1) {
throw FunctionalError('Invalid relationship schema', { type: relationshipType, from: fromType, to: toType, data: relationRefs });
}

logApp.info(`ANGIE relationRefs[0]=${relationRefs[0].toTypes}`);
if (!relationRefs[0].isRefExistingForTypes(fromType, toType)) {
throw FunctionalError('The relationship is not allowed', { type: relationshipType, from: fromType, to: toType });
}
Expand Down
3 changes: 2 additions & 1 deletion opencti-platform/opencti-graphql/src/manager/taskManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,8 @@ const executeRuleElementRescan = async (context, user, actionContext, element) =
}
}
};
const executeShare = async (context, user, actionContext, element) => {
export const executeShare = async (context, user, actionContext, element) => {
logApp.info('ANGIE executeShare', { actionContext, element });
const { values } = actionContext;
for (let indexCreate = 0; indexCreate < values.length; indexCreate += 1) {
const target = values[indexCreate];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ schemaRelationsRefDefinition.registerRelationsRef(ENTITY_TYPE_CONTAINER_GROUPING
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_TYPE_VULNERABILITY, [objectOrganization]);

schemaRelationsRefDefinition.registerRelationsRef(ENTITY_TYPE_IDENTITY_SYSTEM, [objectOrganization]);
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_TYPE_IDENTITY_SECTOR, []);
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_TYPE_IDENTITY_SECTOR, [objectOrganization]);
schemaRelationsRefDefinition.registerRelationsRef(ENTITY_TYPE_IDENTITY_INDIVIDUAL, [objectOrganization]);

schemaRelationsRefDefinition.registerRelationsRef(ENTITY_TYPE_LOCATION_REGION, []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,6 @@ export const STIX_ORGANIZATIONS_UNRESTRICTED = [
ABSTRACT_STIX_REF_RELATIONSHIP,
ENTITY_TYPE_IDENTITY_ORGANIZATION,
ENTITY_TYPE_IDENTITY_SECTOR,
ENTITY_TYPE_IDENTITY_SYSTEM,
ENTITY_TYPE_IDENTITY_INDIVIDUAL,
ENTITY_TYPE_LOCATION,
ENTITY_TYPE_WORK, // Work is defined as an history object
ENTITY_TYPE_TAXII_COLLECTION, // TODO TaxiiCollection must be migrate to add according parent types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import {
ENTITY_WINDOWS_REGISTRY_VALUE_TYPE
} from './stixCyberObservable';
import { ATTRIBUTE_SAMPLE } from '../modules/malwareAnalysis/malwareAnalysis-types';
import { logApp } from '../config/conf';

export const ABSTRACT_STIX_NESTED_REF_RELATIONSHIP = 'stix-nested-ref-relationship'; // Only for front usage

Expand Down Expand Up @@ -727,13 +728,14 @@ export const objectOrganization: RefAttribute = {
multiple: true,
upsert: true,
isRefExistingForTypes(this, fromType, toType) {
return !(fromType === ENTITY_TYPE_EVENT || isStixDomainObjectIdentity(fromType)
logApp.info(`ANGIE isRefExistingForTypes this.type:${this.type}, fromType:${fromType}, toType:${toType} `);
return !(fromType === ENTITY_TYPE_EVENT /* || isStixDomainObjectIdentity(fromType) */
|| isStixDomainObjectLocation(fromType))
&& this.toTypes.includes(toType);
},
datable: false,
isFilterable: true,
toTypes: [ENTITY_TYPE_IDENTITY_ORGANIZATION],
toTypes: [ENTITY_TYPE_IDENTITY_ORGANIZATION], // ANGIE
};

export const objectAssignee: RefAttribute = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
import { describe, expect, it } from 'vitest';
import gql from 'graphql-tag';
import {
ADMIN_API_TOKEN,
ADMIN_USER,
adminQuery,
API_URI,
FIVE_MINUTES,
getOrganizationIdByName,
PLATFORM_ORGANIZATION,
PYTHON_PATH,
TEST_ORGANIZATION,
testContext,
USER_EDITOR,
} from '../../utils/testQuery';
import { adminQueryWithSuccess, queryAsUserWithSuccess } from '../../utils/testQueryHelper';
import { findById } from '../../../src/domain/report';
import { execChildPython } from '../../../src/python/pythonBridge';
import { wait } from '../../../src/database/utils';

const READ_QUERY = gql`
query caseIncident($id: String!) {
caseIncident(id: $id) {
id
standard_id
name
authorized_members {
id
access_right
}
currentUserAccessRight
}
}
`;

const DELETE_QUERY = gql`
mutation CaseIncidentDelete($id: ID!) {
caseIncidentDelete(id: $id)
}
`;

const PLATFORM_ORGANIZATION_QUERY = gql`
mutation PoliciesFieldPatchMutation($id: ID!, $input: [EditInput]!) {
settingsEdit(id: $id) {
fieldPatch(input: $input) {
platform_organization {
id
name
}
enterprise_edition
id
}
}
}
`;

const ORGANIZATION_SHARING_QUERY = gql`
mutation StixCoreObjectSharingGroupAddMutation(
$id: ID!
$organizationId: ID!
) {
stixCoreObjectEdit(id: $id) {
restrictionOrganizationAdd(organizationId: $organizationId) {
id
objectOrganization {
id
name
}
}
}
}
`;

const importOpts: string[] = [API_URI, ADMIN_API_TOKEN, './tests/data/DATA-TEST-STIX2_v2.json'];

describe('Database provision', () => {
it('Should import creation succeed', async () => {
// Inject data
const execution = await execChildPython(testContext, ADMIN_USER, PYTHON_PATH, 'local_importer.py', importOpts);
expect(execution).not.toBeNull();
expect(execution.status).toEqual('success');
}, FIVE_MINUTES);
// Python lib is fixed but we need to wait for a new release
it('Should import update succeed', async () => {
const execution = await execChildPython(testContext, ADMIN_USER, PYTHON_PATH, 'local_importer.py', importOpts);
expect(execution).not.toBeNull();
expect(execution.status).toEqual('success');
}, FIVE_MINUTES);
});

describe('Organization sharing standard behavior for container', () => {
let reportInternalId: string;
let organizationId: string;
let settingsInternalId: string;
let platformOrganizationId: string;
it('should load Report', async () => {
const report = await findById(testContext, ADMIN_USER, 'report--57162a65-2a58-560b-9a65-47c3f040f3d4'); // Report is in DATA-TEST-STIX_v2.json
reportInternalId = report.internal_id;
});
it('should plateform organization sharing and EE activated', async () => { // TODO extract set/unset EE and orga platfor in testQueryHelpers
// Get organization id
platformOrganizationId = await getOrganizationIdByName(PLATFORM_ORGANIZATION.name);

// Get settings ID
const SETTINGS_READ_QUERY = gql`
query settings {
settings {
id
platform_organization {
id
name
}
}
}
`;
const queryResult = await adminQuery({ query: SETTINGS_READ_QUERY, variables: {} });
settingsInternalId = queryResult.data?.settings?.id;

// Set plateform organization
const platformOrganization = await adminQueryWithSuccess({
query: PLATFORM_ORGANIZATION_QUERY,
variables: {
id: settingsInternalId,
input: [
{ key: 'platform_organization', value: platformOrganizationId },
{ key: 'enterprise_edition', value: new Date().getTime() },
]
}
});
expect(platformOrganization?.data?.settingsEdit.fieldPatch.platform_organization).not.toBeUndefined();
expect(platformOrganization?.data?.settingsEdit.fieldPatch.enterprise_edition).not.toBeUndefined();
expect(platformOrganization?.data?.settingsEdit.fieldPatch.platform_organization.name).toEqual(PLATFORM_ORGANIZATION.name);
});
it('should share Report with Organization', async () => {
// Get organization id
organizationId = await getOrganizationIdByName(TEST_ORGANIZATION.name);
const organizationSharingQueryResult = await adminQueryWithSuccess({
query: ORGANIZATION_SHARING_QUERY,
variables: { id: reportInternalId, organizationId }
});
expect(organizationSharingQueryResult?.data?.stixCoreObjectEdit.restrictionOrganizationAdd).not.toBeNull();
expect(organizationSharingQueryResult?.data?.stixCoreObjectEdit.restrictionOrganizationAdd.objectOrganization[0].name).toEqual(TEST_ORGANIZATION.name);

// Wait for background task magic to happens
await wait(5000);
});
it('should Editor user access all objects', async () => {
const REPORT_STIX_DOMAIN_ENTITIES = gql`
query report($id: String!) {
report(id: $id) {
id
standard_id
objects(first: 30) {
edges {
node {
... on BasicObject {
id
standard_id
}
... on BasicRelationship {
id
standard_id
}
}
}
}
}
}
`;
const queryResult = await queryAsUserWithSuccess(USER_EDITOR.client, {
query: REPORT_STIX_DOMAIN_ENTITIES,
variables: { id: reportInternalId },
});
expect(queryResult.data.report.objects.edges.length).toEqual(10);
});
it.skip('should delete Report', async () => {
// Delete the case
await adminQuery({
query: DELETE_QUERY,
variables: { id: reportInternalId },
});
// Verify is no longer found
const queryResult = await adminQueryWithSuccess({ query: READ_QUERY, variables: { id: reportInternalId } });
expect(queryResult?.data?.caseIncident).toBeNull();
});
it.skip('should plateform organization sharing and EE deactivated', async () => {
// Remove plateform organization
const platformOrganization = await adminQueryWithSuccess({
query: PLATFORM_ORGANIZATION_QUERY,
variables: {
id: settingsInternalId,
input: [
{ key: 'platform_organization', value: [] },
{ key: 'enterprise_edition', value: [] },
]
}
});
expect(platformOrganization?.data?.settingsEdit.fieldPatch.platform_organization).toBeNull();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
import type { BasicStoreEntity } from '../../../src/types/store';
import { addIndicator, promoteIndicatorToObservables } from '../../../src/modules/indicator/indicator-domain';
import { addStixCyberObservable, promoteObservableToIndicator, stixCyberObservableDelete } from '../../../src/domain/stixCyberObservable';
import { executePromoteIndicatorToObservables, executePromoteObservableToIndicator, executeReplace } from '../../../src/manager/taskManager';
import { executePromoteIndicatorToObservables, executePromoteObservableToIndicator, executeReplace, executeShare } from '../../../src/manager/taskManager';
import type { AuthContext } from '../../../src/types/user';
import { ADMIN_USER, TEST_ORGANIZATION, testContext } from '../../utils/testQuery';
import { MARKING_TLP_AMBER, MARKING_TLP_CLEAR } from '../../../src/schema/identifier';
Expand Down Expand Up @@ -362,4 +362,15 @@ describe('TaskManager executePromote tests', () => {
createdObservableId = createdObservables.map(({ id }) => id);
});
});

/* describe('TaskManager execute SHARE ', () => {
it('Enable EE and platform Organisation', async () => {
});
it('SHARE a report', async () => {
await executeShare(testContext, ADMIN_USER,);
});
});
*/
});
Loading

0 comments on commit 13a5b8e

Please sign in to comment.