pycti 6.8.6__py3-none-any.whl → 6.8.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pycti might be problematic. Click here for more details.

pycti/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
- __version__ = "6.8.6"
2
+ __version__ = "6.8.8"
3
3
 
4
4
  from .api.opencti_api_client import OpenCTIApiClient
5
5
  from .api.opencti_api_connector import OpenCTIApiConnector
@@ -79,6 +79,7 @@ class OpenCTIApiConnector:
79
79
  push
80
80
  push_exchange
81
81
  push_routing
82
+ dead_letter_routing
82
83
  }
83
84
  }
84
85
  }
@@ -204,6 +204,15 @@ class OpenCTIApiWork:
204
204
  result = self.api.query(query, {"id": work_id}, True)
205
205
  return result["data"]["work"]
206
206
 
207
+ def get_is_work_alive(self, work_id: str) -> Dict:
208
+ query = """
209
+ query WorkAliveQuery($id: ID!) {
210
+ isWorkAlive(id: $id)
211
+ }
212
+ """
213
+ result = self.api.query(query, {"id": work_id}, True)
214
+ return result["data"]["isWorkAlive"]
215
+
207
216
  def get_connector_works(self, connector_id: str) -> List[Dict]:
208
217
  query = """
209
218
  query ConnectorWorksQuery(
@@ -707,6 +707,7 @@ class CaseIncident:
707
707
  modified = kwargs.get("modified", None)
708
708
  name = kwargs.get("name", None)
709
709
  description = kwargs.get("description", None)
710
+ content = kwargs.get("content", None)
710
711
  severity = kwargs.get("severity", None)
711
712
  priority = kwargs.get("priority", None)
712
713
  x_opencti_stix_ids = kwargs.get("x_opencti_stix_ids", None)
@@ -749,6 +750,7 @@ class CaseIncident:
749
750
  "modified": modified,
750
751
  "name": name,
751
752
  "description": description,
753
+ "content": content,
752
754
  "severity": severity,
753
755
  "priority": priority,
754
756
  "x_opencti_stix_ids": x_opencti_stix_ids,
@@ -884,6 +886,12 @@ class CaseIncident:
884
886
  stix_object["x_opencti_workflow_id"] = (
885
887
  self.opencti.get_attribute_in_extension("workflow_id", stix_object)
886
888
  )
889
+ if "x_opencti_content" not in stix_object or "content" not in stix_object:
890
+ stix_object["content"] = self.opencti.get_attribute_in_extension(
891
+ "content", stix_object
892
+ )
893
+ if "x_opencti_content" in stix_object:
894
+ stix_object["content"] = stix_object["x_opencti_content"]
887
895
  if "x_opencti_assignee_ids" not in stix_object:
888
896
  stix_object["x_opencti_assignee_ids"] = (
889
897
  self.opencti.get_attribute_in_extension("assignee_ids", stix_object)
@@ -926,6 +934,11 @@ class CaseIncident:
926
934
  if "description" in stix_object
927
935
  else None
928
936
  ),
937
+ content=(
938
+ self.opencti.stix2.convert_markdown(stix_object["content"])
939
+ if "content" in stix_object
940
+ else None
941
+ ),
929
942
  severity=stix_object["severity"] if "severity" in stix_object else None,
930
943
  priority=stix_object["priority"] if "priority" in stix_object else None,
931
944
  response_types=(
@@ -8,7 +8,7 @@ import random
8
8
  import time
9
9
  import traceback
10
10
  import uuid
11
- from typing import Any, Dict, List, Optional, Union
11
+ from typing import Any, Dict, List, Optional, Tuple, Union
12
12
 
13
13
  import datefinder
14
14
  import dateutil.parser
@@ -32,6 +32,7 @@ from pycti.utils.opencti_stix2_utils import (
32
32
  STIX_CORE_OBJECTS,
33
33
  STIX_CYBER_OBSERVABLE_MAPPING,
34
34
  STIX_META_OBJECTS,
35
+ OpenCTIStix2Utils,
35
36
  )
36
37
 
37
38
  datefinder.ValueError = ValueError, OverflowError
@@ -196,7 +197,7 @@ class OpenCTIStix2:
196
197
  file_path: str,
197
198
  update: bool = False,
198
199
  types: List = None,
199
- ) -> Optional[List]:
200
+ ) -> Optional[Tuple[list, list]]:
200
201
  """import a stix2 bundle from a file
