Skip to content
This repository was archived by the owner on Dec 5, 2025. It is now read-only.

Commit ac4fccd

Browse files
[client] Add helpers for background tasks in worker execution (opencti #10274)
Co-authored-by: Julien Richard <[email protected]>
1 parent 111858d commit ac4fccd

15 files changed

+598
-11
lines changed

pycti/api/opencti_api_client.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@
1010

1111
from pycti import __version__
1212
from pycti.api.opencti_api_connector import OpenCTIApiConnector
13+
from pycti.api.opencti_api_draft import OpenCTIApiDraft
1314
from pycti.api.opencti_api_pir import OpenCTIApiPir
1415
from pycti.api.opencti_api_playbook import OpenCTIApiPlaybook
16+
from pycti.api.opencti_api_public_dashboard import OpenCTIApiPublicDashboard
17+
from pycti.api.opencti_api_trash import OpenCTIApiTrash
1518
from pycti.api.opencti_api_work import OpenCTIApiWork
19+
from pycti.api.opencti_api_workspace import OpenCTIApiWorkspace
1620
from pycti.entities.opencti_attack_pattern import AttackPattern
1721
from pycti.entities.opencti_campaign import Campaign
1822
from pycti.entities.opencti_capability import Capability
@@ -168,6 +172,10 @@ def __init__(
168172
self.session = requests.session()
169173
# Define the dependencies
170174
self.work = OpenCTIApiWork(self)
175+
self.trash = OpenCTIApiTrash(self)
176+
self.draft = OpenCTIApiDraft(self)
177+
self.workspace = OpenCTIApiWorkspace(self)
178+
self.public_dashboard = OpenCTIApiPublicDashboard(self)
171179
self.playbook = OpenCTIApiPlaybook(self)
172180
self.connector = OpenCTIApiConnector(self)
173181
self.stix2 = OpenCTIStix2(self)

pycti/api/opencti_api_draft.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class OpenCTIApiDraft:
2+
"""OpenCTIApiDraft"""
3+
4+
def __init__(self, api):
5+
self.api = api
6+
7+
def delete(self, **kwargs):
8+
id = kwargs.get("id", None)
9+
query = """
10+
mutation DraftWorkspaceDelete($id: ID!) {
11+
draftWorkspaceDelete(id: $id)
12+
}
13+
"""
14+
self.api.query(
15+
query,
16+
{
17+
"id": id,
18+
},
19+
)

pycti/api/opencti_api_playbook.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,23 @@ def playbook_step_execution(self, playbook: dict, bundle: str):
3232
"bundle": bundle,
3333
},
3434
)
35+
36+
def delete(self, **kwargs):
37+
id = kwargs.get("id", None)
38+
if id is not None:
39+
query = """
40+
mutation PlaybookDelete($id: ID!) {
41+
playbookDelete(id: $id)
42+
}
43+
"""
44+
self.api.query(
45+
query,
46+
{
47+
"id": id,
48+
},
49+
)
50+
else:
51+
self.opencti.app_logger.error(
52+
"[stix_playbook] Cant delete playbook, missing parameters: id"
53+
)
54+
return None
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class OpenCTIApiPublicDashboard:
2+
"""OpenCTIApiPublicDashboard"""
3+
4+
def __init__(self, api):
5+
self.api = api
6+
7+
def delete(self, **kwargs):
8+
id = kwargs.get("id", None)
9+
if id is not None:
10+
query = """
11+
mutation PublicDashboardDelete($id: ID!) {
12+
publicDashboardDelete(id: $id)
13+
}
14+
"""
15+
self.api.query(
16+
query,
17+
{
18+
"id": id,
19+
},
20+
)
21+
else:
22+
self.opencti.app_logger.error(
23+
"[stix_public_dashboard] Cant delete public dashboard, missing parameters: id"
24+
)
25+
return None

pycti/api/opencti_api_trash.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
class OpenCTIApiTrash:
2+
"""OpenCTIApiTrash"""
3+
4+
def __init__(self, api):
5+
self.api = api
6+
7+
def restore(self, operation_id: str):
8+
query = """
9+
mutation DeleteOperationRestore($id: ID!) {
10+
deleteOperationRestore(id: $id)
11+
}
12+
"""
13+
self.api.query(
14+
query,
15+
{
16+
"id": operation_id,
17+
},
18+
)
19+
20+
def delete(self, **kwargs):
21+
"""Delete a trash item given its ID
22+
23+
:param id: ID for the delete operation on the platform.
24+
:type id: str
25+
"""
26+
id = kwargs.get("id", None)
27+
if id is None:
28+
self.api.admin_logger.error(
29+
"[opencti_trash] Cant confirm delete, missing parameter: id"
30+
)
31+
return None
32+
query = """
33+
mutation DeleteOperationConfirm($id: ID!) {
34+
deleteOperationConfirm(id: $id)
35+
}
36+
"""
37+
self.api.query(
38+
query,
39+
{
40+
"id": id,
41+
},
42+
)

