Skip to content

Commit da281ea

Browse files
authored
Capturing enhancements to the DefectDojo API (v2) Python wrapper (#39)
* Pass tuple with file path and file content to the upload_scan function to fix issue with Nessus scan uploads. * Adding additional optional properties for the creation of a test * TODO -> Done * Adding new vars to the unittest and restoring the lost work done on the the create_test function * Remvong duplicate line * Adding function to add metadata to a product, removing create_product function and adding the ability to add custom headers to the requests * Since metadata can be applied to multiple objects, renaming the function to be more specific as to what object metadate is being applied * Capturing enhancements to the DefectDojo API (v2) Python wrapper * Adding title, description and version to the wrapper used to modify a test * using the proper verb * Fixing merge conflicts take #2
1 parent 0ee26fc commit da281ea

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

defectdojo_api/defectdojo_apiv2.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,24 @@ def set_engagement(self, id, product_id=None, lead_id=None, name=None, status=No
312312
return self._request('PATCH', 'engagements/' + str(id) + '/', data=data)
313313

314314
###### Product API #######
315+
def set_product_metadata(self, product_id, name=None, value=None):
316+
"""Add a custom field to a product.
317+
318+
:param product_id: Product ID.
319+
:param meta_data: name/value array.
320+
321+
"""
322+
data = {
323+
'product': product_id,
324+
'name': name,
325+
'value': value
326+
}
327+
headers = {
328+
'product_id': '{}'.format(product_id)
329+
}
330+
331+
return self._request('POST', 'metadata/', data=data, custom_headers=headers)
332+
315333
def list_products(self, name=None, name_contains=None, limit=200, offset=0):
316334

317335
"""Retrieves all the products.
@@ -438,14 +456,20 @@ def get_test(self, test_id):
438456
"""
439457
return self._request('GET', 'tests/' + str(test_id) + '/')
440458

441-
def create_test(self, engagement_id, test_type, environment, target_start, target_end, percent_complete=None):
459+
def create_test(self, engagement_id, test_type, environment, target_start,
460+
target_end, percent_complete=None, lead=None, title=None,
461+
version=None, description=None):
442462
"""Creates a product with the given properties.
443463
444464
:param engagement_id: Engagement id.
445465
:param test_type: Test type key id.
446466
:param target_start: Test start date.
447467
:param target_end: Test end date.
448468
:param percent_complete: Percentage until test completion.
469+
:param lead: Test lead id
470+
:param title: Test title/name
471+
:param version: Test version
472+
:param description: Test description
449473
450474
"""
451475

@@ -458,6 +482,18 @@ def create_test(self, engagement_id, test_type, environment, target_start, targe
458482
'percent_complete': percent_complete
459483
}
460484

485+
if lead:
486+
data['lead'] = lead
487+
488+
if title:
489+
data['title'] = title
490+
491+
if version:
492+
data['version'] = version
493+
494+
if description:
495+
data['description'] = description
496+
461497
return self._request('POST', 'tests/', data=data)
462498

463499
def set_test(self, test_id, engagement_id=None, test_type=None, environment=None,
@@ -744,7 +780,6 @@ def build_details(self, engagement_id, json):
744780
)
745781

746782
##### Upload API #####
747-
748783
def upload_scan(self, engagement_id, scan_type, file, active, verified, close_old_findings, skip_duplicates, scan_date, tags=None, build=None, version=None, branch_tag=None, commit_hash=None, minimum_severity="Info", auto_group_by=None):
749784
"""Uploads and processes a scan file.
750785
@@ -798,7 +833,6 @@ def upload_scan(self, engagement_id, scan_type, file, active, verified, close_ol
798833
)
799834

800835
##### Re-upload API #####
801-
802836
def reupload_scan(self, test_id, scan_type, file, active, scan_date, tags=None, build=None, version=None, branch_tag=None, commit_hash=None, minimum_severity="Info", auto_group_by=None):
803837
"""Re-uploads and processes a scan file.
804838
@@ -1150,7 +1184,7 @@ def list_jira_issues(self, finding_id=None, jira_key=None, limit=100, offset=0):
11501184
Retrieves JIRA issues assigned to findings
11511185
11521186
:param finding_id: Search for a specific finding ID
1153-
:param jira_key: Search a specific JIRA key
1187+
:param jira_key: Search a specific JIRA key
11541188
:param limit: Number of records to return.
11551189
:param offset: The initial index from which to return the result
11561190
"""

tests/defectdojo_api_unit_test_apiv2.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,11 @@ def test_19_upload_scan(self):
165165
dir_path = os.path.dirname(os.path.realpath(__file__))
166166

167167
date = datetime.now()
168-
upload_scan = self.dd.upload_scan(self.__class__.engagement_id, "Burp Scan", dir_path + "/scans/Bodgeit-burp.xml",
169-
"true", "false", "false", "false", date.strftime("%Y-%m-%d"), "API")
168+
user_id = 1
169+
upload_scan = self.dd.upload_scan(self.__class__.engagement_id,
170+
"Test Burp Scan", dir_path + "/scans/Bodgeit-burp.xml",
171+
"true", "false", "false", "false", user_id, "Burp Scan",
172+
date.strftime("%Y-%m-%d"), "API")
170173

171174
#upload_scan = self.dd.upload_scan(self.__class__.engagement_id, "NPM Audit Scan", dir_path + "/report.json",
172175
#"true", date.strftime("%Y-%m-%d"), "API")
@@ -181,8 +184,11 @@ def test_20_reupload_scan(self):
181184
dir_path = os.path.dirname(os.path.realpath(__file__))
182185

183186
date = datetime.now()
184-
upload_scan = self.dd.upload_scan(self.__class__.test_id, "Burp Scan", dir_path + "/scans/Bodgeit-burp.xml",
185-
"true", date.strftime("%Y-%m-%d"), "API")
187+
user_id = 1
188+
upload_scan = self.dd.upload_scan(self.__class__.engagement_id,
189+
"Test Burp Scan", dir_path + "/scans/Bodgeit-burp.xml",
190+
"true", "false", "false", "false", user_id, "Burp Scan",
191+
date.strftime("%Y-%m-%d"), "API")
186192

187193
# response doesn't contain an id, so check for engagement instead
188194
self.assertIsNotNone(upload_scan.data["engagement"])

0 commit comments

Comments
 (0)