201
202
 
202
203
  :param file_path: valid path to the file
@@ -221,7 +222,8 @@ class OpenCTIStix2:
221
222
  update: bool = False,
222
223
  types: List = None,
223
224
  work_id: str = None,
224
- ) -> List:
225
+ objects_max_refs: int = 0,
226
+ ) -> Tuple[list, list]:
225
227
  """import a stix2 bundle from JSON data
226
228
 
227
229
  :param json_data: JSON data
@@ -231,11 +233,13 @@ class OpenCTIStix2:
231
233
  :param types: list of stix2 types, defaults to None
232
234
  :type types: list, optional
233
235
  :param work_id work_id: str, optional
234
- :return: list of imported stix2 objects
235
- :rtype: List
236
+ :param objects_max_refs: max deps amount of objects, reject object import if larger than configured amount
237
+ :type objects_max_refs: int, optional
238
+ :return: list of imported stix2 objects and a list of stix2 objects with too many deps
239
+ :rtype: Tuple[List,List]
236
240
  """
237
241
  data = json.loads(json_data)
238
- return self.import_bundle(data, update, types, work_id)
242
+ return self.import_bundle(data, update, types, work_id, objects_max_refs)
239
243
 
240
244
  def resolve_author(self, title: str) -> Optional[Identity]:
241
245
  if "fireeye" in title.lower() or "mandiant" in title.lower():
@@ -3060,7 +3064,8 @@ class OpenCTIStix2:
3060
3064
  update: bool = False,
3061
3065
  types: List = None,
3062
3066
  work_id: str = None,
3063
- ) -> List:
3067
+ objects_max_refs: int = 0,
3068
+ ) -> Tuple[list, list]:
3064
3069
  # Check if the bundle is correctly formatted
3065
3070
  if "type" not in stix_bundle or stix_bundle["type"] != "bundle":
3066
3071
  raise ValueError("JSON data type is not a STIX2 bundle")
@@ -3094,12 +3099,27 @@ class OpenCTIStix2:
3094
3099
 
3095
3100
  # Import every element in a specific order
3096
3101
  imported_elements = []
3102
+ too_large_elements_bundles = []
3097
3103
  for bundle in bundles:
3098
3104
  for item in bundle["objects"]:
3099
- self.import_item(item, update, types, 0, work_id)
3100
- imported_elements.append({"id": item["id"], "type": item["type"]})
3105
+ # If item is considered too large, meaning that it has a number of refs higher than inputted objects_max_refs, do not import it
3106
+ nb_refs = OpenCTIStix2Utils.compute_object_refs_number(item)
3107
+ if 0 < objects_max_refs <= nb_refs:
3108
+ self.opencti.work.report_expectation(
3109
+ work_id,
3110
+ {
3111
+ "error": "Too large element in bundle",
3112
+ "source": "Element "
3113
+ + item["id"]
3114
+ + " is too large and couldn't be processed",
3115
+ },
3116
+ )
3117
+ too_large_elements_bundles.append(item)
3118
+ else:
3119
+ self.import_item(item, update, types, 0, work_id)
3120
+ imported_elements.append({"id": item["id"], "type": item["type"]})
3101
3121
 
3102
- return imported_elements
3122
+ return imported_elements, too_large_elements_bundles
3103
3123
 
3104
3124
  @staticmethod
3105
3125
  def put_attribute_in_extension(
@@ -196,6 +196,7 @@ class OpenCTIStix2Splitter:
196
196
  )
197
197
  else:
198
198
  is_compatible = is_id_supported(item_id)
199
+
199
200
  if is_compatible:
200
201
  self.elements.append(item)
201
202
  else:
@@ -262,7 +263,11 @@ class OpenCTIStix2Splitter:
262
263
  )
263
264
  )
264
265
 
265
- return number_expectations, self.incompatible_items, bundles
266
+ return (
267
+ number_expectations,
268
+ self.incompatible_items,
269
+ bundles,
270
+ )
266
271
 
267
272
  @deprecated("Use split_bundle_with_expectations instead")