pycti/api/opencti_api_work.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,25 @@ def delete_work(self, work_id: str):
131131
work = self.api.query(query, {"workId": work_id}, True)
132132
return work["data"]
133133

134+
def delete(self, **kwargs):
135+
id = kwargs.get("id", None)
136+
if id is None:
137+
self.opencti.admin_logger.error(
138+
"[opencti_work] Cant delete work, missing parameter: id"
139+
)
140+
return None
141+
query = """
142+
mutation ConnectorWorksMutation($workId: ID!) {
143+
workEdit(id: $workId) {
144+
delete
145+
}
146+
}"""
147+
work = self.api.query(
148+
query,
149+
{"workId": id},
150+
)
151+
return work["data"]
152+
134153
def wait_for_work_to_finish(self, work_id: str):
135154
status = ""
136155
cnt = 0

pycti/api/opencti_api_workspace.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class OpenCTIApiWorkspace:
2+
"""OpenCTIApiWorkspace"""
3+
4+
def __init__(self, api):
5+
self.api = api
6+
7+
def delete(self, **kwargs):
8+
id = kwargs.get("id", None)
9+
if id is None:
10+
self.api.admin_logger.error(
11+
"[opencti_workspace] Cant delete workspace, missing parameter: id"
12+
)
13+
return None
14+
query = """
15+
mutation WorkspaceDelete($id: ID!) {
16+
workspaceDelete(id: $id)
17+
}
18+
"""
19+
self.api.query(
20+
query,
21+
{
22+
"id": id,
23+
},
24+
)

pycti/entities/opencti_group.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,18 @@ def create(self, **kwargs) -> Optional[Dict]:
315315
)
316316
return self.opencti.process_multiple_fields(result["data"]["groupAdd"])
317317

318-
def delete(self, id: str):
318+
def delete(self, **kwargs):
319319
"""Delete a given group from OpenCTI
320320
321321
:param id: ID of the group to delete.
322322
:type id: str
323323
"""
324+
id = kwargs.get("id", None)
325+
if id is None:
326+
self.opencti.admin_logger.error(
327+
"[opencti_group] Cant delete group, missing parameter: id"
328+
)
329+
return None
324330
self.opencti.admin_logger.info("Deleting group", {"id": id})
325331
query = """
326332
mutation GroupDelete($id: ID!) {

pycti/entities/opencti_indicator.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,43 @@ def create(self, **kwargs):
301301
"name or pattern or pattern_type or x_opencti_main_observable_type"
302302
)
303303

304+
"""
305+
Update an Indicator object field
306+
307+
:param id: the Indicator id
308+
:param input: the input of the field
309+
"""
310+
311+
def update_field(self, **kwargs):
312+
id = kwargs.get("id", None)
313+
input = kwargs.get("input", None)
314+
if id is not None and input is not None:
315+
self.opencti.app_logger.info("Updating Indicator", {"id": id})
316+
query = """
317+
mutation IndicatorFieldPatch($id: ID!, $input: [EditInput!]!) {
318+
indicatorFieldPatch(id: $id, input: $input) {
319+
id
320+
standard_id
321+
entity_type
322+
}
323+
}
324+
"""
325+
result = self.opencti.query(
326+
query,
327+
{
328+
"id": id,
329+
"input": input,
330+
},
331+
)
332+
return self.opencti.process_multiple_fields(
333+
result["data"]["indicatorFieldPatch"]
334+
)
335+
else:
336+
self.opencti.app_logger.error(
337+
"[opencti_stix_domain_object] Cant update indicator field, missing parameters: id and input"
338+
)
339+
return None
340+
304341
def add_stix_cyber_observable(self, **kwargs):
305342
"""
306343
Add a Stix-Cyber-Observable object to Indicator object (based-on)

pycti/entities/opencti_stix.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,17 @@ def __init__(self, opencti):
1111

1212
def delete(self, **kwargs):
1313
id = kwargs.get("id", None)
14+
force_delete = kwargs.get("force_delete", True)
1415
if id is not None:
1516
self.opencti.app_logger.info("Deleting Stix element", {"id": id})
1617
query = """
17-
mutation StixEdit($id: ID!) {
18+
mutation StixEdit($id: ID!, $forceDelete: Boolean) {
1819
stixEdit(id: $id) {
19-
delete
20+
delete(forceDelete: $forceDelete)
2021
}
2122
}
2223
"""
23-
self.opencti.query(query, {"id": id})
24+
self.opencti.query(query, {"id": id, "forceDelete": force_delete})
2425
else:
2526
self.opencti.app_logger.error("[opencti_stix] Missing parameters: id")
2627
return None

0 commit comments

Comments
 (0)