Projects STRLCPY opencti Commits 194f7301
🤬
  • ■ ■ ■ ■ ■
    opencti-platform/opencti-front/src/private/components/common/form/StatusTemplateField.tsx
    skipped 71 lines
    72 72   value: n?.node.id,
    73 73   color: n?.node.color,
    74 74   }));
    75  - setStatusTemplates([...statusTemplates, ...NewStatusTemplates]);
     75 + const templateValues = [...statusTemplates, ...NewStatusTemplates];
     76 + // Keep only the unique list of options
     77 + const uniqTemplates = templateValues.filter((item, index) => {
     78 + return templateValues.findIndex((e) => e.value === item.value) === index;
     79 + });
     80 + setStatusTemplates(uniqTemplates);
    76 81   });
    77 82   };
    78 83   
    skipped 43 lines
  • ■ ■ ■ ■ ■
    opencti-platform/opencti-front/src/private/components/common/stix_core_objects/StixCoreObjectSharing.tsx
    skipped 113 lines
    114 114   const { t } = useFormatter();
    115 115   const { me } = useContext(UserContext);
    116 116   const [displaySharing, setDisplaySharing] = useState(false);
    117  - const userIsOrganizationEditor = granted(me, [
    118  - KNOWLEDGE_KNUPDATE_KNORGARESTRICT,
    119  - ]);
     117 + const userIsOrganizationEditor = granted(me, [KNOWLEDGE_KNUPDATE_KNORGARESTRICT]);
    120 118   // If user not an organization organizer, return empty div
    121  - if (!userIsOrganizationEditor && variant === 'header') {
    122  - return <div style={{ display: 'inline-block' }} />;
    123  - }
    124 119   if (!userIsOrganizationEditor) {
    125  - return <div style={{ marginTop: -20 }} />;
     120 + return variant === 'header' ? <div style={{ display: 'inline-block' }} /> : <div style={{ marginTop: -20 }} />;
    126 121   }
    127 122   const handleOpenSharing = () => setDisplaySharing(true);
    128 123   const handleCloseSharing = () => setDisplaySharing(false);
    skipped 188 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-front/src/private/components/settings/roles/RoleEditionOverview.js
    1 1  import React from 'react';
    2 2  import * as PropTypes from 'prop-types';
    3  -import { graphql, createFragmentContainer } from 'react-relay';
    4  -import { Form, Formik, Field } from 'formik';
     3 +import { createFragmentContainer, graphql } from 'react-relay';
     4 +import { Field, Form, Formik } from 'formik';
    5 5  import * as R from 'ramda';
    6 6  import * as Yup from 'yup';
    7 7  import ListItem from '@mui/material/ListItem';
    skipped 9 lines
    17 17  import inject18n from '../../../../components/i18n';
    18 18  import Loader from '../../../../components/Loader';
    19 19  import SwitchField from '../../../../components/SwitchField';
     20 +import { CAPABILITY_INFORMATION } from '../../../../utils/Security';
    20 21   
    21 22  const roleMutationFieldPatch = graphql`
    22 23   mutation RoleEditionOverviewFieldPatchMutation(
    skipped 202 lines
    225 226   );
    226 227   const isDisabled = matchingCapabilities.length > 0;
    227 228   const isChecked = isDisabled || roleCapability !== undefined;
     229 + const capabilityDetail = CAPABILITY_INFORMATION[capability.name];
     230 + const capabilityDetailText = capabilityDetail ? ` (${t(capabilityDetail)})` : '';
    228 231   return (
    229  - <ListItem
    230  - key={capability.name}
    231  - divider={true}
    232  - style={{ paddingLeft }}
    233  - >
    234  - <ListItemText primary={capability.description} />
     232 + <ListItem key={capability.name} divider={true} style={{ paddingLeft }}>
     233 + <ListItemText primary={t(capability.description) + capabilityDetailText} />
    235 234   <ListItemSecondaryAction>
    236  - <Checkbox
    237  - onChange={(event) => handleToggle(capability, event)
    238  - }
     235 + <Checkbox onChange={(event) => handleToggle(capability, event)}
    239 236   checked={isChecked}
    240 237   disabled={isDisabled}
    241 238   />
    skipped 46 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-front/src/utils/Security.tsx
    skipped 35 lines
    36 36  export const TAXIIAPI_SETCOLLECTIONS = 'TAXIIAPI_SETCOLLECTIONS';
    37 37  export const SETTINGS_SETACCESSES = 'SETTINGS_SETACCESSES';
    38 38  export const SETTINGS_SETLABELS = 'SETTINGS_SETLABELS';
     39 +export const CAPABILITY_INFORMATION = {
     40 + [KNOWLEDGE_KNUPDATE_KNORGARESTRICT]: 'Granted only if user is a member of platform organization',
     41 +};
    39 42   
    40 43  interface SecurityProps {
    41 44   children: ReactElement;
    skipped 70 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/config/audit.ts
    skipped 27 lines
    28 28   if (name === 'member-of') {
    29 29   convertName = 'GROUP';
    30 30   }
     31 + if (name === 'participate-to') {
     32 + convertName = 'ORGANIZATION';
     33 + }
    31 34   return isAdd ? `${convertName}_ADD` : `${convertName}_REMOVE`;
    32 35  };
    33 36   
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/database/engine.js
    skipped 316 lines
    317 317   // Data with Empty granted_refs are not visible
    318 318   // Data with granted_refs users that participate to at least one
    319 319   const should = [...excludedEntityMatches];
    320  - const shouldOrgs = user.organizations.map((m) => ({ match: { [buildRefRelationSearchKey(RELATION_GRANTED_TO)]: m.internal_id } }));
     320 + const shouldOrgs = user.allowed_organizations
     321 + .map((m) => ({ match: { [buildRefRelationSearchKey(RELATION_GRANTED_TO)]: m.internal_id } }));
    321 322   should.push(...shouldOrgs);
    322 323   // User individual or data created by this individual must be accessible
    323 324   if (user.individual_id) {
    skipped 8 lines
    332 333   const should = [...excludedEntityMatches];
    333 334   should.push({ bool: { must_not: [{ exists: { field: buildRefRelationSearchKey(RELATION_GRANTED_TO) } }] } });
    334 335   // Data with granted_refs users that participate to at least one
    335  - if (user.organizations.length > 0) {
    336  - const shouldOrgs = user.organizations.map((m) => ({ match: { [buildRefRelationSearchKey(RELATION_GRANTED_TO)]: m.internal_id } }));
     336 + if (user.allowed_organizations.length > 0) {
     337 + const shouldOrgs = user.allowed_organizations
     338 + .map((m) => ({ match: { [buildRefRelationSearchKey(RELATION_GRANTED_TO)]: m.internal_id } }));
    337 339   should.push(...shouldOrgs);
    338 340   }
    339 341   // User individual or data created by this individual must be accessible
    skipped 2011 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/database/middleware.js
    skipped 595 lines
    596 596   // Relationship
    597 597   { src: 'fromId', dst: 'from' },
    598 598   { src: 'toId', dst: 'to' },
    599  - // Granted
    600  - { src: INPUT_GRANTED_REFS },
    601 599   // Other meta refs
    602 600   ...STIX_META_RELATIONSHIPS_INPUTS.map((e) => ({ src: e })),
    603 601   ...STIX_CYBER_OBSERVABLE_RELATIONSHIPS_INPUTS.map((e) => ({ src: e })),
    skipped 671 lines
    1275 1273   // - TRANSACTION PART
    1276 1274   const mergeImpacts = await mergeEntitiesRaw(context, user, target, sources, targetDependencies, sourcesDependencies, opts);
    1277 1275   const mergedInstance = await storeLoadByIdWithRefs(context, user, targetEntityId);
    1278  - await storeMergeEvent(context, user, initialInstance, mergedInstance, sources, mergeImpacts);
     1276 + await storeMergeEvent(context, user, initialInstance, mergedInstance, sources, mergeImpacts, opts);
    1279 1277   // Temporary stored the deleted elements to prevent concurrent problem at creation
    1280 1278   await redisAddDeletions(sources.map((s) => s.internal_id));
    1281 1279   // - END TRANSACTION
    skipped 1567 lines
    2849 2847   }
    2850 2848   // Create the meta relationships (ref, refs)
    2851 2849   const relToCreate = [];
    2852  - // For organizations management
    2853  - if (!STIX_ORGANIZATIONS_UNRESTRICTED.some((o) => getParentTypes(data.entity_type).includes(o))) {
    2854  - if (userHaveCapability(user, KNOWLEDGE_ORGANIZATION_RESTRICT)) {
    2855  - relToCreate.push(...buildInnerRelation(data, input[INPUT_GRANTED_REFS], RELATION_GRANTED_TO));
    2856  - } else if (!user.inside_platform_organization) {
    2857  - // If user is not part of the platform organization, put its own organizations
    2858  - relToCreate.push(...buildInnerRelation(data, user.organizations, RELATION_GRANTED_TO));
     2850 + const isSegregationEntity = !STIX_ORGANIZATIONS_UNRESTRICTED.some((o) => getParentTypes(data.entity_type).includes(o));
     2851 + const appendMetaRelationships = (inputField, relType) => {
     2852 + if (input[inputField] || relType === RELATION_GRANTED_TO) {
     2853 + // For organizations management
     2854 + if (relType === RELATION_GRANTED_TO && isSegregationEntity) {
     2855 + if (userHaveCapability(user, KNOWLEDGE_ORGANIZATION_RESTRICT) && input[inputField]) {
     2856 + relToCreate.push(...buildInnerRelation(data, input[inputField], RELATION_GRANTED_TO));
     2857 + } else if (!user.inside_platform_organization) {
     2858 + // If user is not part of the platform organization, put its own organizations
     2859 + relToCreate.push(...buildInnerRelation(data, user.organizations, RELATION_GRANTED_TO));
     2860 + }
     2861 + } else if (input[inputField]) {
     2862 + const instancesToCreate = Array.isArray(input[inputField]) ? input[inputField] : [input[inputField]];
     2863 + relToCreate.push(...buildInnerRelation(data, instancesToCreate, relType));
     2864 + }
    2859 2865   }
    2860  - }
     2866 + };
    2861 2867   // For meta stix core
    2862 2868   if (isStixCoreObject(type)) {
    2863 2869   const inputFields = STIX_META_RELATIONSHIPS_INPUTS;
    2864 2870   for (let fieldIndex = 0; fieldIndex < inputFields.length; fieldIndex += 1) {
    2865 2871   const inputField = inputFields[fieldIndex];
    2866  - if (input[inputField]) {
    2867  - const relType = FIELD_TO_META_RELATION[inputField];
    2868  - relToCreate.push(...buildInnerRelation(data, input[inputField], relType));
    2869  - }
     2872 + const relType = FIELD_TO_META_RELATION[inputField];
     2873 + appendMetaRelationships(inputField, relType);
    2870 2874   }
    2871 2875   }
    2872 2876   // For meta observables
    skipped 1 lines
    2874 2878   const inputFields = stixCyberObservableFieldsForType(type);
    2875 2879   for (let fieldIndex = 0; fieldIndex < inputFields.length; fieldIndex += 1) {
    2876 2880   const inputField = inputFields[fieldIndex];
    2877  - if (input[inputField]) {
    2878  - const instancesToCreate = Array.isArray(input[inputField]) ? input[inputField] : [input[inputField]];
    2879  - const stixField = STIX_CYBER_OBSERVABLE_FIELD_TO_STIX_ATTRIBUTE[inputField];
    2880  - const relType = STIX_ATTRIBUTE_TO_CYBER_RELATIONS[stixField];
    2881  - const newRelations = buildInnerRelation(data, instancesToCreate, relType);
    2882  - relToCreate.push(...newRelations);
    2883  - }
     2881 + const stixField = STIX_CYBER_OBSERVABLE_FIELD_TO_STIX_ATTRIBUTE[inputField];
     2882 + const relType = STIX_ATTRIBUTE_TO_CYBER_RELATIONS[stixField];
     2883 + appendMetaRelationships(inputField, relType);
    2884 2884   }
    2885 2885   }
    2886 2886   // Transaction succeed, complete the result to send it back
    skipped 348 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/database/redis.ts
    skipped 18 lines
    19 19   isInferredIndex,
    20 20   waitInSec,
    21 21  } from './utils';
    22  -import { isStixExportableData } from '../schema/stixCoreObject';
     22 +import { INTERNAL_EXPORTABLE_TYPES, isStixExportableData } from '../schema/stixCoreObject';
    23 23  import { DatabaseError, FunctionalError, UnsupportedError } from '../config/errors';
    24 24  import { now, utcDate } from '../utils/format';
    25 25  import RedisStore, { REDIS_PREFIX } from './sessionStore-redis';
    skipped 5 lines
    31 31  import type {
    32 32   CreateEventOpts,
    33 33   DeleteEvent,
    34  - DeleteEventOpts,
    35 34   Event,
     35 + EventOpts,
    36 36   MergeEvent,
    37 37   StreamEvent,
    38 38   UpdateEvent,
    skipped 1 lines
    40 40  } from '../types/event';
    41 41  import type { StixCoreObject } from '../types/stix-common';
    42 42  import type { EditContext } from '../generated/graphql';
    43  -import { RELATION_PARTICIPATE_TO } from '../schema/internalRelationship';
    44 43  import { telemetry } from '../config/tracing';
    45 44   
    46 45  const USE_SSL = booleanConf('redis:use_ssl', false);
    skipped 7 lines
    54 53  const REDIS_EXPIRE_TIME = 90;
    55 54  const MAX_RETRY_COMMAND = 10;
    56 55   
    57  -const allowedInternalEventTypes = [RELATION_PARTICIPATE_TO];
    58  -const isStreamPublishable = (instance: StoreObject) => {
     56 +const isStreamPublishable = (instance: StoreObject, opts: EventOpts) => {
    59 57   const isInferredInstance = isInferredIndex(instance._index);
    60 58   if (isInferredInstance && !INCLUDE_INFERENCES) return false;
    61  - return isStixExportableData(instance) || allowedInternalEventTypes.includes(instance.entity_type);
     59 + return opts.publishStreamEvent === undefined || opts.publishStreamEvent;
    62 60  };
    63 61   
    64 62  const redisOptions = (database: number): RedisOptions => ({
    skipped 320 lines
    385 383   });
    386 384   return cmdArgs;
    387 385  };
    388  -const isDataStreamable = (instance: StoreObject, opts: { publishStreamEvent?: boolean }) => {
    389  - return isStixExportableData(instance) && (opts.publishStreamEvent === undefined || opts.publishStreamEvent);
    390  -};
    391  -const pushToStream = async (context: AuthContext, user: AuthUser, client: Redis, instance: StoreObject, event: Event) => {
    392  - if (isStreamPublishable(instance)) {
     386 +const pushToStream = async (context: AuthContext, user: AuthUser, client: Redis, instance: StoreObject, event: Event, opts: EventOpts) => {
     387 + if (isStreamPublishable(instance, opts)) {
    393 388   const pushToStreamFn = async () => {
    394 389   if (streamTrimming) {
    395 390   await client.call('XADD', REDIS_STREAM_NAME, 'MAXLEN', '~', streamTrimming, '*', ...mapJSToStream(event));
    skipped 8 lines
    404 399  };
    405 400   
    406 401  // Merge
    407  -const buildMergeEvent = (user: AuthUser, previous: StoreObject, instance: StoreObject, sourceEntities: Array<StoreObject>, impacts: any): MergeEvent => {
     402 +interface MergeImpacts {
     403 + updatedRelations: Array<string>;
     404 + dependencyDeletions: Array<StoreObject>;
     405 +}
     406 +const buildMergeEvent = (user: AuthUser, previous: StoreObject, instance: StoreObject, sourceEntities: Array<StoreObject>, impacts: MergeImpacts): MergeEvent => {
    408 407   const message = generateMergeMessage(instance, sourceEntities);
    409 408   const { updatedRelations, dependencyDeletions } = impacts;
    410 409   const previousStix = convertStoreToStix(previous) as StixCoreObject;
    skipped 1 lines
    412 411   return {
    413 412   version: EVENT_CURRENT_VERSION,
    414 413   type: EVENT_TYPE_MERGE,
    415  - scope: 'external',
     414 + scope: INTERNAL_EXPORTABLE_TYPES.includes(instance.entity_type) ? 'internal' : 'external',
    416 415   message,
    417 416   origin: user.origin,
    418 417   data: currentStix,
    skipped 12 lines
    431 430   initialInstance: StoreObject,
    432 431   mergedInstance: StoreObject,
    433 432   sourceEntities: Array<StoreObject>,
    434  - impacts: any
     433 + impacts: MergeImpacts,
     434 + opts: EventOpts,
    435 435  ) => {
    436 436   try {
    437 437   const event = buildMergeEvent(user, initialInstance, mergedInstance, sourceEntities, impacts);
    438  - await pushToStream(context, user, clientBase, mergedInstance, event);
     438 + await pushToStream(context, user, clientBase, mergedInstance, event, opts);
    439 439   return event;
    440 440   } catch (e) {
    441 441   throw DatabaseError('Error in store merge event', { error: e });
    skipped 15 lines
    457 457   return {
    458 458   version: EVENT_CURRENT_VERSION,
    459 459   type: EVENT_TYPE_UPDATE,
    460  - scope: isDataStreamable(instance, opts) ? 'external' : 'internal',
     460 + scope: INTERNAL_EXPORTABLE_TYPES.includes(instance.entity_type) ? 'internal' : 'external',
    461 461   message,
    462 462   origin: user.origin,
    463 463   data: stix,
    skipped 8 lines
    472 472   try {
    473 473   if (isStixExportableData(instance)) {
    474 474   const event = buildUpdateEvent(user, previous, instance, message, opts);
    475  - if (opts.publishStreamEvent === undefined || opts.publishStreamEvent) {
    476  - await pushToStream(context, user, clientBase, instance, event);
    477  - }
     475 + await pushToStream(context, user, clientBase, instance, event, opts);
    478 476   return event;
    479 477   }
    480 478   return undefined;
    skipped 2 lines
    483 481   }
    484 482  };
    485 483  // Create
    486  -export const buildCreateEvent = (user: AuthUser, instance: StoreObject, message: string, opts: CreateEventOpts): Event => {
     484 +export const buildCreateEvent = (user: AuthUser, instance: StoreObject, message: string): Event => {
    487 485   const stix = convertStoreToStix(instance) as StixCoreObject;
    488 486   return {
    489 487   version: EVENT_CURRENT_VERSION,
    490 488   type: EVENT_TYPE_CREATE,
    491  - scope: isDataStreamable(instance, opts) ? 'external' : 'internal',
     489 + scope: INTERNAL_EXPORTABLE_TYPES.includes(instance.entity_type) ? 'internal' : 'external',
    492 490   message,
    493 491   origin: user.origin,
    494 492   data: stix,
    skipped 4 lines
    499 497   if (isStixExportableData(instance)) {
    500 498   const { withoutMessage = false } = opts;
    501 499   const message = withoutMessage ? '-' : generateCreateMessage(instance);
    502  - const event = buildCreateEvent(user, instance, message, opts);
    503  - await pushToStream(context, user, clientBase, instance, event);
     500 + const event = buildCreateEvent(user, instance, message);
     501 + await pushToStream(context, user, clientBase, instance, event, opts);
    504 502   return event;
    505 503   }
    506 504   return undefined;
    skipped 4 lines
    511 509  export const storeCreateEntityEvent = async (context: AuthContext, user: AuthUser, instance: StoreObject, message: string, opts: CreateEventOpts = {}) => {
    512 510   try {
    513 511   if (isStixExportableData(instance)) {
    514  - const event = buildCreateEvent(user, instance, message, opts);
    515  - if (opts.publishStreamEvent === undefined || opts.publishStreamEvent) {
    516  - await pushToStream(context, user, clientBase, instance, event);
    517  - }
     512 + const event = buildCreateEvent(user, instance, message);
     513 + await pushToStream(context, user, clientBase, instance, event, opts);
    518 514   return event;
    519 515   }
    520 516   return undefined;
    skipped 8 lines
    529 525   instance: StoreObject,
    530 526   message: string,
    531 527   deletions: Array<StoreObject>,
    532  - opts: DeleteEventOpts
    533 528  ): Promise<DeleteEvent> => {
    534 529   const stix = convertStoreToStix(instance) as StixCoreObject;
    535 530   return {
    536 531   version: EVENT_CURRENT_VERSION,
    537 532   type: EVENT_TYPE_DELETE,
    538  - scope: isDataStreamable(instance, opts) ? 'external' : 'internal',
     533 + scope: INTERNAL_EXPORTABLE_TYPES.includes(instance.entity_type) ? 'internal' : 'external',
    539 534   message,
    540 535   origin: user.origin,
    541 536   data: stix,
    skipped 2 lines
    544 539   }
    545 540   };
    546 541  };
    547  -export const storeDeleteEvent = async (context: AuthContext, user: AuthUser, instance: StoreObject, deletions: Array<StoreObject>, opts: DeleteEventOpts = {}) => {
     542 +export const storeDeleteEvent = async (context: AuthContext, user: AuthUser, instance: StoreObject, deletions: Array<StoreObject>, opts: EventOpts = {}) => {
    548 543   try {
    549 544   if (isStixExportableData(instance)) {
    550 545   const message = generateDeleteMessage(instance);
    551  - const event = await buildDeleteEvent(user, instance, message, deletions, opts);
    552  - await pushToStream(context, user, clientBase, instance, event);
     546 + const event = await buildDeleteEvent(user, instance, message, deletions);
     547 + await pushToStream(context, user, clientBase, instance, event, opts);
    553 548   return event;
    554 549   }
    555 550   return undefined;
    skipped 151 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/database/stix-converter.ts
    1 1  import * as R from 'ramda';
    2  -import { v4 as uuidv4, version as uuidVersion } from 'uuid';
     2 +import { version as uuidVersion } from 'uuid';
    3 3  import { isEmptyField, isInferredIndex } from './utils';
    4 4  import { FunctionalError, UnsupportedError } from '../config/errors';
    5 5  import { isBasicObject } from '../schema/stixCoreObject';
    skipped 332 lines
    338 338  };
    339 339   
    340 340  // INTERNAL
    341  -const convertInternalToStix = (instance: StoreEntity, type: string): S.StixInternalObject => {
     341 +const convertInternalToStix = (instance: StoreEntity, type: string): S.StixObject => {
    342 342   if (!isInternalObject(type)) {
    343 343   throw UnsupportedError(`${instance.entity_type} not compatible with internal`);
    344 344   }
    345  - const stixObject = buildStixObject(instance);
    346  - return {
    347  - ...stixObject,
    348  - sequence: uuidv4()
    349  - };
     345 + return buildStixObject(instance);
    350 346  };
    351 347  // SDO
    352 348  const convertIdentityToStix = (instance: StoreEntity, type: string): SDO.StixIdentity => {
    skipped 1133 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/domain/user.js
    skipped 207 lines
    208 208  };
    209 209   
    210 210  export const roleDelete = async (context, user, roleId) => {
     211 + await roleSessionRefresh(context, user, roleId);
    211 212   await deleteElementById(context, user, roleId, ENTITY_TYPE_ROLE);
    212 213   logAudit.info(user, ROLE_DELETION, { id: roleId });
    213 214   return roleId;
    skipped 1 lines
    215 216   
    216 217  export const roleCleanContext = async (context, user, roleId) => {
    217 218   await delEditContext(user, roleId);
    218  - return storeLoadById(context, user, roleId, ENTITY_TYPE_ROLE).then((role) => notify(BUS_TOPICS[ENTITY_TYPE_ROLE].EDIT_TOPIC, role, user));
     219 + return storeLoadById(context, user, roleId, ENTITY_TYPE_ROLE).then((role) => {
     220 + return notify(BUS_TOPICS[ENTITY_TYPE_ROLE].EDIT_TOPIC, role, user);
     221 + });
    219 222  };
    220 223   
    221 224  export const roleEditContext = async (context, user, roleId, input) => {
    222 225   await setEditContext(user, roleId, input);
    223  - return storeLoadById(context, user, roleId, ENTITY_TYPE_ROLE).then((role) => notify(BUS_TOPICS[ENTITY_TYPE_ROLE].EDIT_TOPIC, role, user));
     226 + return storeLoadById(context, user, roleId, ENTITY_TYPE_ROLE).then((role) => {
     227 + return notify(BUS_TOPICS[ENTITY_TYPE_ROLE].EDIT_TOPIC, role, user);
     228 + });
    224 229  };
    225 230   
    226 231  const assignRoleToUser = async (context, user, userId, roleName) => {
    227 232   const generateToId = generateStandardId(ENTITY_TYPE_ROLE, { name: roleName });
    228  - // TODO Check is valid role
    229 233   const assignInput = {
    230 234   fromId: userId,
    231 235   toId: generateToId,
    skipped 3 lines
    235 239  };
    236 240   
    237 241  export const assignOrganizationToUser = async (context, user, userId, organizationId) => {
    238  - // TODO Check is valid organization
    239 242   const assignInput = { fromId: userId, toId: organizationId, relationship_type: RELATION_PARTICIPATE_TO };
    240 243   await createRelation(context, user, assignInput);
     244 + await userSessionRefresh(userId);
    241 245   return user;
    242 246  };
    243 247   
    skipped 4 lines
    248 252   toId: generateToId,
    249 253   relationship_type: RELATION_MEMBER_OF,
    250 254   };
    251  - return createRelation(context, user, assignInput);
     255 + const rel = await createRelation(context, user, assignInput);
     256 + await userSessionRefresh(userId);
     257 + return rel;
    252 258  };
    253 259   
    254 260  export const addUser = async (context, user, newUser) => {
    skipped 43 lines
    298 304   
    299 305  export const roleEditField = async (context, user, roleId, input) => {
    300 306   const { element } = await updateAttribute(context, user, roleId, ENTITY_TYPE_ROLE, input);
     307 + await roleSessionRefresh(context, user, roleId);
    301 308   return notify(BUS_TOPICS[ENTITY_TYPE_ROLE].EDIT_TOPIC, element, user);
    302 309  };
    303 310   
    skipped 148 lines
    452 459   await deleteRelationsByFromAndTo(context, user, userId, toId, RELATION_PARTICIPATE_TO, ABSTRACT_INTERNAL_RELATIONSHIP);
    453 460   const operation = convertRelationToAction(RELATION_PARTICIPATE_TO, false);
    454 461   logAudit.info(user, operation, { from: userId, to: toId, type: RELATION_PARTICIPATE_TO });
     462 + await userSessionRefresh(userId);
    455 463   return notify(BUS_TOPICS[ENTITY_TYPE_USER].EDIT_TOPIC, targetUser, user);
    456 464  };
    457 465   
    skipped 126 lines
    584 592   impersonate: impersonate !== undefined,
    585 593   capabilities: user.capabilities.map((c) => ({ id: c.id, internal_id: c.internal_id, name: c.name })),
    586 594   organizations: user.organizations,
     595 + allowed_organizations: user.allowed_organizations,
    587 596   inside_platform_organization: user.inside_platform_organization,
    588 597   allowed_marking: user.allowed_marking.map((m) => ({
    589 598   id: m.id,
    skipped 16 lines
    606 615   return undefined;
    607 616   }
    608 617   const settings = await getEntityFromCache(context, SYSTEM_USER, ENTITY_TYPE_SETTINGS);
    609  - const organizations = await batchOrganizations(context, SYSTEM_USER, client.id, { batched: false, paginate: false });
    610  - const userOrganizations = organizations.map((m) => m.internal_id);
     618 + const batchOpts = { batched: false, paginate: false };
     619 + const organizations = await batchOrganizations(context, SYSTEM_USER, client.id, { ...batchOpts, withInferences: false });
     620 + const allowed_organizations = await batchOrganizations(context, SYSTEM_USER, client.id, batchOpts);
     621 + const userOrganizations = allowed_organizations.map((m) => m.internal_id);
    611 622   const isUserPlatform = settings.platform_organization ? userOrganizations.includes(settings.platform_organization) : true;
    612 623   const capabilities = await getCapabilities(context, client.id, isUserPlatform);
    613 624   const marking = await getUserAndGlobalMarkings(context, client.id, capabilities);
    skipped 4 lines
    618 629   ...client,
    619 630   capabilities,
    620 631   organizations,
     632 + allowed_organizations,
    621 633   individual_id: individualId,
    622 634   inside_platform_organization: isUserPlatform,
    623 635   allowed_marking: marking.user,
    skipped 168 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/manager/taskManager.js
    skipped 279 lines
    280 280   if (!instance) {
    281 281   throw FunctionalError('Cant find element to scan', { id: element.internal_id });
    282 282   }
    283  - const event = buildCreateEvent(user, instance, '-', {});
     283 + const event = buildCreateEvent(user, instance, '-');
    284 284   await rulesApplyHandler(context, user, [event], [rule]);
    285 285  };
    286 286  const executeRuleClean = async (context, user, actionContext, element) => {
    skipped 33 lines
    320 320   const { values } = actionContext;
    321 321   for (let indexCreate = 0; indexCreate < values.length; indexCreate += 1) {
    322 322   const target = values[indexCreate];
    323  - await createRelation(context, user, { fromId: element.id, toId: target, relationship_type: RELATION_GRANTED_TO });
     323 + const currentGrants = element[buildRefRelationKey(RELATION_GRANTED_TO)] ?? [];
     324 + if (!currentGrants.includes(target)) {
     325 + await createRelation(context, user, { fromId: element.id, toId: target, relationship_type: RELATION_GRANTED_TO });
     326 + }
    324 327   }
    325 328  };
    326 329  const executeUnshare = async (context, user, actionContext, element) => {
    skipped 146 lines
  • ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/rules/rules.js
    skipped 45 lines
    46 46   roles: [{ name: ROLE_ADMINISTRATOR }],
    47 47   capabilities: [{ name: BYPASS }],
    48 48   organizations: [],
     49 + allowed_organizations: [],
    49 50   allowed_marking: [],
    50 51   all_marking: [],
    51 52  };
    skipped 17 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/schema/stixCoreObject.js
    skipped 2 lines
    3 3  import { isStixMetaObject } from './stixMetaObject';
    4 4  import { isInternalObject } from './internalObject';
    5 5  import { ABSTRACT_BASIC_OBJECT, ABSTRACT_STIX_CORE_OBJECT, ABSTRACT_STIX_OBJECT, buildRefRelationKey } from './general';
    6  -import { isStixRelationShipExceptMeta, isBasicRelationship } from './stixRelationship';
     6 +import { isBasicRelationship, isStixRelationShipExceptMeta } from './stixRelationship';
    7 7  import {
    8  - RELATION_CREATED_BY, RELATION_EXTERNAL_REFERENCE,
     8 + RELATION_CREATED_BY,
     9 + RELATION_EXTERNAL_REFERENCE,
    9 10   RELATION_OBJECT,
    10 11   RELATION_OBJECT_LABEL,
    11 12   RELATION_OBJECT_MARKING
    12 13  } from './stixMetaRelationship';
    13 14  import { RELATION_INDICATES } from './stixCoreRelationship';
     15 +import { RELATION_PARTICIPATE_TO } from './internalRelationship';
     16 + 
     17 +export const INTERNAL_EXPORTABLE_TYPES = [RELATION_PARTICIPATE_TO];
    14 18   
    15 19  export const isStixCoreObject = (type) => isStixDomainObject(type) || isStixCyberObservable(type) || type === ABSTRACT_STIX_CORE_OBJECT;
    16 20  export const isStixObject = (type) => isStixCoreObject(type) || isStixMetaObject(type) || type === ABSTRACT_STIX_OBJECT;
    17 21  export const isBasicObject = (type) => isInternalObject(type) || isStixObject(type) || type === ABSTRACT_BASIC_OBJECT;
    18  -export const isStixExportableData = (instance) => isStixObject(instance.entity_type) || isStixRelationShipExceptMeta(instance.entity_type);
     22 +export const isStixExportableData = (instance) => isStixObject(instance.entity_type)
     23 + || isStixRelationShipExceptMeta(instance.entity_type) || INTERNAL_EXPORTABLE_TYPES.includes(instance.entity_type);
    19 24  export const isBasicData = (instance) => isBasicObject(instance.entity_type) || isBasicRelationship(instance.entity_type);
    20 25   
    21 26  export const stixCoreObjectOptions = {
    skipped 15 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/types/event.d.ts
    skipped 7 lines
    8 8   references: Array<string>;
    9 9  }
    10 10   
    11  -interface CreateEventOpts {
    12  - withoutMessage?: boolean;
     11 +interface EventOpts {
    13 12   publishStreamEvent?: boolean;
    14 13  }
    15 14   
    16  -interface UpdateEventOpts {
    17  - commit?: CommitContext | undefined,
    18  - publishStreamEvent?: boolean;
     15 +interface CreateEventOpts extends EventOpts {
     16 + withoutMessage?: boolean;
    19 17  }
    20 18   
    21  -interface DeleteEventOpts {
    22  - publishStreamEvent?: boolean;
     19 +interface UpdateEventOpts extends EventOpts {
     20 + commit?: CommitContext | undefined;
    23 21  }
    24 22   
    25 23  interface RuleEvent {
    skipped 59 lines
  • ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/types/stix-common.d.ts
    skipped 3 lines
    4 4  import type { StixInternalExternalReference } from './stix-smo';
    5 5   
    6 6  type StixId = `${string}--${v4 | v5}`;
    7  -type StixFieldExtension = `${string}--${string}`;
    8 7   
    9 8  export enum OrganizationReliability {
    10 9   A = 'A',
    skipped 50 lines
    61 60   extensions: {
    62 61   [STIX_EXT_OCTI] : StixOpenctiExtension;
    63 62   };
    64  -}
    65  - 
    66  -interface StixInternalObject extends StixObject {
    67  - sequence: string;
    68 63  }
    69 64   
    70 65  // --- STIX Core Objects
    skipped 83 lines
  • ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/types/user.d.ts
    skipped 23 lines
    24 24   origin: Partial<UserOrigin>;
    25 25   roles: Array<UserRole>;
    26 26   organizations: Array<BasicStoreCommon>;
     27 + allowed_organizations: Array<BasicStoreCommon>;
    27 28   capabilities: Array<UserCapability>;
    28 29   allowed_marking: Array<StoreMarkingDefinition>;
    29 30   all_marking: Array<StoreMarkingDefinition>;
    skipped 7 lines
  • ■ ■ ■ ■ ■ ■
    opencti-platform/opencti-graphql/src/utils/access.ts
    skipped 56 lines
    57 57   roles: [{ name: ROLE_ADMINISTRATOR }],
    58 58   capabilities: [{ name: BYPASS }],
    59 59   organizations: [],
     60 + allowed_organizations: [],
    60 61   allowed_marking: [],
    61 62   all_marking: [],
    62 63  };
    skipped 8 lines
    71 72   roles: [{ name: ROLE_ADMINISTRATOR }],
    72 73   capabilities: [{ name: BYPASS }],
    73 74   organizations: [],
     75 + allowed_organizations: [],
    74 76   allowed_marking: [],
    75 77   all_marking: [],
    76 78  };
    skipped 39 lines
    116 118   }
    117 119   // Organizations
    118 120   const elementOrganizations = element[RELATION_GRANTED_TO] ?? [];
    119  - const userOrganizations = user.organizations.map((o) => o.internal_id);
     121 + const userOrganizations = user.allowed_organizations.map((o) => o.internal_id);
    120 122   if (settings.platform_organization) {
    121 123   if (user.inside_platform_organization) {
    122 124   return true;
    skipped 26 lines
    149 151   /// Organizations
    150 152   const settings = await getEntityFromCache<BasicStoreSettings>(context, user, ENTITY_TYPE_SETTINGS);
    151 153   const elementOrganizations = instance.extensions[STIX_EXT_OCTI].granted_refs ?? [];
    152  - const userOrganizations = user.organizations.map((o) => o.standard_id);
     154 + const userOrganizations = user.allowed_organizations.map((o) => o.standard_id);
    153 155   if (settings.platform_organization) {
    154 156   if (user.inside_platform_organization) {
    155 157   return true;
    skipped 6 lines
Please wait...
Page is in error, reload to recover