268
273
  def split_bundle(self, bundle, use_json=True, event_version=None) -> list:
@@ -233,3 +233,17 @@ class OpenCTIStix2Utils:
233
233
  if hasattr(attribute, method):
234
234
  return attribute
235
235
  return None
236
+
237
+ @staticmethod
238
+ def compute_object_refs_number(entity: Dict):
239
+ refs_number = 0
240
+ for key in list(entity.keys()):
241
+ if key.endswith("_refs") and entity[key] is not None:
242
+ refs_number += len(entity[key])
243
+ elif key.endswith("_ref"):
244
+ refs_number += 1
245
+ elif key == "external_references" and entity[key] is not None:
246
+ refs_number += len(entity[key])
247
+ elif key == "kill_chain_phases" and entity[key] is not None:
248
+ refs_number += len(entity[key])
249
+ return refs_number
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycti
3
- Version: 6.8.6
3
+ Version: 6.8.8
4
4
  Summary: Python API client for OpenCTI.
5
5
  Home-page: https://github.com/OpenCTI-Platform/client-python
6
6
  Author: Filigran
@@ -1,7 +1,7 @@
1
- pycti/__init__.py,sha256=RmMRMV_0c9FhoOOlFN7CRNHh2wKSMdbI0N02SyXsQ7U,5676
1
+ pycti/__init__.py,sha256=5LvHzMfpp2PQ9_yBONK0Dcej_TnePHuDpK_uwzwt4S4,5676
2
2
  pycti/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  pycti/api/opencti_api_client.py,sha256=lbygp2fOsmTKIrM-8Y7GxFzCZzdFStC0dhxyKYs0Wzo,35368
4
- pycti/api/opencti_api_connector.py,sha256=8xwHuLINP3ZCImzE9_K_iCR9QEA3K6aHpK4bJhcZf20,5582
4
+ pycti/api/opencti_api_connector.py,sha256=MbOHtU9uQy6v_cI7bph9gZYGnpTaJlyTFnvP1bConuk,5626
5
5
  pycti/api/opencti_api_draft.py,sha256=ZFrva6p7VZA7rCtIpyfyA-KTWvcTaWvpy51_Edi9rG4,428
6
6
  pycti/api/opencti_api_internal_file.py,sha256=v_IFGZC3tngrZiaf9K64lnJbQgczgjym2NUECmdV_jk,802
7
7
  pycti/api/opencti_api_notification.py,sha256=uTBSjym2RfSYHTnfBIVmWj5kATrzQ2lRQ178Jy5bsu0,1375
@@ -9,7 +9,7 @@ pycti/api/opencti_api_pir.py,sha256=3yDfUNVe9G_G9OrCcL3pBTE31kcstKXhXCiSrGhpUYY,
9
9
  pycti/api/opencti_api_playbook.py,sha256=yKg54sRaE4gtmQURQ_7jFjcyQJqchWsn-Uepe6MZUfs,2183
10
10
  pycti/api/opencti_api_public_dashboard.py,sha256=aa4trEuaf7WstmiS4WAHoe1qmYmaFWmbO0N4N_iXPGM,711
11
11
  pycti/api/opencti_api_trash.py,sha256=r_zi57n5TfLw9LYs2UFg33Nvyy3Huc6CjpK2mRQsmao,1065
12
- pycti/api/opencti_api_work.py,sha256=uV1mbPz3zmNZjoNHVmX6SyWPQKEHkpSDXkb_a2NIOA4,8982
12
+ pycti/api/opencti_api_work.py,sha256=IucltT8DcZtJV3NO4RbVi6tnGtjbyxD78_FIHAPYmK0,9261
13
13
  pycti/api/opencti_api_workspace.py,sha256=ycqOTEXeUHF2k8H4jhoYDd1W6ijFcNUjYf4eSdLpH0k,611
14
14
  pycti/connector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  pycti/connector/opencti_connector.py,sha256=8lCZFvcA9-S1x6vFl756hgWAlzKfrnq-C4AIdDJr-Kg,2715
@@ -19,7 +19,7 @@ pycti/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  pycti/entities/opencti_attack_pattern.py,sha256=Mf5ltnxG5XIgMdaplhSBFhuMBwsjGFZvkfhTX7jpTOw,23580
20
20
  pycti/entities/opencti_campaign.py,sha256=MhkzqwMsu1w9VnOUHq4dQVViLh6KeAAI3YmLOAqJYhg,18969
