1010from urllib .parse import urlencode
1111
1212from django .conf import settings
13- from django .core .paginator import PageNotAnInteger
1413from django .core .paginator import Paginator
1514from django .db .models import Count
1615from django .db .models import Q
1716from django .http .response import HttpResponseNotAllowed
1817from django .shortcuts import render
1918from django .urls import reverse
2019from django .views import View
21- from django .views .generic .edit import UpdateView
2220from django .views .generic .list import ListView
2321from packageurl import PackageURL
24- from packaging import version
2522
26- from vulnerabilities import forms
2723from vulnerabilities import models
2824from vulnerabilities .forms import PackageForm
2925from vulnerabilities .forms import VulnerabilityForm
@@ -40,112 +36,98 @@ def get(self, request):
4036 if request .GET :
4137 packages = self .request_to_queryset (request )
4238 result_size = len (packages )
39+
40+ if not packages :
41+ return self .render_no_packages (request = request )
42+
43+ page_no = request .GET .get ("page" , 1 )
4344 try :
44- page_no = request .GET .get ("page" , 1 )
45- pages = Paginator (packages , 50 )
46- packages = Paginator (packages , 50 ).get_page (page_no )
47- except PageNotAnInteger :
48- packages = Paginator (packages , 50 ).get_page (1 )
49- packages = pages .get_page (page_no )
45+ page_no = int (page_no )
46+ except ValueError :
47+ page_no = 1
5048
49+ packages = Paginator (packages , per_page = PAGE_SIZE ).get_page (page_no )
5150 context ["packages" ] = packages
5251 context ["searched_for" ] = urlencode (
5352 {param : request .GET [param ] for param in request .GET if param != "page" }
5453 )
5554 context ["result_size" ] = result_size
5655
57- if len ( request .GET ["type" ]):
58- package_type = request . GET [ "type" ]
56+ package_type = request .GET ["type" ]
57+ if package_type :
5958 context ["package_type" ] = package_type
6059
61- if len ( request .GET ["name" ]):
62- package_name = request . GET [ "name" ]
60+ package_name = request .GET ["name" ]
61+ if package_name :
6362 context ["package_name" ] = package_name
6463
65- if result_size == 0 :
66- context = {
67- "package_search" : "The VCIO DB does not contain a record of the package you entered -- "
68- + request .GET ["name" ]
69- + "." ,
70- "debug_ui" : settings .DEBUG_UI ,
71- }
72-
73- if request .GET .get ("template" ) == "packages" :
74- context ["package_form" ] = PackageForm (request .GET or None )
75- context ["template_name" ] = "packages.html"
76- return render (request , "packages.html" , context )
77- elif request .GET .get ("template" ) == "package_details" :
78- context ["package_form" ] = PackageForm (request .GET or None )
79- context ["template_name" ] = "package_update.html"
80- return render (request , "package_update.html" , context )
81- elif request .GET .get ("template" ) == "index" :
82- context ["package_form" ] = PackageForm (request .GET or None )
83- context ["vulnerability_form" ] = VulnerabilityForm (request .GET or None )
84- context ["template_name" ] = "index.html"
85- return render (request , "index.html" , context )
86- else :
87- context ["package_form" ] = PackageForm (request .GET or None )
88- context ["vulnerability_form" ] = VulnerabilityForm (request .GET or None )
89- context ["template_name" ] = "index.html"
90- return render (request , "index.html" , context )
91-
9264 context ["package_form" ] = PackageForm (request .GET or None )
9365 context ["template_name" ] = self .template_name
9466 return render (request , self .template_name , context )
9567
68+ def render_no_packages (self , request ):
69+ context = {
70+ "package_search" : "Package not found." ,
71+ "debug_ui" : settings .DEBUG_UI ,
72+ }
73+
74+ template = request .GET .get ("template" )
75+ context ["package_form" ] = PackageForm (request .GET or None )
76+
77+ if template == "packages" :
78+ context ["template_name" ] = "packages.html"
79+ return render (request , "packages.html" , context )
80+
81+ elif template == "package" :
82+ context ["template_name" ] = "package.html"
83+ return render (request , "package.html" , context )
84+
85+ else :
86+ context ["vulnerability_form" ] = VulnerabilityForm (request .GET or None )
87+ context ["template_name" ] = "index.html"
88+ return render (request , "index.html" , context )
89+
9690 @staticmethod
9791 def request_to_queryset (request ):
98- package_type = ""
99- package_name = ""
92+ """
93+ Return a list of Package objects for a ``request`` object.
94+ """
95+ package_type = request .GET ["type" ] or ""
96+ package_name = request .GET ["name" ] or ""
10097 purl = ""
10198
102- if len (request .GET ["type" ]):
103- package_type = request .GET ["type" ]
104-
105- if len (request .GET ["name" ]):
106- package_name = request .GET ["name" ]
107-
10899 # Check whether the input value is a syntactically-correct purl
109100 try :
110101 purl = PackageURL .from_string (package_name )
111- return list (
112- models .Package .objects .all ()
113- .filter (Q (type = purl .type , name = purl .name , version = purl .version ))
114- .annotate (
115- vulnerability_count = Count (
116- "vulnerabilities" ,
117- filter = Q (packagerelatedvulnerability__fix = False ),
118- ),
119- # TODO: consider renaming to fixed in the future
120- patched_vulnerability_count = Count (
121- "vulnerabilities" ,
122- filter = Q (packagerelatedvulnerability__fix = True ),
123- ),
124- )
125- .prefetch_related ()
102+ qs = models .Package .objects .filter (
103+ type = purl .type ,
104+ namespace = purl .namespace ,
105+ name = purl .name ,
106+ version = purl .version ,
107+ )
108+ except ValueError :
109+ qs = models .Package .objects .filter (
110+ type__icontains = package_type ,
111+ name__icontains = package_name ,
126112 )
127- except :
128- pass
129113
130114 return list (
131- models .Package .objects .all ()
132- .filter (name__icontains = package_name , type__icontains = package_type )
133- .order_by ("type" , "namespace" , "name" , "version" , "subpath" , "qualifiers" )
134- .annotate (
115+ qs .annotate (
135116 vulnerability_count = Count (
136117 "vulnerabilities" ,
137118 filter = Q (packagerelatedvulnerability__fix = False ),
138119 ),
139- # TODO: consider renaming to fixed in the future
140120 patched_vulnerability_count = Count (
141121 "vulnerabilities" ,
142122 filter = Q (packagerelatedvulnerability__fix = True ),
143123 ),
144- )
145- .prefetch_related ()
124+ ).prefetch_related ()
146125 )
147126
148127
128+ PAGE_SIZE = 50
129+
130+
149131class VulnerabilitySearchView (View ):
150132 template_name = "vulnerabilities.html"
151133
@@ -156,43 +138,43 @@ def get(self, request):
156138 if request .GET :
157139 vulnerabilities = self .request_to_vulnerabilities (request )
158140 result_size = len (vulnerabilities )
159- pages = Paginator (vulnerabilities , 50 )
141+ pages = Paginator (vulnerabilities , per_page = PAGE_SIZE )
160142 vulnerabilities = pages .get_page (int (self .request .GET .get ("page" , 1 )))
143+ if not vulnerabilities :
144+ return self .render_no_vuln (request = request )
145+
161146 vuln_id = request .GET ["vuln_id" ]
162147 context ["vulnerabilities" ] = vulnerabilities
163148 context ["result_size" ] = result_size
164149 context ["vuln_id" ] = vuln_id
165150
166- if result_size == 0 :
167- context = {
168- "vuln_search" : "The VCIO DB does not contain a record of the vulnerability you entered -- "
169- + request .GET .get ("vuln_id" )
170- or "" + "." ,
171- "debug_ui" : settings .DEBUG_UI ,
172- }
173-
174- if request .GET .get ("template" ) == "vulnerabilities" :
175- context ["vulnerability_form" ] = VulnerabilityForm (request .GET or None )
176- context ["template_name" ] = "vulnerabilities.html"
177- return render (request , "vulnerabilities.html" , context )
178- elif request .GET .get ("template" ) == "vulnerability_details" :
179- context ["vulnerability_form" ] = VulnerabilityForm (request .GET or None )
180- context ["template_name" ] = "vulnerability.html"
181- return render (request , "vulnerability.html" , context )
182- elif request .GET .get ("template" ) == "index" :
183- context ["package_form" ] = PackageForm (request .GET or None )
184- context ["vulnerability_form" ] = VulnerabilityForm (request .GET or None )
185- context ["template_name" ] = "index.html"
186- return render (request , "index.html" , context )
187- else :
188- context ["package_form" ] = PackageForm (request .GET or None )
189- context ["vulnerability_form" ] = VulnerabilityForm (request .GET or None )
190- context ["template_name" ] = "index.html"
191- return render (request , "index.html" , context )
192-
193151 context ["vulnerability_form" ] = VulnerabilityForm (request .GET or None )
194152 context ["template_name" ] = self .template_name
195- return render (request , self .template_name , context )
153+ return render (request = request , template_name = self .template_name , context = context )
154+
155+ def render_no_vuln (self , request ):
156+ context = {
157+ "vuln_search" : f"Vulnerability not found" ,
158+ "debug_ui" : settings .DEBUG_UI ,
159+ }
160+
161+ context ["vulnerability_form" ] = VulnerabilityForm (request .GET or None )
162+ template = request .GET .get ("template" )
163+
164+ if template == "vulnerabilities" :
165+ context ["template_name" ] = "vulnerabilities.html"
166+ return render (request = request , template_name = "vulnerabilities.html" , context = context )
167+
168+ elif template == "vulnerability_details" :
169+ context ["template_name" ] = "vulnerability_details.html"
170+ return render (
171+ request = request , template_name = "vulnerability_details.html" , context = context
172+ )
173+
174+ else :
175+ context ["package_form" ] = PackageForm (request .GET or None )
176+ context ["template_name" ] = "index.html"
177+ return render (request = request , template_name = "index.html" , context = context )
196178
197179 @staticmethod
198180 def request_to_vulnerabilities (request ):
@@ -213,13 +195,13 @@ def request_to_vulnerabilities(request):
213195 )
214196
215197
216- class PackageUpdate ( UpdateView ):
217- template_name = "package_update .html"
198+ class PackageDetails ( View ):
199+ template_name = "package_details .html"
218200 model = models .Package
219- fields = ["name " , "type " , "version " , "namespace " ]
201+ fields = ["type " , "name " , "namespace " , "version " ]
220202
221203 def get_context_data (self , ** kwargs ):
222- context = super (PackageUpdate , self ).get_context_data (** kwargs )
204+ context = super ().get_context_data (** kwargs )
223205 context ["debug_ui" ] = settings .DEBUG_UI
224206 resolved_vuln , unresolved_vuln = self ._package_vulnerabilities ()
225207 context ["resolved_vuln" ] = resolved_vuln
@@ -245,34 +227,27 @@ def _package_vulnerabilities(self):
245227 # is called
246228 package = self .get_object ()
247229
248- resolved_vuln = [i for i in package .resolved_to ]
249- unresolved_vuln = [i for i in package .vulnerable_to ]
250-
251- resolved_vuln = sorted (resolved_vuln , key = lambda x : x .vulnerability_id )
252- unresolved_vuln = sorted (unresolved_vuln , key = lambda x : x .vulnerability_id )
230+ resolved_vuln = sorted (package .resolved_to , key = lambda x : x .vulnerability_id )
231+ unresolved_vuln = sorted (package .vulnerable_to , key = lambda x : x .vulnerability_id )
253232
254233 return resolved_vuln , unresolved_vuln
255234
256235 def _related_packages (self ):
257- purl = self .get_object ()
236+ package = self .get_object ()
258237 return list (
259- models .Package .objects .all ()
260- .filter (
261- Q (
262- type = purl .type ,
263- namespace = purl .namespace ,
264- name = purl .name ,
265- subpath = purl .subpath ,
266- qualifiers = purl .qualifiers ,
267- )
238+ models .Package .objects .filter (
239+ type = package .type ,
240+ namespace = package .namespace ,
241+ name = package .name ,
242+ subpath = package .subpath ,
243+ qualifiers = package .qualifiers ,
268244 )
269245 .order_by ("version" )
270246 .annotate (
271247 vulnerability_count = Count (
272248 "vulnerabilities" ,
273249 filter = Q (packagerelatedvulnerability__fix = False ),
274250 ),
275- # TODO: consider renaming to fixed in the future
276251 patched_vulnerability_count = Count (
277252 "vulnerabilities" ,
278253 filter = Q (packagerelatedvulnerability__fix = True ),
@@ -292,22 +267,19 @@ class VulnerabilityDetails(ListView):
292267 def get_context_data (self , ** kwargs ):
293268 context = super (VulnerabilityDetails , self ).get_context_data (** kwargs )
294269 context ["debug_ui" ] = settings .DEBUG_UI
270+
295271 vulnerability = models .Vulnerability .objects .get (id = self .kwargs ["pk" ])
296272 context ["vulnerability" ] = vulnerability
297- context ["aliases" ] = vulnerability .aliases .alias ()
298-
299- vulnerability_list = vulnerability .references .all ()
300- vulnerability_list_count = len (vulnerability_list )
301- context ["vulnerability_list_count" ] = vulnerability_list_count
273+ context ["aliases" ] = vulnerability .aliases
302274
303275 context ["vulnerability_form" ] = VulnerabilityForm (self .request .GET or None )
304276 context ["template_name" ] = self .template_name
305277
306- severity_list = []
307- for ref in self .object_list .all ():
308- for obj in ref .severities :
309- severity_list .append (obj )
310- context ["severity_list " ] = severity_list
278+ severities = []
279+ for reference in self .object_list .all ():
280+ for severity in reference .severities :
281+ severities .append (severity )
282+ context ["severities " ] = severities
311283
312284 return context
313285
0 commit comments