Skip to content

Commit 24724ff

Browse files
committed
Streamline views
* remove duplicated code * use same naming conventions of robjects and templates for packages and vulnerabilities. * Use constant for PAGE_SIZE Signed-off-by: Philippe Ombredanne <[email protected]>
1 parent 8cdbc7e commit 24724ff

File tree

4 files changed

+109
-137
lines changed

4 files changed

+109
-137
lines changed

vulnerabilities/templates/vulnerability.html renamed to vulnerabilities/templates/vulnerability_details.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@
182182

183183
<div class="has-text-weight-bold tab-nested-div ml-1 mb-1 mt-6">
184184
Severity
185-
{% if severity_list %}
186-
({{ severity_list|length }})
185+
{% if severities %}
186+
({{ severities|length }})
187187
{% else %}
188188
(0)
189189
{% endif %}
@@ -196,7 +196,7 @@
196196
<th> Score </th>
197197
<th> Found at </th>
198198
</tr>
199-
{% if severity_list|length > 0 %}
199+
{% if severities|length > 0 %}
200200
{% for ref in object_list %}
201201
{% for obj in ref.severities %}
202202
<tr>

vulnerabilities/views.py

Lines changed: 104 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,16 @@
1010
from urllib.parse import urlencode
1111

1212
from django.conf import settings
13-
from django.core.paginator import PageNotAnInteger
1413
from django.core.paginator import Paginator
1514
from django.db.models import Count
1615
from django.db.models import Q
1716
from django.http.response import HttpResponseNotAllowed
1817
from django.shortcuts import render
1918
from django.urls import reverse
2019
from django.views import View
21-
from django.views.generic.edit import UpdateView
2220
from django.views.generic.list import ListView
2321
from packageurl import PackageURL
24-
from packaging import version
2522

26-
from vulnerabilities import forms
2723
from vulnerabilities import models
2824
from vulnerabilities.forms import PackageForm
2925
from 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+
149131
class 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

vulnerablecode/urls.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
from vulnerabilities.api import PackageViewSet
1818
from vulnerabilities.api import VulnerabilityViewSet
1919
from vulnerabilities.views import HomePage
20+
from vulnerabilities.views import PackageDetails
2021
from vulnerabilities.views import PackageSearchView
21-
from vulnerabilities.views import PackageUpdate
2222
from vulnerabilities.views import VulnerabilityDetails
2323
from vulnerabilities.views import VulnerabilitySearchView
2424
from vulnerabilities.views import schema_view
@@ -43,7 +43,7 @@ def __init__(self, *args, **kwargs):
4343
path("admin/", admin.site.urls),
4444
path("api/docs", schema_view, name="redoc"),
4545
path("packages/search", PackageSearchView.as_view(), name="package_search"),
46-
path("packages/<int:pk>", PackageUpdate.as_view(), name="package_view"),
46+
path("packages/<int:pk>", PackageDetails.as_view(), name="package_view"),
4747
path("vulnerabilities/<int:pk>", VulnerabilityDetails.as_view(), name="vulnerability_view"),
4848
path("vulnerabilities/search", VulnerabilitySearchView.as_view(), name="vulnerability_search"),
4949
path("", HomePage.as_view(), name="home"),

0 commit comments

Comments
 (0)