Skip to content

Commit e0d8b60

Browse files
Merge pull request #96 from veracode/main
merge main into CMK branch
2 parents 00b98b2 + 9375636 commit e0d8b60

File tree

10 files changed

+98
-23
lines changed

10 files changed

+98
-23
lines changed

docs/analytics.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,25 @@ The following methods call Veracode REST APIs and return JSON.
66

77
1. The Reporting API is available to Veracode customers by request. More information about the API is available in the [Veracode Docs](https://docs.veracode.com/r/Reporting_REST_API).
88

9-
- `Analytics().create_report(report_type ('findings'),last_updated_start_date, last_updated_end_date (opt), scan_type (opt), finding_status(opt), passed_policy(opt), policy_sandbox(opt), application_id(opt), rawjson(opt))`: set up a request for a report. By default this command returns the GUID of the report request; specify `rawjson=True` to get the full response. Dates should be specified as `YYYY-MM-DD HH:MM:SS` with the timestamp optional. Options include:
10-
- `report_type`: required, currently supports `findings` and `scans`.
11-
- `last_updated_start_date`: required, beginning of date range for new or changed findings
12-
- `last_updated_end_date`: optional, end of date range for new or changed findings
13-
- `scan_type`: optional, one or more of 'Static Analysis', 'Dynamic Analysis', 'Manual', 'Software Composition Analysis', 'SCA'
9+
- `Analytics().create_report(report_type ('findings'),last_updated_start_date(opt), last_updated_end_date (opt), scan_type (opt), finding_status(opt), passed_policy(opt), policy_sandbox(opt), application_id(opt), rawjson(opt), deletion_start_date(opt), deletion_end_date(opt))`: set up a request for a report. By default this command returns the GUID of the report request; specify `rawjson=True` to get the full response. Dates should be specified as `YYYY-MM-DD HH:MM:SS` with the timestamp optional. Options include:
10+
- `report_type`: required, currently supports `findings`, `scans`, and `deletedscans`.
11+
- `last_updated_start_date`: required for `findings` report type, beginning of date range for new or changed findings or scans
12+
- `last_updated_end_date`: optional, end of date range for new or changed findings or scans
13+
- `scan_type`: optional, one or more of 'Static Analysis', 'Dynamic Analysis', 'Manual', 'Software Composition Analysis', 'SCA'. `SCA` is only supported for the `findings` report type.
1414
- `finding_status`: optional, 'Open' or 'Closed'. Applies only to the `findings` report.
1515
- `passed_policy`: optional, boolean. Applies only to the `findings` report.
1616
- `policy_sandbox`: optional, 'Policy' or 'Sandbox'
1717
- `application_id`: optional, application ID for which to return results
1818
- `rawjson`: optional, defaults to False. Returns full response if True, the GUID of the request if false
19+
- `deletion_start_date`: required for `deletedscans` report type, beginning of date range for deleted scans.
20+
- `deletion_end_date`: optional, end of date range for deleted scans.
1921

2022
- `Analytics().get(guid, report_type(findings))`: check the status of the report request and return the report contents when ready. Note that this method returns a tuple of `status` (string) and `results` (list); when `status` is `COMPLETED`, the `results` list will populate with results. Also, you need to specify the type of data expected by the GUID with `report_type`; this defaults to `findings`.
2123

2224
- `Analytics().get_findings(guid)`: check the status of a findings report request specified by `guid` and return the report contents when ready. Note that this method returns a tuple of `status` (string) and `results` (list); when `status` is `COMPLETED`, the `results` list will populate with results.
2325

2426
- `Analytics().get_scans(guid)`: check the status of a scans report request specified by `guid` and return the report contents when ready. Note that this method returns a tuple of `status` (string) and `results` (list); when `status` is `COMPLETED`, the `results` list will populate with results.
2527

28+
- `Analytics().get_deletedscans(guid)`: check the status of a deleted scans report request specified by `guid` and return the report contents when ready. Note that this method returns a tuple of `status` (string) and `results` (list); when `status` is `COMPLETED`, the `results` list will populate with results.
29+
2630
[All docs](docs.md)

docs/api.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,14 @@ As an alternative to importing individual objects into your library, you can acc
2626

2727
### Analytics Reporting
2828

29-
1. *Accessing*: The Reporting API is available to Veracode customers by request.
3029
1. *More information*: See the [Veracode Docs](https://docs.veracode.com/r/Reporting_REST_API).
3130
1. *See Also*: You can also access these methods from the [Analytics class](analytics.md).
3231

3332
- `create_analytics_report(report_type ('findings'),last_updated_start_date, last_updated_end_date (opt), scan_type (opt), finding_status(opt), passed_policy(opt), policy_sandbox(opt), application_id(opt), rawjson(opt))`: set up a request for a report. By default this command returns the GUID of the report request; specify `rawjson=True` to get the full response. Dates should be specified as `YYYY-MM-DD HH:MM:SS` with the timestamp optional. Options include:
34-
- `report_type`: required, currently only supports `findings`
33+
- `report_type`: required, currently only supports `findings`, `scans` and `deletedscans`
3534
- `last_updated_start_date`: required, beginning of date range for new or changed findings
3635
- `last_updated_end_date`: optional, end of date range for new or changed findings
37-
- `scan_type`: optional, one or more of 'Static Analysis', 'Dynamic Analysis', 'Manual', 'Software Composition Analysis', 'SCA'
36+
- `scan_type`: optional, one or more of 'Static Analysis', 'Dynamic Analysis', 'Manual', 'Software Composition Analysis', 'SCA'. `SCA` is only supported for the `findings` type
3837
- `finding_status`: optional, 'Open' or 'Closed'
3938
- `passed_policy`: optional, boolean
4039
- `policy_sandbox`: optional, 'Policy' or 'Sandbox'

docs/findings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ The following methods call Veracode REST APIs and return JSON.
55
## Findings and Annotations
66

77
- `Findings().get_findings(app,scantype(opt),annot(opt),request_params(opt),sandbox(opt))`: get the findings for `app` (guid).
8-
- `scantype`: Defaults to STATIC findings, but can be STATIC, DYNAMIC, MANUAL, SCA, or ALL (static, dynamic, manual).
8+
- `scantype`: Defaults to STATIC findings, but can be STATIC, DYNAMIC, MANUAL, SCA, or ALL (static, dynamic, manual). You can also pass a comma-delimited string of valid scantype options.
99
- `annot`: Defaults to TRUE but can be FALSE
1010
- `sandbox`: The guid of the sandbox in `app` for which you want findings. (Use the Sandboxes APIs to get the sandbox guid.)
1111
- `request_params`: Dictionary of additional query parameters. See the full [Findings API specification](https://help.veracode.com/r/c_findings_v2_intro) for some of the other options available.

requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
requests>=2.32.0
2-
veracode-api-signing>=22.3.0
3-
urllib3>= 2.2.2
2+
veracode-api-signing>=24.11.0
43
Pygments>= 2.9.0
54
idna>=3.7
65
certifi>=2024.7.4
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import time
2+
import sys
3+
import json
4+
import datetime
5+
from veracode_api_py import Analytics
6+
7+
wait_seconds = 15
8+
9+
print('Generating deleted scans report...')
10+
theguid = Analytics().create_report(report_type="deletedscans",deletion_start_date='2024-07-01',deletion_end_date='2024-12-31')
11+
12+
print('Checking status for report {}...'.format(theguid))
13+
thestatus,thescans=Analytics().get_deleted_scans(theguid)
14+
15+
while thestatus != 'COMPLETED':
16+
print('Waiting {} seconds before we try again...'.format(wait_seconds))
17+
time.sleep(wait_seconds)
18+
print('Checking status for report {}...'.format(theguid))
19+
thestatus,thescans=Analytics().get_deleted_scans(theguid)
20+
21+
recordcount = len(thescans)
22+
23+
print('Retrieved {} scans'.format(recordcount))
24+
25+
if recordcount > 0:
26+
now = datetime.datetime.now().astimezone()
27+
filename = 'report-{}'.format(now)
28+
with open('{}.json'.format(filename), 'w') as outfile:
29+
json.dump(thescans,outfile)
30+
outfile.close()
31+
32+
print('Wrote {} findings to {}.json'.format(recordcount,filename))

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
long_description_content_type="text/markdown",
1515
author = 'Tim Jarrett',
1616
author_email = '[email protected]',
17-
url = 'https://github.com/tjarrettveracode',
17+
url = 'https://github.com/tjarrettveracode',
1818
download_url = 'https://github.com/veracode/veracode-api-py/archive/v_0957.tar.gz',
1919
keywords = ['veracode', 'veracode-api'],
2020
install_requires=[

veracode_api_py/analytics.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,46 @@
66
from .apihelper import APIHelper
77

88
class Analytics():
9-
report_types = [ "findings", "scans" ]
9+
report_types = [ "findings", "scans", "deletedscans" ]
1010

1111
findings_scan_types = ["Static Analysis", "Dynamic Analysis", "Manual", "SCA", "Software Composition Analysis" ]
1212
scan_scan_types = ["Static Analysis", "Dynamic Analysis", "Manual" ]
1313

1414
base_url = 'appsec/v1/analytics/report'
1515

1616
#public methods
17-
def create_report(self,report_type,last_updated_start_date,last_updated_end_date=None,
17+
def create_report(self,report_type,last_updated_start_date=None,last_updated_end_date=None,
1818
scan_type:list = [], finding_status=None,passed_policy=None,
19-
policy_sandbox=None,application_id=None,rawjson=False):
19+
policy_sandbox=None,application_id=None,rawjson=False, deletion_start_date=None,
20+
deletion_end_date=None):
2021

2122
if report_type not in self.report_types:
2223
raise ValueError("{} is not in the list of valid report types ({})".format(report_type,self.report_types))
2324

24-
report_def = { "report_type": report_type,"last_updated_start_date": last_updated_start_date }
25+
report_def = { 'report_type': report_type }
26+
27+
if last_updated_start_date:
28+
report_def['last_updated_start_date'] = last_updated_start_date
29+
else:
30+
if report_type in ['findings','scans']:
31+
raise ValueError("{} report type requires a last updated start date.").format(report_type)
2532

2633
if last_updated_end_date:
2734
report_def['last_updated_end_date'] = last_updated_end_date
2835

36+
if deletion_end_date:
37+
report_def['deletion_end_date'] = deletion_end_date
38+
39+
if deletion_start_date:
40+
report_def['deletion_start_date'] = deletion_start_date
41+
else:
42+
if report_type == 'deletedscans':
43+
raise ValueError("{} report type requires a deleteion start date.").format(report_type)
44+
2945
if len(scan_type) > 0:
3046
if report_type == 'findings':
3147
valid_scan_types = self.findings_scan_types
32-
elif report_type == 'scans':
48+
elif report_type in [ 'scans', 'deletedscans' ]:
3349
valid_scan_types = self.scan_scan_types
3450
if not(self._case_insensitive_list_compare(scan_type,valid_scan_types)):
3551
raise ValueError("{} is not in the list of valid scan types ({})".format(report_type,valid_scan_types))
@@ -62,6 +78,10 @@ def get_findings(self, guid: UUID):
6278
def get_scans(self, guid: UUID):
6379
thestatus, thescans = self.get(guid=guid,report_type='scans')
6480
return thestatus, thescans
81+
82+
def get_deleted_scans(self, guid: UUID):
83+
thestatus, thescans = self.get(guid=guid,report_type='deletedscans')
84+
return thestatus, thescans
6585

6686
def get(self,guid: UUID,report_type='findings'):
6787
# handle multiple scan types

veracode_api_py/api.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -642,15 +642,29 @@ def dyn_start_scan(self, length, unit):
642642
return DynUtils().start_scan(length,unit)
643643

644644
# analytics apis
645-
def create_analytics_report(self,report_type,last_updated_start_date,last_updated_end_date=None,
645+
def create_analytics_report(self,report_type,last_updated_start_date=None,last_updated_end_date=None,
646646
scan_type:list = [], finding_status=None,passed_policy=None,
647-
policy_sandbox=None,application_id=None,rawjson=False):
647+
policy_sandbox=None,application_id=None,rawjson=False,deletion_start_date=None,
648+
deletion_end_date=None):
648649
return Analytics().create_report(report_type=report_type,last_updated_start_date=last_updated_start_date,
649650
last_updated_end_date=last_updated_end_date,scan_type=scan_type,
650651
finding_status=finding_status,passed_policy=passed_policy,
651652
policy_sandbox=policy_sandbox,application_id=application_id,
652-
rawjson=rawjson)
653+
rawjson=rawjson, deletion_start_date=deletion_start_date,
654+
deletion_end_date=deletion_end_date)
653655

654656
def get_analytics_report(self,guid: UUID):
655657
status, findings = Analytics().get(guid=guid)
658+
return status, findings
659+
660+
def get_analytics_findings_report(self,guid:UUID):
661+
status, findings = Analytics().get_findings(guid=guid)
662+
return status, findings
663+
664+
def get_analytics_scans(self,guid:UUID):
665+
status, findings = Analytics().get_scans(guid=guid)
666+
return status, findings
667+
668+
def get_analytics_deleted_scans(self,guid:UUID):
669+
status, findings = Analytics().get_deleted_scans(guid=guid)
656670
return status, findings

veracode_api_py/findings.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,15 @@ def get_findings(self,app: UUID,scantype='STATIC',annot='TRUE',request_params=No
1414
if request_params == None:
1515
request_params = {}
1616

17-
if scantype in ['STATIC', 'DYNAMIC', 'MANUAL','SCA']:
18-
request_params['scan_type'] = scantype
17+
scantypes = ""
18+
scantype = scantype.split(',')
19+
for st in scantype:
20+
if st in ['STATIC', 'DYNAMIC', 'MANUAL','SCA']:
21+
if len(scantypes) > 0:
22+
scantypes += ","
23+
scantypes += st
24+
if len(scantypes) > 0:
25+
request_params['scan_type'] = scantypes
1926
#note that scantype='ALL' will result in no scan_type parameter as in API
2027

2128
request_params['include_annot'] = annot

veracode_api_py/identity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ def _create_or_update(self, method, role_name, role_description, role_guid: UUID
298298
if len(child_roles) > 0:
299299
role_def['child_roles'] = child_roles
300300

301-
payload = json.dumps({"profile": role_def})
301+
payload = json.dumps(role_def)
302302
return APIHelper()._rest_request(uri,httpmethod,body=payload)
303303

304304
class Permissions():

0 commit comments

Comments
 (0)