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