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

Commit b6f0392

Browse files
author
Samuel Hassine
authored
[client] Implement methods for export/import, upgrade with connectors helpers, handle update (#22,#24,#25)
* Implement graphql file upload specification using multipart * Adding support for multiple uploads at the same time * Adapt mutation to push export file * Adapating helper to rely on API * Improve helper * Refactoring client api to introduce connectors needs * Update all entities if the entity already exists and update is True * Add the init file and enhance upgrading entities * Update version number for next release * Introduce keys for internal_id and stix_id to avoid race conditions * Adapt helper for now reporting jobs. Add capacity for observable localization relations * Adapt job api for internal key and remove city api * Prepare relation to relation
1 parent ee39a54 commit b6f0392

File tree

10 files changed

+1028
-638
lines changed

10 files changed

+1028
-638
lines changed

pycti/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
from .opencti_api_client import OpenCTIApiClient
2-
from .opencti_connector_helper import OpenCTIConnectorHelper
1+
from api.opencti_api_client import OpenCTIApiClient
2+
from connector.opencti_connector_helper import OpenCTIConnectorHelper
Lines changed: 470 additions & 312 deletions
Large diffs are not rendered by default.

pycti/api/opencti_api_connector.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import logging
2+
3+
from connector.opencti_connector import OpenCTIConnector
4+
5+
6+
class OpenCTIApiConnector:
7+
8+
def __init__(self, api):
9+
self.api = api
10+
11+
def list(self):
12+
logging.info('Getting connectors ...')
13+
query = """
14+
query GetConnectors {
15+
connectors {
16+
id
17+
name
18+
config {
19+
uri
20+
listen
21+
push
22+
}
23+
}
24+
}
25+
"""
26+
result = self.api.query(query)
27+
return result['data']['connectors']
28+
29+
def ping(self, connector_id):
30+
query = """
31+
mutation PingConnector($id: ID!) {
32+
pingConnector(id: $id) {
33+
id
34+
}
35+
}
36+
"""
37+
self.api.query(query, {'id': connector_id})
38+
39+
def register(self, connector: OpenCTIConnector):
40+
query = """
41+
mutation RegisterConnector($input: RegisterConnectorInput) {
42+
registerConnector(input: $input) {
43+
id
44+
config {
45+
uri
46+
listen
47+
listen_exchange
48+
push
49+
push_exchange
50+
}
51+
}
52+
}
53+
"""
54+
result = self.api.query(query, connector.to_input())
55+
return result['data']['registerConnector']
56+

pycti/api/opencti_api_job.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import logging
2+
3+
4+
class OpenCTIApiJob:
5+
6+
def __init__(self, api):
7+
self.api = api
8+
9+
def update_job(self, job_id: str, status: str, messages: [str]):
10+
logging.info('Reporting job ' + job_id + ' with status ' + status + '...')
11+
query = """
12+
mutation UpdateJob($id: ID!, $status: Status!, $messages: [String]) {
13+
updateJob(jobId: $id, status: $status, messages: $messages) {
14+
internal_id_key
15+
}
16+
}
17+
"""
18+
result = self.api.query(query, {'id': job_id, 'status': status, 'messages': messages})
19+
return result['data']['updateJob']['internal_id_key']
20+
21+
def initiate_job(self, work_id: str):
22+
logging.info('Creating new job on work ' + work_id)
23+
query = """
24+
mutation InitiateJob($id: ID!) {
25+
initiateJob(workId: $id) {
26+
internal_id_key
27+
}
28+
}
29+
"""
30+
result = self.api.query(query, {'id': work_id})
31+
return result['data']['initiateJob']['internal_id_key']
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from enum import Enum
2+
3+
# Scope definition
4+
# EXTERNAL_IMPORT = None
5+
# INTERNAL_IMPORT_FILE = Files mime types to support (application/json, ...)
6+
# INTERNAL_ENRICHMENT = Entity types to support (Report, Hash, ...)
7+
# INTERNAL_EXPORT_FILE = Files mime types to generate (application/pdf, ...)
8+
9+
10+
class ConnectorType(Enum):
11+
EXTERNAL_IMPORT = 'EXTERNAL_IMPORT' # From remote sources to OpenCTI stix2
12+
INTERNAL_IMPORT_FILE = 'INTERNAL_IMPORT_FILE' # From OpenCTI file system to OpenCTI stix2
13+
INTERNAL_ENRICHMENT = 'INTERNAL_ENRICHMENT' # From OpenCTI stix2 to OpenCTI stix2
14+
INTERNAL_EXPORT_FILE = 'INTERNAL_EXPORT_FILE' # From OpenCTI stix2 to OpenCTI file system
15+
16+
17+
class OpenCTIConnector:
18+
def __init__(self, connector_id: str, connector_name: str, connector_type: str, scope: str):
19+
self.id = connector_id
20+
self.name = connector_name
21+
self.type = ConnectorType(connector_type)
22+
if self.type is None:
23+
raise ValueError('Invalid connector type: ' + connector_type)
24+
self.scope = scope.split(',')
25+
26+
def to_input(self):
27+
return {'input': {'id': self.id, 'name': self.name, 'type': self.type.name, 'scope': self.scope}}

0 commit comments

Comments
 (0)