Skip to content

Commit 425f140

Browse files
author
Samuel Hassine
committed
[client] Fix updating created_by_ref of observable, introduce delete methods
1 parent 2224a05 commit 425f140

File tree

4 files changed

+138
-33
lines changed

4 files changed

+138
-33
lines changed

examples/import_stix2_file.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
from pycti import OpenCTIApiClient
44

55
# Variables
6-
api_url = "https://demo.opencti.io"
7-
api_token = "2b4f29e3-5ea8-4890-8cf5-a76f61f1e2b2"
6+
api_url = "http://localhost:4000"
7+
api_token = "0b23f787-d013-41a8-8078-97bee84cc99d"
88

99
# OpenCTI initialization
1010
opencti_api_client = OpenCTIApiClient(api_url, api_token)

pycti/entities/opencti_report.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ def add_stix_entity(self, **kwargs):
439439
if report is None:
440440
custom_attributes = """
441441
id
442-
objectRefs {
442+
objectRefs(first: 10000) {
443443
edges {
444444
node {
445445
id
@@ -448,7 +448,7 @@ def add_stix_entity(self, **kwargs):
448448
}
449449
}
450450
}
451-
relationRefs {
451+
relationRefs(first: 10000) {
452452
edges {
453453
node {
454454
id

pycti/entities/opencti_stix_observable.py

+124-1
Original file line numberDiff line numberDiff line change
@@ -374,5 +374,128 @@ def update_field(self, **kwargs):
374374
result["data"]["stixObservableEdit"]["fieldPatch"]
375375
)
376376
else:
377-
self.opencti.log("error", "Missing parameters: id and key and value")
377+
self.opencti.log("error", "[opencti_stix_observable_update_field] Missing parameters: id and key and value")
378378
return None
379+
380+
"""
381+
Delete a Stix-Observable
382+
383+
:param id: the Stix-Observable id
384+
:return void
385+
"""
386+
387+
def delete(self, **kwargs):
388+
id = kwargs.get("id", None)
389+
if id is not None:
390+
self.opencti.log("info", "Deleting Stix-Observable {" + id + "}.")
391+
query = """
392+
mutation StixObservableEdit($id: ID!) {
393+
stixObservableEdit(id: $id) {
394+
delete
395+
}
396+
}
397+
"""
398+
self.opencti.query(query, {"id": id})
399+
else:
400+
self.opencti.log(
401+
"error", "[opencti_stix_observable_delete] Missing parameters: id"
402+
)
403+
return None
404+
405+
"""
406+
Update the Identity author of a Stix-Observable object (created_by_ref)
407+
408+
:param id: the id of the Stix-Observable
409+
:param identity_id: the id of the Identity
410+
:return Boolean
411+
"""
412+
413+
def update_created_by_ref(self, **kwargs):
414+
id = kwargs.get("id", None)
415+
stix_entity = kwargs.get("entity", None)
416+
identity_id = kwargs.get("identity_id", None)
417+
if id is not None and identity_id is not None:
418+
if stix_entity is None:
419+
custom_attributes = """
420+
id
421+
createdByRef {
422+
node {
423+
id
424+
entity_type
425+
stix_id_key
426+
stix_label
427+
name
428+
alias
429+
description
430+
created
431+
modified
432+
... on Organization {
433+
organization_class
434+
}
435+
}
436+
relation {
437+
id
438+
}
439+
}
440+
"""
441+
stix_entity = self.read(id=id, customAttributes=custom_attributes)
442+
if stix_entity is None:
443+
self.opencti.log(
444+
"error", "Cannot update created_by_ref, entity not found"
445+
)
446+
return False
447+
current_identity_id = None
448+
current_relation_id = None
449+
if stix_entity["createdByRef"] is not None:
450+
current_identity_id = stix_entity["createdByRef"]["id"]
451+
current_relation_id = stix_entity["createdByRef"]["remote_relation_id"]
452+
# Current identity is the same
453+
if current_identity_id == identity_id:
454+
return True
455+
else:
456+
self.opencti.log(
457+
"info",
458+
"Updating author of Stix-Entity {"
459+
+ id
460+
+ "} with Identity {"
461+
+ identity_id
462+
+ "}",
463+
)
464+
# Current identity is different, delete the old relation
465+
if current_relation_id is not None:
466+
query = """
467+
mutation StixObservableEdit($id: ID!, $relationId: ID!) {
468+
stixObservableEdit(id: $id) {
469+
relationDelete(relationId: $relationId) {
470+
id
471+
}
472+
}
473+
}
474+
"""
475+
self.opencti.query(
476+
query, {"id": id, "relationId": current_relation_id}
477+
)
478+
# Add the new relation
479+
query = """
480+
mutation StixObservableEdit($id: ID!, $input: RelationAddInput) {
481+
stixObservableEdit(id: $id) {
482+
relationAdd(input: $input) {
483+
id
484+
}
485+
}
486+
}
487+
"""
488+
variables = {
489+
"id": id,
490+
"input": {
491+
"fromRole": "so",
492+
"toId": identity_id,
493+
"toRole": "creator",
494+
"through": "created_by_ref",
495+
},
496+
}
497+
self.opencti.query(query, variables)
498+
499+
else:
500+
self.opencti.log("error", "Missing parameters: id and identity_id")
501+
return False

pycti/utils/opencti_stix2.py

+10-28
Original file line numberDiff line numberDiff line change
@@ -445,30 +445,6 @@ def import_object(self, stix_object, update=False, types=None):
445445
else [],
446446
}
447447

448-
# Update created by ref
449-
if (
450-
created_by_ref_id is not None
451-
and "observableRefs" in stix_object_result
452-
and stix_object_result["observableRefs"] is not None
453-
and len(stix_object_result["observableRefs"]) > 0
454-
):
455-
for observable_ref in stix_object_result["observableRefs"]:
456-
self.opencti.stix_entity.update_created_by_ref(
457-
id=observable_ref["id"], identity_id=created_by_ref_id
458-
)
459-
460-
# Add marking definitions
461-
for marking_definition_id in marking_definitions_ids:
462-
if (
463-
"observableRefs" in stix_object_result
464-
and stix_object_result["observableRefs"] is not None
465-
and len(stix_object_result["observableRefs"]) > 0
466-
):
467-
for observable_ref in stix_object_result["observableRefs"]:
468-
self.opencti.stix_entity.add_marking_definition(
469-
id=observable_ref["id"],
470-
marking_definition_id=marking_definition_id,
471-
)
472448
# Add tags
473449
for tag_id in tags_ids:
474450
self.opencti.stix_entity.add_tag(
@@ -1290,7 +1266,6 @@ def prepare_export(
12901266
if entity_relation_ref["stix_id_key"] not in object_refs:
12911267
object_refs.append(entity_relation_ref["stix_id_key"])
12921268
stix_object["object_refs"] = object_refs
1293-
result.append(stix_object)
12941269

12951270
uuids = []
12961271
for x in result:
@@ -1309,6 +1284,12 @@ def prepare_export(
13091284
observables_stix_ids = (
13101285
observables_stix_ids + observable_object_data["stixIds"]
13111286
)
1287+
if stix_object['type'] == 'report':
1288+
if 'object_refs' in stix_object:
1289+
stix_object['object_refs'].append(observable_object_data['observedData']['id'])
1290+
else:
1291+
stix_object['object_refs'] = [observable_object_data['observedData']['id']]
1292+
result.append(stix_object)
13121293

13131294
if mode == "simple":
13141295
return result
@@ -1406,9 +1387,10 @@ def prepare_export(
14061387
final_result = []
14071388
for entity in result:
14081389
if entity["type"] == "report":
1409-
entity["object_refs"] = [
1410-
k for k in entity["object_refs"] if k in uuids
1411-
]
1390+
if 'object_refs' in entity:
1391+
entity["object_refs"] = [
1392+
k for k in entity["object_refs"] if k in uuids
1393+
]
14121394
final_result.append(entity)
14131395
else:
14141396
final_result.append(entity)

0 commit comments

Comments
 (0)