1010
1111from pycti import __version__
1212from pycti .api .opencti_api_connector import OpenCTIApiConnector
13+ from pycti .api .opencti_api_draft import OpenCTIApiDraft
14+ from pycti .api .opencti_api_internal_file import OpenCTIApiInternalFile
15+ from pycti .api .opencti_api_notification import OpenCTIApiNotification
16+ from pycti .api .opencti_api_pir import OpenCTIApiPir
1317from pycti .api .opencti_api_playbook import OpenCTIApiPlaybook
18+ from pycti .api .opencti_api_public_dashboard import OpenCTIApiPublicDashboard
19+ from pycti .api .opencti_api_trash import OpenCTIApiTrash
1420from pycti .api .opencti_api_work import OpenCTIApiWork
21+ from pycti .api .opencti_api_workspace import OpenCTIApiWorkspace
1522from pycti .entities .opencti_attack_pattern import AttackPattern
1623from pycti .entities .opencti_campaign import Campaign
1724from pycti .entities .opencti_capability import Capability
7178from pycti .utils .opencti_stix2_utils import OpenCTIStix2Utils
7279
7380
81+ def build_request_headers (token : str , custom_headers : str , app_logger ):
82+ headers_dict = {
83+ "User-Agent" : "pycti/" + __version__ ,
84+ "Authorization" : "Bearer " + token ,
85+ }
86+ # Build and add custom headers
87+ if custom_headers is not None :
88+ for header_pair in custom_headers .strip ().split (";" ):
89+ if header_pair : # Skip empty header pairs
90+ try :
91+ key , value = header_pair .split (":" , 1 )
92+ headers_dict [key .strip ()] = value .strip ()
93+ except ValueError :
94+ app_logger .warning (
95+ "Ignored invalid header pair" , {"header_pair" : header_pair }
96+ )
97+ return headers_dict
98+
99+
74100class File :
75101 def __init__ (self , name , data , mime = "text/plain" ):
76102 self .name = name
@@ -99,24 +125,28 @@ class OpenCTIApiClient:
99125 ```
100126 :param json_logging: format the logs as json if set to True
101127 :type json_logging: bool, optional
128+ :param bundle_send_to_queue: if bundle will be sent to queue
129+ :type bundle_send_to_queue: bool, optional
102130 :param cert: If String, file path to pem file. If Tuple, a ('path_to_cert.crt', 'path_to_key.key') pair representing the certificate and the key.
103131 :type cert: str, tuple, optional
104- :param auth: Add a AuthBase class with custom authentication for you OpenCTI infrastructure.
105- :type auth: requests.auth.AuthBase, optional
132+ :param custom_headers: Add custom headers to use with the graphql queries
133+ :type custom_headers: str, optional must in the format header01:value;header02:value
134+ :param perform_health_check: if client init must check the api access
135+ :type perform_health_check: bool, optional
106136 """
107137
108138 def __init__ (
109139 self ,
110140 url : str ,
111141 token : str ,
112- log_level = "info" ,
142+ log_level : str = "info" ,
113143 ssl_verify : Union [bool , str ] = False ,
114144 proxies : Union [Dict [str , str ], None ] = None ,
115- json_logging = False ,
116- bundle_send_to_queue = True ,
145+ json_logging : bool = False ,
146+ bundle_send_to_queue : bool = True ,
117147 cert : Union [str , Tuple [str , str ], None ] = None ,
118- auth = None ,
119- perform_health_check = True ,
148+ custom_headers : str = None ,
149+ perform_health_check : bool = True ,
120150 ):
121151 """Constructor method"""
122152
@@ -138,22 +168,22 @@ def __init__(
138168 # Define API
139169 self .api_token = token
140170 self .api_url = url + "/graphql"
141- self .request_headers = {
142- "User-Agent" : "pycti/" + __version__ ,
143- "Authorization" : "Bearer " + token ,
144- }
145-
146- if auth is not None :
147- self .session = requests .session ()
148- self .session .auth = auth
149- else :
150- self .session = requests .session ()
151-
171+ self .request_headers = build_request_headers (
172+ token , custom_headers , self .app_logger
173+ )
174+ self .session = requests .session ()
152175 # Define the dependencies
153176 self .work = OpenCTIApiWork (self )
177+ self .notification = OpenCTIApiNotification (self )
178+ self .trash = OpenCTIApiTrash (self )
179+ self .draft = OpenCTIApiDraft (self )
180+ self .workspace = OpenCTIApiWorkspace (self )
181+ self .public_dashboard = OpenCTIApiPublicDashboard (self )
154182 self .playbook = OpenCTIApiPlaybook (self )
155183 self .connector = OpenCTIApiConnector (self )
156184 self .stix2 = OpenCTIStix2 (self )
185+ self .pir = OpenCTIApiPir (self )
186+ self .internal_file = OpenCTIApiInternalFile (self )
157187
158188 # Define the entities
159189 self .vocabulary = Vocabulary (self )
@@ -248,13 +278,15 @@ def set_retry_number(self, retry_number):
248278 "" if retry_number is None else str (retry_number )
249279 )
250280
251- def query (self , query , variables = None ):
281+ def query (self , query , variables = None , disable_impersonate = False ):
252282 """submit a query to the OpenCTI GraphQL API
253283
254284 :param query: GraphQL query string
255285 :type query: str
256286 :param variables: GraphQL query variables, defaults to {}
257287 :type variables: dict, optional
288+ :param disable_impersonate: removes impersonate header if set to True, defaults to False
289+ :type disable_impersonate: bool, optional
258290 :return: returns the response json content
259291 :rtype: Any
260292 """
@@ -279,6 +311,9 @@ def query(self, query, variables=None):
279311 else :
280312 query_var [key ] = val
281313
314+ query_headers = self .request_headers .copy ()
315+ if disable_impersonate and "opencti-applicant-id" in query_headers :
316+ del query_headers ["opencti-applicant-id" ]
282317 # If yes, transform variable (file to null) and create multipart query
283318 if len (files_vars ) > 0 :
284319 multipart_data = {
@@ -345,7 +380,7 @@ def query(self, query, variables=None):
345380 self .api_url ,
346381 data = multipart_data ,
347382 files = multipart_files ,
348- headers = self . request_headers ,
383+ headers = query_headers ,
349384 verify = self .ssl_verify ,
350385 cert = self .cert ,
351386 proxies = self .proxies ,
@@ -356,7 +391,7 @@ def query(self, query, variables=None):
356391 r = self .session .post (
357392 self .api_url ,
358393 json = {"query" : query , "variables" : variables },
359- headers = self . request_headers ,
394+ headers = query_headers ,
360395 verify = self .ssl_verify ,
361396 cert = self .cert ,
362397 proxies = self .proxies ,
0 commit comments