@@ -162,25 +162,34 @@ class Code42Client(BaseClient):
162162
163163 def __init__ (self , sdk , base_url , auth , verify = True , proxy = False ):
164164 super ().__init__ (base_url , verify = verify , proxy = proxy )
165- # Create the Code42 SDK instance
166- self ._sdk = sdk or py42 .sdk .from_local_account (base_url , auth [0 ], auth [1 ])
165+ # Allow sdk parameter for unit testing.
166+ # Otherwise, lazily load the SDK so that the TEST Command can effectively check auth.
167+ self ._sdk = sdk
168+ self ._sdk_factory = lambda : py42 .sdk .from_local_account (base_url , auth [0 ], auth [1 ]) if not self ._sdk else None
167169 py42 .settings .set_user_agent_suffix ("Cortex XSOAR" )
168170
171+ def _get_sdk (self ):
172+ if self ._sdk is None :
173+ self ._sdk = self ._sdk_factory ()
174+ return self ._sdk
175+
169176 def add_user_to_departing_employee (self , username , departure_date = None , note = None ):
170177 user_id = self .get_user_id (username )
171- self ._sdk .detectionlists .departing_employee .add (user_id , departure_date = departure_date )
178+ self ._get_sdk ().detectionlists .departing_employee .add (
179+ user_id , departure_date = departure_date
180+ )
172181 if note :
173- self ._sdk .detectionlists .update_user_notes (user_id , note )
182+ self ._get_sdk () .detectionlists .update_user_notes (user_id , note )
174183 return user_id
175184
176185 def remove_user_from_departing_employee (self , username ):
177186 user_id = self .get_user_id (username )
178- self ._sdk .detectionlists .departing_employee .remove (user_id )
187+ self ._get_sdk () .detectionlists .departing_employee .remove (user_id )
179188 return user_id
180189
181190 def get_all_departing_employees (self , results ):
182191 res = []
183- pages = self ._sdk .detectionlists .departing_employee .get_all ()
192+ pages = self ._get_sdk () .detectionlists .departing_employee .get_all ()
184193 for page in pages :
185194 employees = page ["items" ]
186195 for employee in employees :
@@ -191,32 +200,32 @@ def get_all_departing_employees(self, results):
191200
192201 def add_user_to_high_risk_employee (self , username , note = None ):
193202 user_id = self .get_user_id (username )
194- self ._sdk .detectionlists .high_risk_employee .add (user_id )
203+ self ._get_sdk () .detectionlists .high_risk_employee .add (user_id )
195204 if note :
196- self ._sdk .detectionlists .update_user_notes (user_id , note )
205+ self ._get_sdk () .detectionlists .update_user_notes (user_id , note )
197206 return user_id
198207
199208 def remove_user_from_high_risk_employee (self , username ):
200209 user_id = self .get_user_id (username )
201- self ._sdk .detectionlists .high_risk_employee .remove (user_id )
210+ self ._get_sdk () .detectionlists .high_risk_employee .remove (user_id )
202211 return user_id
203212
204213 def add_user_risk_tags (self , username , risk_tags ):
205214 risk_tags = _try_convert_str_list_to_list (risk_tags )
206215 user_id = self .get_user_id (username )
207- self ._sdk .detectionlists .add_user_risk_tags (user_id , risk_tags )
216+ self ._get_sdk () .detectionlists .add_user_risk_tags (user_id , risk_tags )
208217 return user_id
209218
210219 def remove_user_risk_tags (self , username , risk_tags ):
211220 risk_tags = _try_convert_str_list_to_list (risk_tags )
212221 user_id = self .get_user_id (username )
213- self ._sdk .detectionlists .remove_user_risk_tags (user_id , risk_tags )
222+ self ._get_sdk () .detectionlists .remove_user_risk_tags (user_id , risk_tags )
214223 return user_id
215224
216225 def get_all_high_risk_employees (self , risk_tags , results ):
217226 risk_tags = _try_convert_str_list_to_list (risk_tags )
218227 res = []
219- pages = self ._sdk .detectionlists .high_risk_employee .get_all ()
228+ pages = self ._get_sdk () .detectionlists .high_risk_employee .get_all ()
220229 for page in pages :
221230 employees = _get_all_high_risk_employees_from_page (page , risk_tags )
222231 for employee in employees :
@@ -227,31 +236,31 @@ def get_all_high_risk_employees(self, risk_tags, results):
227236
228237 def fetch_alerts (self , start_time , event_severity_filter ):
229238 query = _create_alert_query (event_severity_filter , start_time )
230- res = self ._sdk .alerts .search (query )
239+ res = self ._get_sdk () .alerts .search (query )
231240 return res ["alerts" ]
232241
233242 def get_alert_details (self , alert_id ):
234- res = self ._sdk .alerts .get_details (alert_id )["alerts" ]
243+ res = self ._get_sdk () .alerts .get_details (alert_id )["alerts" ]
235244 if not res :
236245 raise Exception ("No alert found with ID {0}." .format (alert_id ))
237246 return res [0 ]
238247
239248 def resolve_alert (self , id ):
240- self ._sdk .alerts .resolve (id )
249+ self ._get_sdk () .alerts .resolve (id )
241250 return id
242251
243252 def get_current_user (self ):
244- res = self ._sdk .users .get_current ()
253+ res = self ._get_sdk () .users .get_current ()
245254 return res
246255
247256 def get_user_id (self , username ):
248- res = self ._sdk .users .get_by_username (username )["users" ]
257+ res = self ._get_sdk () .users .get_by_username (username )["users" ]
249258 if not res :
250259 raise Exception ("No user found with username {0}." .format (username ))
251260 return res [0 ]["userUid" ]
252261
253262 def search_file_events (self , payload ):
254- res = self ._sdk .securitydata .search_file_events (payload )
263+ res = self ._get_sdk () .securitydata .search_file_events (payload )
255264 return res ["fileEvents" ]
256265
257266
@@ -364,7 +373,7 @@ class ObservationToSecurityQueryMapper(object):
364373 exposure_type_map = {
365374 "PublicSearchableShare" : ExposureType .IS_PUBLIC ,
366375 "PublicLinkShare" : ExposureType .SHARED_VIA_LINK ,
367- "SharedOutsideTrustedDomain" : "OutsideTrustedDomains"
376+ "SharedOutsideTrustedDomain" : "OutsideTrustedDomains" ,
368377 }
369378
370379 def __init__ (self , observation , actor ):
@@ -824,11 +833,16 @@ def fetch_incidents(
824833
825834
826835def test_module (client ):
827- if client .get_current_user ():
836+ try :
837+ # Will fail if unauthorized
838+ client .get_current_user ()
828839 return "ok"
829- return "Invalid credentials or host address. Check that the username and password are correct, \
830- that the host is available and reachable, and that you have supplied the full scheme, \
831- domain, and port (e.g. https://myhost.code42.com:4285)"
840+ except Exception :
841+ return (
842+ "Invalid credentials or host address. Check that the username and password are correct, that the host "
843+ "is available and reachable, and that you have supplied the full scheme, domain, and port "
844+ "(e.g. https://myhost.code42.com:4285)."
845+ )
832846
833847
834848def main ():
0 commit comments