21
21
  pycti/entities/opencti_capability.py,sha256=mAR3AT__w6ULuAgc4T_QYxDwW9Jz8bsXQ8SDKF2BCL4,1515
22
- pycti/entities/opencti_case_incident.py,sha256=GESR5355ED9jE83uDNVTKsWJF2ClU9L53mMX_--3Nd0,34937
22
+ pycti/entities/opencti_case_incident.py,sha256=vM-MEdgPMOb-DRRSuf9buV71qr87gXSfiKxf5eemZrw,35585
23
23
  pycti/entities/opencti_case_rfi.py,sha256=0pcujjHV5xbysASPXDceQVkuRS77Gl97HI6ron7XhkU,35251
24
24
  pycti/entities/opencti_case_rft.py,sha256=eai_CkcEEl2NquhfJOhGoyUii92CITkQR8YfkDP6fgY,36171
25
25
  pycti/entities/opencti_channel.py,sha256=zBb9YzpNCWrC1lx8b3q8X9Xif7ijlJXqwxoXge_Z-14,16891
@@ -74,13 +74,13 @@ pycti/entities/stix_cyber_observable/opencti_stix_cyber_observable_properties.py
74
74
  pycti/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
75
  pycti/utils/constants.py,sha256=VRYRvDm6hkTR0ZcHHWMzQBwqlPRskYnusBpgoX0S05A,12854
76
76
  pycti/utils/opencti_logger.py,sha256=MApWthWJrSeBI0rumnhLhBtanjrtmfP6PJqOiQjcCOY,4091
77
- pycti/utils/opencti_stix2.py,sha256=nBBZ4kN1tds6rkd-z4LUuUsaLMIBzWt4WYaipbm_PVs,135837
77
+ pycti/utils/opencti_stix2.py,sha256=Pu7bGrlRVeYcp1Qtta6D6NHhxH5klJKALZKFrjps4hM,137042
78
78
  pycti/utils/opencti_stix2_identifier.py,sha256=k8L1z4q1xdCBfxqUba4YS_kT-MmbJFxYh0RvfGOmrOs,837
79
- pycti/utils/opencti_stix2_splitter.py,sha256=wOOgPM5FYYbCEhFAg9om54AzyNRwK_RzocsJJ6kViqY,11489
79
+ pycti/utils/opencti_stix2_splitter.py,sha256=nMGbFPtGz2Vaeb6asWyPiOntHFNjREzJnbLEJHDV_T0,11539
80
80
  pycti/utils/opencti_stix2_update.py,sha256=CnMyqkeVA0jgyxEcgqna8sABU4YPMjkEJ228GVurIn4,14658
81
- pycti/utils/opencti_stix2_utils.py,sha256=10CF7ip1XEURyd6EUMDpBHPQvmi5uGUxh1QDOw6LKJk,6955
82
- pycti-6.8.6.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
83
- pycti-6.8.6.dist-info/METADATA,sha256=fjVMkY90N5znQZiqNXTuorkUiNwdfVzCh427EO5IzkQ,5808
84
- pycti-6.8.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
85
- pycti-6.8.6.dist-info/top_level.txt,sha256=cqEpxitAhHP4VgSA6xmrak6Yk9MeBkwoMTB6k7d2ZnE,6
86
- pycti-6.8.6.dist-info/RECORD,,
81
+ pycti/utils/opencti_stix2_utils.py,sha256=fV-BHI55UF8tF6Ar9WHCqWy1mFPBZOph9bPlqHyA6W0,7545
82
+ pycti-6.8.8.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
83
+ pycti-6.8.8.dist-info/METADATA,sha256=gCpB8nxmgWc0e35p6rySTph_lBvk2MCyFogQko1bMaM,5808
84
+ pycti-6.8.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
85
+ pycti-6.8.8.dist-info/top_level.txt,sha256=cqEpxitAhHP4VgSA6xmrak6Yk9MeBkwoMTB6k7d2ZnE,6
86
+ pycti-6.8.8.dist-info/RECORD,,
File without changes