Projects STRLCPY opencti Commits 2b214d14
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-front/src/schema/relay.schema.graphql
    skipped 3541 lines
    3542 3542   
    3543 3543  input IndicatorAddInput {
    3544 3544   stix_id: StixId
    3545  - x_opencti_stix_ids: [StixId]
     3545 + x_opencti_stix_ids: [StixId!]
    3546 3546   pattern_type: String!
    3547 3547   pattern_version: String
    3548 3548   pattern: String!
    3549 3549   name: name_String_NotNull_minLength_2!
    3550 3550   description: String
    3551  - indicator_types: [String]
     3551 + indicator_types: [String!]
    3552 3552   valid_from: DateTime
    3553 3553   valid_until: DateTime
    3554 3554   confidence: Int
    skipped 2 lines
    3557 3557   x_opencti_score: Int
    3558 3558   x_opencti_detection: Boolean
    3559 3559   x_opencti_main_observable_type: String
    3560  - x_mitre_platforms: [String]
    3561  - killChainPhases: [String]
     3560 + x_mitre_platforms: [String!]
     3561 + killChainPhases: [String!]
    3562 3562   createdBy: String
    3563  - objectMarking: [String]
    3564  - objectLabel: [String]
    3565  - objectOrganization: [String]
    3566  - externalReferences: [String]
     3563 + objectMarking: [String!]
     3564 + objectLabel: [String!]
     3565 + objectOrganization: [String!]
     3566 + externalReferences: [String!]
    3567 3567   created: DateTime
    3568 3568   modified: DateTime
    3569 3569   clientMutationId: String
    skipped 4954 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/config/schema/opencti.graphql
    skipped 3949 lines
    3950 3950  }
    3951 3951  input IndicatorAddInput {
    3952 3952   stix_id: StixId
    3953  - x_opencti_stix_ids: [StixId]
     3953 + x_opencti_stix_ids: [StixId!]
    3954 3954   pattern_type: String!
    3955 3955   pattern_version: String
    3956 3956   pattern: String!
    3957 3957   name: String! @constraint(minLength: 2)
    3958 3958   description: String
    3959  - indicator_types: [String]
     3959 + indicator_types: [String!]
    3960 3960   valid_from: DateTime
    3961 3961   valid_until: DateTime
    3962 3962   confidence: Int
    skipped 2 lines
    3965 3965   x_opencti_score: Int
    3966 3966   x_opencti_detection: Boolean
    3967 3967   x_opencti_main_observable_type: String
    3968  - x_mitre_platforms: [String]
    3969  - killChainPhases: [String]
     3968 + x_mitre_platforms: [String!]
     3969 + killChainPhases: [String!]
    3970 3970   createdBy: String
    3971  - objectMarking: [String]
    3972  - objectLabel: [String]
    3973  - objectOrganization: [String]
    3974  - externalReferences: [String]
     3971 + objectMarking: [String!]
     3972 + objectLabel: [String!]
     3973 + objectOrganization: [String!]
     3974 + externalReferences: [String!]
    3975 3975   created: DateTime
    3976 3976   modified: DateTime
    3977 3977   clientMutationId: String
    skipped 7188 lines
  • ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/domain/indicator.js
    1  -import moment from 'moment';
    2 1  import * as R from 'ramda';
    3 2  import { Promise } from 'bluebird';
    4 3  import {
     4 + batchListThroughGetTo,
    5 5   createEntity,
    6 6   createRelation,
    7  - batchListThroughGetTo,
     7 + distributionEntities,
    8 8   storeLoadById,
     9 + storeLoadByIdWithRefs,
    9 10   timeSeriesEntities,
    10  - distributionEntities, storeLoadByIdWithRefs,
    11 11  } from '../database/middleware';
    12 12  import { listEntities } from '../database/middleware-loader';
    13 13  import { BUS_TOPICS } from '../config/conf';
    14 14  import { notify } from '../database/redis';
    15  -import { findById as findMarkingDefinitionById } from './markingDefinition';
    16  -import { findById as findKillChainPhaseById } from './killChainPhase';
    17 15  import { checkIndicatorSyntax } from '../python/pythonBridge';
    18 16  import { DatabaseError, FunctionalError } from '../config/errors';
    19 17  import { ENTITY_TYPE_INDICATOR } from '../schema/stixDomainObject';
    skipped 1 lines
    21 19  import { RELATION_BASED_ON, RELATION_INDICATES } from '../schema/stixCoreRelationship';
    22 20  import {
    23 21   ABSTRACT_STIX_CYBER_OBSERVABLE,
    24  - ABSTRACT_STIX_DOMAIN_OBJECT, INPUT_CREATED_BY, INPUT_EXTERNAL_REFS,
     22 + ABSTRACT_STIX_DOMAIN_OBJECT,
     23 + INPUT_CREATED_BY,
     24 + INPUT_EXTERNAL_REFS,
    25 25   INPUT_LABELS,
    26 26   INPUT_MARKINGS
    27 27  } from '../schema/general';
    28 28  import { elCount } from '../database/engine';
    29 29  import { isEmptyField, READ_INDEX_STIX_DOMAIN_OBJECTS } from '../database/utils';
    30 30  import { extractObservablesFromIndicatorPattern } from '../utils/syntax';
    31  - 
    32  -const OpenCTITimeToLive = {
    33  - // Formatted as "[Marking-Definition]-[KillChainPhaseIsDelivery]"
    34  - File: {
    35  - 'TLP:CLEAR-no': 365,
    36  - 'TLP:CLEAR-yes': 365,
    37  - 'TLP:GREEN-no': 365,
    38  - 'TLP:GREEN-yes': 365,
    39  - 'TLP:AMBER-yes': 365,
    40  - 'TLP:AMBER-no': 365,
    41  - 'TLP:AMBER+STRICT-yes': 365,
    42  - 'TLP:AMBER+STRICT-no': 365,
    43  - 'TLP:RED-yes': 365,
    44  - 'TLP:RED-no': 365,
    45  - },
    46  - 'IPv4-Addr': {
    47  - 'TLP:CLEAR-no': 30,
    48  - 'TLP:CLEAR-yes': 7,
    49  - 'TLP:GREEN-no': 30,
    50  - 'TLP:GREEN-yes': 7,
    51  - 'TLP:AMBER-yes': 15,
    52  - 'TLP:AMBER-no': 60,
    53  - 'TLP:AMBER+STRICT-yes': 15,
    54  - 'TLP:AMBER+STRICT-no': 60,
    55  - 'TLP:RED-yes': 120,
    56  - 'TLP:RED-no': 120,
    57  - },
    58  - Url: {
    59  - 'TLP:CLEAR-no': 60,
    60  - 'TLP:CLEAR-yes': 15,
    61  - 'TLP:GREEN-no': 60,
    62  - 'TLP:GREEN-yes': 15,
    63  - 'TLP:AMBER-yes': 30,
    64  - 'TLP:AMBER-no': 180,
    65  - 'TLP:AMBER+STRICT-yes': 30,
    66  - 'TLP:AMBER+STRICT-no': 180,
    67  - 'TLP:RED-yes': 180,
    68  - 'TLP:RED-no': 180,
    69  - },
    70  - default: {
    71  - 'TLP:CLEAR-no': 365,
    72  - 'TLP:CLEAR-yes': 365,
    73  - 'TLP:GREEN-no': 365,
    74  - 'TLP:GREEN-yes': 365,
    75  - 'TLP:AMBER-yes': 365,
    76  - 'TLP:AMBER-no': 365,
    77  - 'TLP:AMBER+STRICT-yes': 365,
    78  - 'TLP:AMBER+STRICT-no': 365,
    79  - 'TLP:RED-yes': 365,
    80  - 'TLP:RED-no': 365,
    81  - },
    82  -};
    83  - 
    84  -const computeValidUntil = async (user, indicator) => {
    85  - let validFrom = moment().utc();
    86  - if (indicator.valid_from) {
    87  - validFrom = moment(indicator.valid_from).utc();
    88  - }
    89  - // get the highest marking definition
    90  - let markingDefinition = 'TLP:CLEAR';
    91  - if (indicator.objectMarking && indicator.objectMarking.length > 0) {
    92  - const markingDefinitions = await Promise.all(
    93  - indicator.objectMarking.map((markingDefinitionId) => {
    94  - return findMarkingDefinitionById(user, markingDefinitionId);
    95  - })
    96  - );
    97  - markingDefinition = R.pipe(
    98  - R.sortWith([R.descend(R.prop('level'))]),
    99  - R.head,
    100  - R.prop('definition')
    101  - )(markingDefinitions);
    102  - }
    103  - // check if kill chain phase is delivery
    104  - let isKillChainPhaseDelivery = 'no';
    105  - if (indicator.killChainPhases && indicator.killChainPhases.length > 0) {
    106  - const killChainPhases = await Promise.all(
    107  - indicator.killChainPhases.map((killChainPhaseId) => {
    108  - return findKillChainPhaseById(user, killChainPhaseId);
    109  - })
    110  - );
    111  - const killChainPhasesNames = R.map((n) => n.phase_name, killChainPhases);
    112  - isKillChainPhaseDelivery = R.includes('initial-access', killChainPhasesNames) || R.includes('execution', killChainPhasesNames)
    113  - ? 'yes'
    114  - : 'no';
    115  - }
    116  - // compute with delivery and marking definition
    117  - const ttlPattern = `${markingDefinition}-${isKillChainPhaseDelivery}`;
    118  - let ttl = OpenCTITimeToLive.default[ttlPattern];
    119  - const mainObservableType = indicator.x_opencti_main_observable_type && indicator.x_opencti_main_observable_type.includes('File')
    120  - ? 'File'
    121  - : indicator.x_opencti_main_observable_type;
    122  - if (mainObservableType && R.has(indicator.x_opencti_main_observable_type, OpenCTITimeToLive)) {
    123  - ttl = OpenCTITimeToLive[indicator.x_opencti_main_observable_type][ttlPattern];
    124  - }
    125  - const validUntil = validFrom.add(ttl, 'days');
    126  - return validUntil.toDate();
    127  -};
     31 +import { computeValidPeriod } from '../utils/indicator-utils';
    128 32   
    129 33  export const findById = (context, user, indicatorId) => {
    130 34   return storeLoadById(context, user, indicatorId, ENTITY_TYPE_INDICATOR);
    skipped 53 lines
    184 88   if (check === false) {
    185 89   throw FunctionalError(`Indicator of type ${indicator.pattern_type} is not correctly formatted.`);
    186 90   }
    187  - const validUntil = isEmptyField(indicator.valid_until) ? await computeValidUntil(user, indicator) : indicator.valid_until;
     91 + const { validFrom, validUntil } = await computeValidPeriod(context, user, indicator);
    188 92   const indicatorToCreate = R.pipe(
    189 93   R.dissoc('createObservables'),
    190 94   R.dissoc('basedOn'),
    191 95   R.assoc('x_opencti_main_observable_type', observableType),
    192  - R.assoc('x_opencti_score', R.isNil(indicator.x_opencti_score) ? 50 : indicator.x_opencti_score),
    193  - R.assoc('x_opencti_detection', R.isNil(indicator.x_opencti_detection) ? false : indicator.x_opencti_detection),
    194  - R.assoc('valid_from', R.isNil(indicator.valid_from) ? validUntil : indicator.valid_from),
     96 + R.assoc('x_opencti_score', indicator.x_opencti_score ?? 50),
     97 + R.assoc('x_opencti_detection', indicator.x_opencti_detection ?? false),
     98 + R.assoc('valid_from', validFrom),
    195 99   R.assoc('valid_until', validUntil)
    196 100   )(indicator);
    197 101   // create the linked observables
    skipped 81 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/domain/stix.js
    skipped 42 lines
    43 43   
    44 44  export const askListExport = async (context, user, format, entityType, listParams, type = 'simple', maxMarkingId = null) => {
    45 45   const connectors = await connectorsForExport(context, user, format, true);
    46  - const markingLevel = maxMarkingId ? await findMarkingDefinitionById(user, maxMarkingId) : null;
     46 + const markingLevel = maxMarkingId ? await findMarkingDefinitionById(context, user, maxMarkingId) : null;
    47 47   const toFileName = (connector) => {
    48 48   const fileNamePart = `${entityType}_${type}.${mime.extension(format)}`;
    49 49   return `${now()}_${markingLevel?.definition || 'TLP:ALL'}_(${connector.name})_${fileNamePart}`;
    skipped 31 lines
    81 81   
    82 82  export const askEntityExport = async (context, user, format, entity, type = 'simple', maxMarkingId = null) => {
    83 83   const connectors = await connectorsForExport(context, user, format, true);
    84  - const markingLevel = maxMarkingId ? await findMarkingDefinitionById(user, maxMarkingId) : null;
     84 + const markingLevel = maxMarkingId ? await findMarkingDefinitionById(context, user, maxMarkingId) : null;
    85 85   const toFileName = (connector) => {
    86 86   const fileNamePart = `${entity.entity_type}-${entity.name || observableValue(entity)}_${type}.${mime.extension(
    87 87   format
    skipped 99 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/generated/graphql.ts
    skipped 5452 lines
    5453 5453   created?: InputMaybe<Scalars['DateTime']>;
    5454 5454   createdBy?: InputMaybe<Scalars['String']>;
    5455 5455   description?: InputMaybe<Scalars['String']>;
    5456  - externalReferences?: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
    5457  - indicator_types?: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
    5458  - killChainPhases?: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
     5456 + externalReferences?: InputMaybe<Array<Scalars['String']>>;
     5457 + indicator_types?: InputMaybe<Array<Scalars['String']>>;
     5458 + killChainPhases?: InputMaybe<Array<Scalars['String']>>;
    5459 5459   lang?: InputMaybe<Scalars['String']>;
    5460 5460   modified?: InputMaybe<Scalars['DateTime']>;
    5461 5461   name: Scalars['String'];
    5462  - objectLabel?: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
    5463  - objectMarking?: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
    5464  - objectOrganization?: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
     5462 + objectLabel?: InputMaybe<Array<Scalars['String']>>;
     5463 + objectMarking?: InputMaybe<Array<Scalars['String']>>;
     5464 + objectOrganization?: InputMaybe<Array<Scalars['String']>>;
    5465 5465   pattern: Scalars['String'];
    5466 5466   pattern_type: Scalars['String'];
    5467 5467   pattern_version?: InputMaybe<Scalars['String']>;
    skipped 2 lines
    5470 5470   update?: InputMaybe<Scalars['Boolean']>;
    5471 5471   valid_from?: InputMaybe<Scalars['DateTime']>;
    5472 5472   valid_until?: InputMaybe<Scalars['DateTime']>;
    5473  - x_mitre_platforms?: InputMaybe<Array<InputMaybe<Scalars['String']>>>;
     5473 + x_mitre_platforms?: InputMaybe<Array<Scalars['String']>>;
    5474 5474   x_opencti_detection?: InputMaybe<Scalars['Boolean']>;
    5475 5475   x_opencti_main_observable_type?: InputMaybe<Scalars['String']>;
    5476 5476   x_opencti_score?: InputMaybe<Scalars['Int']>;
    5477  - x_opencti_stix_ids?: InputMaybe<Array<InputMaybe<Scalars['StixId']>>>;
     5477 + x_opencti_stix_ids?: InputMaybe<Array<Scalars['StixId']>>;
    5478 5478  };
    5479 5479   
    5480 5480  export type IndicatorConnection = {
    skipped 20747 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/schema/identifier.js
    skipped 64 lines
    65 65   return (name || '').toLowerCase().trim();
    66 66  };
    67 67   
    68  -export const MARKING_TLP_CLEAR = '613f2e26-407d-48c7-9eca-b8e91df99dc9';
    69  -export const MARKING_TLP_GREEN = '34098fce-860f-48ae-8e50-ebd3cc5e41da';
    70  -export const MARKING_TLP_AMBER = 'f88d31f6-486f-44da-b317-01333bde0b82';
    71  -export const MARKING_TLP_AMBER_STRICT = '826578e1-40ad-459f-bc73-ede076f81f37';
    72  -export const MARKING_TLP_RED = '5e57c739-391a-4eb3-b6be-7d15ca92d5ed';
     68 +const MARKING_TLP_CLEAR_ID = '613f2e26-407d-48c7-9eca-b8e91df99dc9';
     69 +export const MARKING_TLP_CLEAR = `marking-definition--${MARKING_TLP_CLEAR_ID}`;
     70 +const MARKING_TLP_GREEN_ID = '34098fce-860f-48ae-8e50-ebd3cc5e41da';
     71 +export const MARKING_TLP_GREEN = `marking-definition--${MARKING_TLP_GREEN_ID}`;
     72 +const MARKING_TLP_AMBER_ID = 'f88d31f6-486f-44da-b317-01333bde0b82';
     73 +export const MARKING_TLP_AMBER = `marking-definition--${MARKING_TLP_AMBER_ID}`;
     74 +const MARKING_TLP_AMBER_STRICT_ID = '826578e1-40ad-459f-bc73-ede076f81f37';
     75 +export const MARKING_TLP_AMBER_STRICT = `marking-definition--${MARKING_TLP_AMBER_STRICT_ID}`;
     76 +const MARKING_TLP_RED_ID = '5e57c739-391a-4eb3-b6be-7d15ca92d5ed';
     77 +export const MARKING_TLP_RED = `marking-definition--${MARKING_TLP_RED_ID}`;
     78 +export const STATIC_MARKING_IDS = [
     79 + MARKING_TLP_CLEAR,
     80 + MARKING_TLP_GREEN,
     81 + MARKING_TLP_AMBER,
     82 + MARKING_TLP_AMBER_STRICT,
     83 + MARKING_TLP_RED
     84 +];
    73 85  export const STATIC_STANDARD_IDS = [
    74  - { id: MARKING_TLP_CLEAR, data: { definition_type: 'TLP', definition: 'TLP:WHITE' } },
    75  - { id: MARKING_TLP_CLEAR, data: { definition_type: 'TLP', definition: 'TLP:CLEAR' } },
    76  - { id: MARKING_TLP_GREEN, data: { definition_type: 'TLP', definition: 'TLP:GREEN' } },
    77  - { id: MARKING_TLP_AMBER, data: { definition_type: 'TLP', definition: 'TLP:AMBER' } },
    78  - { id: MARKING_TLP_AMBER_STRICT, data: { definition_type: 'TLP', definition: 'TLP:AMBER+STRICT' } },
    79  - { id: MARKING_TLP_RED, data: { definition_type: 'TLP', definition: 'TLP:RED' } }
     86 + { id: MARKING_TLP_CLEAR_ID, data: { definition_type: 'TLP', definition: 'TLP:WHITE' } },
     87 + { id: MARKING_TLP_CLEAR_ID, data: { definition_type: 'TLP', definition: 'TLP:CLEAR' } },
     88 + { id: MARKING_TLP_GREEN_ID, data: { definition_type: 'TLP', definition: 'TLP:GREEN' } },
     89 + { id: MARKING_TLP_AMBER_ID, data: { definition_type: 'TLP', definition: 'TLP:AMBER' } },
     90 + { id: MARKING_TLP_AMBER_STRICT_ID, data: { definition_type: 'TLP', definition: 'TLP:AMBER+STRICT' } },
     91 + { id: MARKING_TLP_RED_ID, data: { definition_type: 'TLP', definition: 'TLP:RED' } }
    80 92  ];
    81 93  const getStaticIdFromData = (data) => {
    82 94   const findStatic = R.find((s) => R.equals(s.data, data), STATIC_STANDARD_IDS);
    skipped 414 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/utils/indicator-utils.ts
     1 +import type { Moment } from 'moment';
     2 +import {
     3 + MARKING_TLP_AMBER,
     4 + MARKING_TLP_AMBER_STRICT,
     5 + MARKING_TLP_CLEAR,
     6 + MARKING_TLP_GREEN,
     7 + MARKING_TLP_RED,
     8 + STATIC_MARKING_IDS
     9 +} from '../schema/identifier';
     10 +import { getEntitiesMapFromCache } from '../database/cache';
     11 +import { ENTITY_TYPE_MARKING_DEFINITION } from '../schema/stixMetaObject';
     12 +import type { AuthContext, AuthUser } from '../types/user';
     13 +import type { IndicatorAddInput } from '../generated/graphql';
     14 +import type { BasicStoreEntity } from '../types/store';
     15 +import { isNotEmptyField } from '../database/utils';
     16 +import { utcDate } from './format';
     17 + 
     18 +interface TTL_DEFINITION {
     19 + target: Array<string>;
     20 + definition?: Record<string, number>;
     21 + default: number;
     22 +}
     23 + 
     24 +export const DEFAULT_INDICATOR_TTL = 365;
     25 +const INDICATOR_TTL_DEFINITION: Array<TTL_DEFINITION> = [
     26 + {
     27 + target: ['IPv4-Addr', 'IPv6-Addr'],
     28 + definition: {
     29 + [MARKING_TLP_CLEAR]: 30,
     30 + [MARKING_TLP_GREEN]: 30,
     31 + [MARKING_TLP_AMBER]: 30,
     32 + [MARKING_TLP_AMBER_STRICT]: 60,
     33 + [MARKING_TLP_RED]: 60,
     34 + },
     35 + default: 60
     36 + },
     37 + {
     38 + target: ['File'],
     39 + default: DEFAULT_INDICATOR_TTL
     40 + },
     41 + {
     42 + target: ['Url'],
     43 + definition: {
     44 + [MARKING_TLP_CLEAR]: 60,
     45 + [MARKING_TLP_GREEN]: 60,
     46 + [MARKING_TLP_AMBER]: 180,
     47 + [MARKING_TLP_AMBER_STRICT]: 180,
     48 + [MARKING_TLP_RED]: 180,
     49 + },
     50 + default: 180
     51 + },
     52 +];
     53 + 
     54 +export const computeValidTTL = async (context: AuthContext, user: AuthUser, indicator: IndicatorAddInput) => {
     55 + const observableType = indicator.x_opencti_main_observable_type;
     56 + if (observableType) {
     57 + const data = INDICATOR_TTL_DEFINITION.find((ttl) => ttl.target.includes(observableType));
     58 + if (data) {
     59 + if (data.definition && indicator.objectMarking && indicator.objectMarking.length > 0) {
     60 + // Resolve the markings and get the higher rank for TLP
     61 + const markingsMap = await getEntitiesMapFromCache<BasicStoreEntity>(context, user, ENTITY_TYPE_MARKING_DEFINITION);
     62 + const topTlpMarking = indicator.objectMarking
     63 + .map((id) => markingsMap.get(id))
     64 + .filter((marking): marking is BasicStoreEntity => marking !== null && marking !== undefined)
     65 + .filter((marking) => STATIC_MARKING_IDS.includes(marking.standard_id))
     66 + .sort((a, b) => b.x_opencti_order - a.x_opencti_order)
     67 + .at(0);
     68 + if (topTlpMarking) {
     69 + return data.definition[topTlpMarking.standard_id];
     70 + }
     71 + }
     72 + return data.default;
     73 + }
     74 + }
     75 + return DEFAULT_INDICATOR_TTL;
     76 +};
     77 + 
     78 +const computeValidFrom = (indicator: IndicatorAddInput): Moment => {
     79 + if (isNotEmptyField(indicator.valid_from)) {
     80 + return utcDate(indicator.valid_from);
     81 + }
     82 + if (isNotEmptyField(indicator.created)) {
     83 + return utcDate(indicator.created);
     84 + }
     85 + return utcDate();
     86 +};
     87 + 
     88 +const computeValidUntil = async (context: AuthContext, user: AuthUser, indicator: IndicatorAddInput, validFrom: Moment): Promise<Moment> => {
     89 + if (isNotEmptyField(indicator.valid_until)) {
     90 + return utcDate(indicator.valid_until);
     91 + }
     92 + const ttl = await computeValidTTL(context, user, indicator);
     93 + return validFrom.clone().add(ttl, 'days');
     94 +};
     95 + 
     96 +export const computeValidPeriod = async (context: AuthContext, user: AuthUser, indicator: IndicatorAddInput) => {
     97 + const validFrom = computeValidFrom(indicator);
     98 + const validUntil = await computeValidUntil(context, user, indicator, validFrom);
     99 + return { validFrom: validFrom.toISOString(), validUntil: validUntil.toISOString() };
     100 +};
     101 + 
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/tests/01-unit/domain/indicator-test.js
    1  -import { describe, expect, it } from 'vitest';
    2  -import { extractObservablesFromIndicatorPattern } from '../../../src/utils/syntax';
    3  -import * as C from '../../../src/schema/stixCyberObservable';
    4  - 
    5  -describe.concurrent('indicator', () => {
    6  - it('should observables correctly extracted', async () => {
    7  - console.log('indicator');
    8  - // simpleHash
    9  - const simpleHash = extractObservablesFromIndicatorPattern("[file:hashes.'SHA-256' = '4bac27393bdd9777ce02453256c5577cd02275510b2227f473d03f533924f877']");
    10  - expect(simpleHash.length).toEqual(1);
    11  - expect(simpleHash[0].type).toEqual(C.ENTITY_HASHED_OBSERVABLE_STIX_FILE);
    12  - expect(simpleHash[0].hashes['SHA-256']).toEqual('4bac27393bdd9777ce02453256c5577cd02275510b2227f473d03f533924f877');
    13  - // multipleHashes
    14  - const multipleHashes = extractObservablesFromIndicatorPattern("[file:hashes.'SHA-256' = 'bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c' OR file:hashes.MD5 = 'cead3f77f6cda6ec00f57d76c9a6879f']");
    15  - expect(multipleHashes.length).toEqual(2);
    16  - expect(multipleHashes[0].type).toEqual(C.ENTITY_HASHED_OBSERVABLE_STIX_FILE);
    17  - expect(multipleHashes[0].hashes['SHA-256']).toEqual('bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c');
    18  - expect(multipleHashes[1].type).toEqual(C.ENTITY_HASHED_OBSERVABLE_STIX_FILE);
    19  - expect(multipleHashes[1].hashes.MD5).toEqual('cead3f77f6cda6ec00f57d76c9a6879f');
    20  - // simpleipv4
    21  - const simpleipv4 = extractObservablesFromIndicatorPattern("[ipv4-addr:value = '183.89.215.254']");
    22  - expect(simpleipv4.length).toEqual(1);
    23  - expect(simpleipv4[0].type).toEqual(C.ENTITY_IPV4_ADDR);
    24  - expect(simpleipv4[0].value).toEqual('183.89.215.254');
    25  - // domainAndIp
    26  - const domainAndIp = extractObservablesFromIndicatorPattern("[domain-name:value = '5z8.info' AND domain-name:resolves_to_refs[*].value = '198.51.100.1']");
    27  - expect(domainAndIp.length).toEqual(1);
    28  - expect(domainAndIp[0].type).toEqual(C.ENTITY_DOMAIN_NAME);
    29  - expect(domainAndIp[0].value).toEqual('5z8.info');
    30  - // domainAndHostname
    31  - const domainAndHostname = extractObservablesFromIndicatorPattern("[domain-name:value = '5z8.info' OR domain-name:value = 'www.5z8.info']");
    32  - expect(domainAndHostname.length).toEqual(2);
    33  - expect(domainAndHostname[0].type).toEqual(C.ENTITY_DOMAIN_NAME);
    34  - expect(domainAndHostname[0].value).toEqual('5z8.info');
    35  - expect(domainAndHostname[1].type).toEqual(C.ENTITY_DOMAIN_NAME);
    36  - expect(domainAndHostname[1].value).toEqual('www.5z8.info');
    37  - // simpleEmailAddress
    38  - const simpleEmailAddress = extractObservablesFromIndicatorPattern("[email-message:sender_ref.value = '[email protected]' AND email-message:subject = 'Conference Info']");
    39  - expect(simpleEmailAddress.length).toEqual(1);
    40  - expect(simpleEmailAddress[0].type).toEqual(C.ENTITY_EMAIL_MESSAGE);
    41  - expect(simpleEmailAddress[0].subject).toEqual('Conference Info');
    42  - // simpleUrl
    43  - const simpleUrl = extractObservablesFromIndicatorPattern("[url:value = 'http://localhost.com']");
    44  - expect(simpleUrl.length).toEqual(1);
    45  - expect(simpleUrl[0].type).toEqual(C.ENTITY_URL);
    46  - expect(simpleUrl[0].value).toEqual('http://localhost.com');
    47  - // Unknown type
    48  - const unknown = extractObservablesFromIndicatorPattern("[x-company-type:value = 'http://localhost.com']");
    49  - expect(unknown.length).toEqual(0);
    50  - });
    51  -});
    52  - 
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/tests/01-unit/domain/indicator-test.ts
     1 +import { describe, expect, it } from 'vitest';
     2 +import { extractObservablesFromIndicatorPattern } from '../../../src/utils/syntax';
     3 +import * as C from '../../../src/schema/stixCyberObservable';
     4 +import { computeValidTTL, computeValidPeriod, DEFAULT_INDICATOR_TTL } from '../../../src/utils/indicator-utils';
     5 +import { ADMIN_USER, testContext } from '../../utils/testQuery';
     6 +import { MARKING_TLP_AMBER, MARKING_TLP_GREEN, MARKING_TLP_RED } from '../../../src/schema/identifier';
     7 + 
     8 +const DEFAULT_PARAM = { name: 'indicator', pattern_type: 'stix', pattern: 'undefined' };
     9 + 
     10 +describe.concurrent('indicator utils', () => {
     11 + it('should observables correctly extracted', async () => {
     12 + // simpleHash
     13 + const simpleHash = extractObservablesFromIndicatorPattern('[file:hashes.\'SHA-256\' = \'4bac27393bdd9777ce02453256c5577cd02275510b2227f473d03f533924f877\']');
     14 + expect(simpleHash.length).toEqual(1);
     15 + expect(simpleHash[0].type).toEqual(C.ENTITY_HASHED_OBSERVABLE_STIX_FILE);
     16 + expect(simpleHash[0].hashes['SHA-256']).toEqual('4bac27393bdd9777ce02453256c5577cd02275510b2227f473d03f533924f877');
     17 + // multipleHashes
     18 + const multipleHashes = extractObservablesFromIndicatorPattern('[file:hashes.\'SHA-256\' = \'bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c\' OR file:hashes.MD5 = \'cead3f77f6cda6ec00f57d76c9a6879f\']');
     19 + expect(multipleHashes.length).toEqual(2);
     20 + expect(multipleHashes[0].type).toEqual(C.ENTITY_HASHED_OBSERVABLE_STIX_FILE);
     21 + expect(multipleHashes[0].hashes['SHA-256']).toEqual('bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c');
     22 + expect(multipleHashes[1].type).toEqual(C.ENTITY_HASHED_OBSERVABLE_STIX_FILE);
     23 + expect(multipleHashes[1].hashes.MD5).toEqual('cead3f77f6cda6ec00f57d76c9a6879f');
     24 + // simpleipv4
     25 + const simpleipv4 = extractObservablesFromIndicatorPattern('[ipv4-addr:value = \'183.89.215.254\']');
     26 + expect(simpleipv4.length).toEqual(1);
     27 + expect(simpleipv4[0].type).toEqual(C.ENTITY_IPV4_ADDR);
     28 + expect(simpleipv4[0].value).toEqual('183.89.215.254');
     29 + // domainAndIp
     30 + const domainAndIp = extractObservablesFromIndicatorPattern('[domain-name:value = \'5z8.info\' AND domain-name:resolves_to_refs[*].value = \'198.51.100.1\']');
     31 + expect(domainAndIp.length).toEqual(1);
     32 + expect(domainAndIp[0].type).toEqual(C.ENTITY_DOMAIN_NAME);
     33 + expect(domainAndIp[0].value).toEqual('5z8.info');
     34 + // domainAndHostname
     35 + const domainAndHostname = extractObservablesFromIndicatorPattern('[domain-name:value = \'5z8.info\' OR domain-name:value = \'www.5z8.info\']');
     36 + expect(domainAndHostname.length).toEqual(2);
     37 + expect(domainAndHostname[0].type).toEqual(C.ENTITY_DOMAIN_NAME);
     38 + expect(domainAndHostname[0].value).toEqual('5z8.info');
     39 + expect(domainAndHostname[1].type).toEqual(C.ENTITY_DOMAIN_NAME);
     40 + expect(domainAndHostname[1].value).toEqual('www.5z8.info');
     41 + // simpleEmailAddress
     42 + const simpleEmailAddress = extractObservablesFromIndicatorPattern('[email-message:sender_ref.value = \'[email protected]\' AND email-message:subject = \'Conference Info\']');
     43 + expect(simpleEmailAddress.length).toEqual(1);
     44 + expect(simpleEmailAddress[0].type).toEqual(C.ENTITY_EMAIL_MESSAGE);
     45 + expect(simpleEmailAddress[0].subject).toEqual('Conference Info');
     46 + // simpleUrl
     47 + const simpleUrl = extractObservablesFromIndicatorPattern('[url:value = \'http://localhost.com\']');
     48 + expect(simpleUrl.length).toEqual(1);
     49 + expect(simpleUrl[0].type).toEqual(C.ENTITY_URL);
     50 + expect(simpleUrl[0].value).toEqual('http://localhost.com');
     51 + // Unknown type
     52 + const unknown = extractObservablesFromIndicatorPattern('[x-company-type:value = \'http://localhost.com\']');
     53 + expect(unknown.length).toEqual(0);
     54 + });
     55 + it('should valid_from default', async () => {
     56 + const { validFrom } = await computeValidPeriod(testContext, ADMIN_USER, { ...DEFAULT_PARAM });
     57 + expect(validFrom).toBeDefined();
     58 + });
     59 + it('should valid_from created', async () => {
     60 + const { validFrom, validUntil } = await computeValidPeriod(testContext, ADMIN_USER, {
     61 + ...DEFAULT_PARAM,
     62 + created: '2023-01-21T17:57:09.266Z'
     63 + });
     64 + expect(validFrom).toBe('2023-01-21T17:57:09.266Z');
     65 + expect(validUntil).toBe('2024-01-21T17:57:09.266Z');
     66 + });
     67 + it('should valid_from itself', async () => {
     68 + const { validFrom, validUntil } = await computeValidPeriod(testContext, ADMIN_USER, {
     69 + ...DEFAULT_PARAM,
     70 + valid_from: '2023-02-21T17:57:09.266Z',
     71 + created: '2023-01-21T17:57:09.266Z'
     72 + });
     73 + expect(validFrom).toBe('2023-02-21T17:57:09.266Z');
     74 + expect(validUntil).toBe('2024-02-21T17:57:09.266Z');
     75 + });
     76 + it('should ttl default', async () => {
     77 + let ttl = await computeValidTTL(testContext, ADMIN_USER, { ...DEFAULT_PARAM });
     78 + expect(ttl).toBe(DEFAULT_INDICATOR_TTL);
     79 + ttl = await computeValidTTL(testContext, ADMIN_USER, { ...DEFAULT_PARAM, objectMarking: [] });
     80 + expect(ttl).toBe(DEFAULT_INDICATOR_TTL);
     81 + ttl = await computeValidTTL(testContext, ADMIN_USER, {
     82 + ...DEFAULT_PARAM,
     83 + x_opencti_main_observable_type: 'wrong'
     84 + });
     85 + expect(ttl).toBe(DEFAULT_INDICATOR_TTL);
     86 + ttl = await computeValidTTL(testContext, ADMIN_USER, { ...DEFAULT_PARAM, objectMarking: ['invalid'] });
     87 + expect(ttl).toBe(DEFAULT_INDICATOR_TTL);
     88 + });
     89 + it('should ttl File', async () => {
     90 + const ttl = await computeValidTTL(testContext, ADMIN_USER, {
     91 + ...DEFAULT_PARAM,
     92 + x_opencti_main_observable_type: 'File',
     93 + objectMarking: [MARKING_TLP_GREEN],
     94 + });
     95 + expect(ttl).toBe(365);
     96 + });
     97 + it('should ttl Url', async () => {
     98 + const ttl = await computeValidTTL(testContext, ADMIN_USER, {
     99 + ...DEFAULT_PARAM,
     100 + x_opencti_main_observable_type: 'Url',
     101 + objectMarking: [MARKING_TLP_AMBER],
     102 + });
     103 + expect(ttl).toBe(180);
     104 + });
     105 + it('should ttl Url ordered', async () => {
     106 + const ttl = await computeValidTTL(testContext, ADMIN_USER, {
     107 + ...DEFAULT_PARAM,
     108 + x_opencti_main_observable_type: 'Url',
     109 + objectMarking: [MARKING_TLP_GREEN, MARKING_TLP_RED],
     110 + });
     111 + expect(ttl).toBe(180);
     112 + });
     113 + it('should ttl IPv6', async () => {
     114 + const ttl = await computeValidTTL(testContext, ADMIN_USER, {
     115 + ...DEFAULT_PARAM,
     116 + x_opencti_main_observable_type: 'IPv6-Addr',
     117 + objectMarking: [MARKING_TLP_RED],
     118 + });
     119 + expect(ttl).toBe(60);
     120 + });
     121 +});
     122 + 
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/tests/utils/testQuery.js opencti-platform/opencti-graphql/tests/utils/testQuery.ts
    skipped 5 lines
    6 6   
    7 7  // region static graphql modules
    8 8  import '../../src/modules/index';
     9 +import type { AuthUser } from '../../src/types/user';
    9 10  // endregion
    10 11   
    11 12  export const SYNC_RAW_START_REMOTE_URI = conf.get('app:sync_raw_start_remote_uri');
    skipped 22 lines
    34 35   return `Basic ${buff.toString('base64')}`;
    35 36  };
    36 37   
    37  -export const executeExternalQuery = async (uri, query, variables = {}) => {
     38 +export const executeExternalQuery = async (uri: string, query: unknown, variables = {}) => {
    38 39   const response = await axios({
    39 40   url: uri,
    40 41   method: 'POST',
    skipped 8 lines
    49 50   return data;
    50 51  };
    51 52   
    52  -export const ADMIN_USER = {
     53 +export const ADMIN_USER: AuthUser = {
    53 54   id: '88ec0c6a-13ce-5e39-b486-354fe4a7084f',
     55 + internal_id: '88ec0c6a-13ce-5e39-b486-354fe4a7084f',
     56 + organizations: [],
    54 57   name: 'admin',
    55 58   user_email: '[email protected]',
    56  - otp_activated: false,
    57  - otp_validated: false,
    58 59   roles: [{ name: ROLE_ADMINISTRATOR }],
    59 60   capabilities: [{ name: BYPASS }],
    60  - groups: [],
     61 + all_marking: [],
     62 + allowed_organizations: [],
     63 + inside_platform_organization: true,
    61 64   allowed_marking: [],
    62  - origin: { source: 'test', user_id: '88ec0c6a-13ce-5e39-b486-354fe4a7084f' },
     65 + origin: { referer: 'test', user_id: '88ec0c6a-13ce-5e39-b486-354fe4a7084f' }
    63 66  };
    64 67   
    65 68  export const serverFromUser = (user = ADMIN_USER) => {
    skipped 2 lines
    68 71   introspection: true,
    69 72   persistedQueries: false,
    70 73   context: () => {
    71  - const executeContext = executionContext('test');
    72  - executeContext.user = user;
    73  - return executeContext;
     74 + return executionContext('test', user);
    74 75   },
    75 76   });
    76 77  };
    77 78   
    78 79  const adminApolloServer = serverFromUser();
    79  -export const queryAsAdmin = (request) => adminApolloServer.executeOperation(request);
     80 +export const queryAsAdmin = (request: any) => adminApolloServer.executeOperation(request);
    80 81   
Please wait...
Page is in error, reload to recover