Skip to content

Commit 546cc08

Browse files
author
Glenn Snyder
authored
Merge pull request #39 from blackducksoftware/gsnyder/adding_more_examples_for_pulling_vulnerability_info
adding example to retrieve vulnerability notifications
2 parents 23852e9 + 5ecd3ae commit 546cc08

File tree

2 files changed

+125
-6
lines changed

2 files changed

+125
-6
lines changed

examples/get_bom_component_vulnerability_info.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
parser = argparse.ArgumentParser("Retreive BOM component vulnerability information for the given project and version")
3030
parser.add_argument("project_name")
3131
parser.add_argument("version")
32+
parser.add_argument("-u", "--include_updated_vulns",
33+
action='store_true',
34+
help="If set, will also retrieve vulnerabilities whose update date/time is later than the newer_than date/time")
3235
parser.add_argument("-n", "--newer_than",
3336
default=None,
3437
type=str,
@@ -57,17 +60,24 @@
5760

5861
version = hub.get_version_by_name(project, args.version)
5962

63+
import pdb; pdb.set_trace()
64+
6065
vulnerable_bom_components_info = hub.get_vulnerable_bom_components(version)
6166

6267
vulnerable_bom_components = vulnerable_bom_components_info.get('items', [])
6368

6469
if vulnerable_bom_components:
65-
vulnerable_bom_components = sorted(
66-
vulnerable_bom_components,
67-
key = lambda k: k['vulnerabilityWithRemediation']['vulnerabilityPublishedDate'])
68-
if newer_than:
69-
vulnerable_bom_components = [v for v in vulnerable_bom_components
70-
if timestring.Date(v['vulnerabilityWithRemediation']['vulnerabilityPublishedDate']) > newer_than ]
70+
vulnerable_bom_components = sorted(
71+
vulnerable_bom_components,
72+
key = lambda k: k['vulnerabilityWithRemediation']['vulnerabilityPublishedDate'])
73+
if newer_than:
74+
if args.include_updated_vulns:
75+
vulnerable_bom_components = [v for v in vulnerable_bom_components
76+
if timestring.Date(v['vulnerabilityWithRemediation']['vulnerabilityPublishedDate']) > newer_than
77+
or timestring.Date(v['vulnerabilityWithRemediation']['vulnerabilityUpdatedDate']) > newer_than ]
78+
else:
79+
vulnerable_bom_components = [v for v in vulnerable_bom_components
80+
if timestring.Date(v['vulnerabilityWithRemediation']['vulnerabilityPublishedDate']) > newer_than ]
7181
else:
7282
logging.debug("Did not find any vulnerable BOM components in project {}, version {}".format(args.project_name, args.version))
7383

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/env python
2+
3+
'''
4+
Created on Mar 29, 2019
5+
6+
@author: gsnyder
7+
8+
Retrieve vulnerability notifications
9+
10+
Note: The user account you run this under will determine the scope (i.e. projects, versions) of
11+
the notifications that can be received.
12+
13+
'''
14+
15+
import argparse
16+
from datetime import datetime
17+
import json
18+
import logging
19+
import pytz
20+
import sys
21+
import timestring
22+
23+
from blackduck.HubRestApi import HubInstance, object_id
24+
25+
#
26+
# Example usage:
27+
#
28+
# To get all the vulnerability notices,
29+
# python examples/get_vulnerability_notifications.py > all_vuln_notifications.json
30+
#
31+
# To get all the vulnerability notices and save the date/time of the last run,
32+
# python examples/get_vulnerability_notifications.py -s > all_vuln_notifications.json
33+
#
34+
# To get all the vulnerability notices since the last run,
35+
# python examples/get_vulnerability_notifications.py -n `cat .last_run` > all_vuln_notifications.json
36+
#
37+
# To get all the vulnerability notices since a date/time,
38+
# python examples/get_vulnerability_notifications.py -n "March 29, 2019 12:00" > since_mar_29_at_noon_vuln_notifications.json
39+
#
40+
# To get all the vulnerability notices for a given project,
41+
# python examples/get_vulnerability_notifications.py -p my-project > all_vuln_notifications_for_my_project.json
42+
#
43+
# To get all the vulnerability notices for a given project and version,
44+
# python examples/get_vulnerability_notifications.py -p my-project -v 1.0 > all_vuln_notifications_for_my_project_v1.0.json
45+
#
46+
#
47+
48+
49+
parser = argparse.ArgumentParser("Retreive vulnerability notifications")
50+
parser.add_argument("-p", "--project", help="If supplied, filter the notifications to this project")
51+
parser.add_argument("-v", "--version", help="If supplied, filter the notifications to this version (requires a project)")
52+
parser.add_argument("-n", "--newer_than",
53+
default=None,
54+
type=str,
55+
help="Set this option to see all vulnerability notifications published since the given date/time.")
56+
parser.add_argument("-s", "--save_dt",
57+
action='store_true',
58+
help="If set, the date/time will be saved to a file named '.last_run' in the current directory which can be used later with the -n option to see vulnerabilities published since the last run.")
59+
parser.add_argument("-l", "--limit", default=100000, help="To change the limit on the number of notifications to retrieve")
60+
61+
args = parser.parse_args()
62+
63+
if args.newer_than:
64+
newer_than = timestring.Date(args.newer_than).date
65+
# adjust to UTC so the comparison is normalized
66+
newer_than = newer_than.astimezone(pytz.utc)
67+
else:
68+
newer_than = None
69+
70+
if args.save_dt:
71+
with open(".last_run", "w") as f:
72+
f.write(datetime.now().isoformat())
73+
74+
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', stream=sys.stderr, level=logging.DEBUG)
75+
logging.getLogger("requests").setLevel(logging.WARNING)
76+
logging.getLogger("urllib3").setLevel(logging.WARNING)
77+
78+
hub = HubInstance()
79+
80+
current_user = hub.get_current_user()
81+
82+
user_notifications_url = hub.get_link(current_user, "notifications")
83+
user_notifications_url = "{}?limit={}".format(user_notifications_url, args.limit)
84+
85+
# notifications_url = "{}/api/notifications?limit={}".format(hub.get_urlbase(), args.limit)
86+
87+
vulnerability_notifications = []
88+
89+
response = hub.execute_get(user_notifications_url)
90+
if response.status_code == 200:
91+
notifications = response.json()
92+
notifications = notifications.get('items', [])
93+
94+
vulnerability_notifications = list(filter(lambda n: n['type'] == "VULNERABILITY", notifications))
95+
if newer_than:
96+
vulnerability_notifications = list(
97+
filter(lambda n: timestring.Date(n['createdAt']) > newer_than, vulnerability_notifications))
98+
if args.project:
99+
vulnerability_notifications = list(
100+
filter(lambda n: args.project in [apv['projectName'] for apv in n['content']['affectedProjectVersions']],
101+
vulnerability_notifications))
102+
if args.version:
103+
vulnerability_notifications = list(
104+
filter(lambda n: args.version in [apv['projectVersionName'] for apv in n['content']['affectedProjectVersions']],
105+
vulnerability_notifications))
106+
else:
107+
print("Failed to retrieve notifications for user {}".format(current_user))
108+
109+
print(json.dumps(vulnerability_notifications))

0 commit comments

Comments
 (0)