Skip to content

Commit a596062

Browse files
committed
Refactor views for new models, do some style changes
The views are now based on PackageRelatedVulnerablity model. Apart from that out of need, the properties vulnerable_to and resolved_to are added to Vulnerability and Package models. Style changes include centering the search bars. Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
1 parent b8c6703 commit a596062

6 files changed

Lines changed: 84 additions & 62 deletions

File tree

vulnerabilities/models.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ class Vulnerability(models.Model):
4545
help_text='Summary of the vulnerability', blank=True)
4646
cvss = models.FloatField(max_length=100, help_text='CVSS Score', null=True)
4747

48+
@property
49+
def vulnerable_to(self):
50+
return self.packagerelatedvulnerability_set.filter(is_vulnerable=True)
51+
52+
@property
53+
def resolved_to(self):
54+
return self.packagerelatedvulnerability_set.filter(is_vulnerable=False)
55+
4856
def __str__(self):
4957
return self.cve_id or self.summary
5058

@@ -80,6 +88,14 @@ class Package(PackageURLMixin):
8088
vulnerabilities = models.ManyToManyField(
8189
to='Vulnerability', through='PackageRelatedVulnerability')
8290

91+
@property
92+
def vulnerable_to(self):
93+
return self.packagerelatedvulnerability_set.filter(is_vulnerable=True)
94+
95+
@property
96+
def resolved_to(self):
97+
return self.packagerelatedvulnerability_set.filter(is_vulnerable=False)
98+
8399
class Meta:
84100
unique_together = ('name', 'namespace', 'type',
85101
'version', 'qualifiers', 'subpath')

vulnerabilities/templates/packages.html

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
{% load widget_tweaks %}
77

88
<section class="columns has-text-centered">
9-
<div class = "column is-one-quarter">
10-
</div>
11-
<form action="{% url 'package_search' %}" method="get">
9+
<div class = "column is-three-fifths is-offset-one-fifth">
10+
<form action="{% url 'package_search' %}" method="get">
1211
<div class="field is-horizontal">
1312
{% for field in form %}
1413
{{ field|add_class:"input" }}
@@ -18,6 +17,8 @@
1817
</button>
1918
</form>
2019
</div>
20+
</div>
21+
2122
</section>
2223

2324
{% if packages %}
@@ -40,8 +41,8 @@ <h3 class="subtitle">Total Results {{packages|length}}</h3>
4041
{% for package in packages %}
4142
<tr>
4243
<td><a href="{% url 'package_view' package.pk %}">{{package}}</a></td>
43-
<td>{{package.resolvedpackage_set.all|length}}</td>
44-
<td>{{package.impactedpackage_set.all|length}}</td>
44+
<td>{{package.resolved_to.all|length}}</td>
45+
<td>{{package.vulnerable_to.all|length}}</td>
4546
</tr>
4647
{% endfor %}
4748
</table>

vulnerabilities/templates/vulnerabilities.html

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
{% block content %}
77

88
<div class="columns">
9-
<div class="column is-one-third mx-6">
10-
</div>
9+
<div class="column is-one-third is-offset-one-third">
10+
1111
<form action="{% url 'vulnerability_search' %}" method="get">
1212
{% load widget_tweaks %}
1313
<div class="field is-horizontal">
@@ -17,6 +17,7 @@
1717
</button>
1818
</div>
1919
</form>
20+
</div>
2021
</div>
2122

2223
{% if vulnerabilities %}
@@ -38,8 +39,8 @@ <h3 class="subtitle" id="results">Total {{vulnerabilities|length}} results</h3>
3839
{% for vulnerability in vulnerabilities %}
3940
<tr>
4041
<td><a href="{% url 'vulnerability_view' vulnerability.pk %}">{{vulnerability.cve_id}}</a></td>
41-
<td>{{vulnerability.resolvedpackage_set.all|length}}</td>
42-
<td>{{vulnerability.impactedpackage_set.all|length}}</td>
42+
<td>{{vulnerability.resolved_to.all|length}}</td>
43+
<td>{{vulnerability.vulnerable_to.all|length}}</td>
4344
</tr>
4445
{% endfor %}
4546
</table>

vulnerabilities/templates/vulnerability.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ <h3>References:</h3>
5555
</span>
5656
</a>
5757

58-
{% if vulnerability.resolvedpackage_set.all %}
58+
{% if vulnerability.resolved_to.all %}
5959
<h3> Patched Packages </h3>
6060
<table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth">
6161
<tr>
6262
<th> Package URL </th>
6363
</tr>
64-
{% for ref in vulnerability.resolvedpackage_set.all %}
64+
{% for ref in vulnerability.resolved_to.all %}
6565
<tr>
6666
<td><a href ="{% url 'package_view' ref.package.pk %}"> {{ref.package}} </a> </td>
6767
</tr>
@@ -71,13 +71,13 @@ <h3> Patched Packages </h3>
7171
<h3> No available patched packages </h3>
7272
{% endif %}
7373

74-
{% if vulnerability.impactedpackage_set.all %}
74+
{% if vulnerability.vulnerable_to.all %}
7575
<h3> Vulnerable Packages </h3>
7676
<table class="table is-bordered is-striped is-narrow is-hoverable is-fullwidth">
7777
<tr>
7878
<th> Package URL </th>
7979
</tr>
80-
{% for ref in vulnerability.impactedpackage_set.all %}
80+
{% for ref in vulnerability.vulnerable_to.all %}
8181
<tr>
8282
<td><a href ="{% url 'package_view' ref.package.pk %}"> {{ref.package}}</a></td>
8383
</tr>

vulnerabilities/views.py

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -20,69 +20,68 @@
2020
# VulnerableCode is a free software code scanning tool from nexB Inc. and others.
2121
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
2222

23-
from itertools import chain
24-
2523
from django.shortcuts import render
2624
from django.urls import reverse
27-
from django.http import HttpResponse
2825
from django.views.generic.list import ListView
2926
from django.views.generic.detail import DetailView
3027
from django.views.generic.edit import UpdateView
3128
from django.views.generic.edit import CreateView
3229
from django.views.generic.edit import DeleteView
3330
from django.views import View
3431

35-
from vulnerabilities.forms import PackageForm, VulnerabilitySearchForm
36-
from vulnerabilities.models import Package, ImpactedPackage, ResolvedPackage, VulnerabilityReference, Vulnerability
32+
from vulnerabilities import forms
33+
from vulnerabilities import models
3734

3835
class PackageSearchView(View):
39-
template_name = "packages.html"
36+
template_name = 'packages.html'
4037

4138
def get(self, request):
42-
context = {'form': PackageForm()}
39+
context = {'form': forms.PackageForm()}
4340

4441
if request.GET :
45-
packages = _to_queryset(request)
42+
packages = self.request_to_queryset(request)
4643
context['packages'] = packages
4744

4845
return render(request, self.template_name, context)
4946

50-
def _to_queryset(request):
51-
query = {}
52-
if len(request.GET['name']) :
53-
query['name'] = request.GET['name']
47+
@staticmethod
48+
def request_to_queryset(request):
49+
query = {}
50+
if len(request.GET['name']) :
51+
query['name'] = request.GET['name']
5452

55-
if request.GET['type'] and request.GET['type'] != '*' :
56-
query['type'] = request.GET['type']
53+
if request.GET['type'] and request.GET['type'] != '*' :
54+
query['type'] = request.GET['type']
5755

58-
if len(request.GET['version']) :
59-
query['version'] = request.GET['version']
56+
if len(request.GET['version']) :
57+
query['version'] = request.GET['version']
6058

61-
return Package.objects.all().filter(**query)
59+
return models.Package.objects.all().filter(**query)
6260

6361
class VulnerabilitySearchView(View):
6462

65-
template_name = "vulnerabilities.html"
63+
template_name = 'vulnerabilities.html'
6664

6765
def get(self, request):
68-
context = {'form' : VulnerabilitySearchForm() }
66+
context = {'form' : forms.VulnerabilitySearchForm() }
6967

7068
if request.GET :
71-
vulnerabilities = self._to_queryset(request)
69+
vulnerabilities = self.request_to_queryset(request)
7270
context['vulnerabilities'] = vulnerabilities
7371

7472
return render(request, self.template_name, context)
7573

76-
def _to_queryset(self,request):
74+
@staticmethod
75+
def request_to_queryset(request):
7776

7877
if request.GET['vuln_id'] :
7978
vuln_id = request.GET['vuln_id']
80-
return Vulnerability.objects.filter(cve_id__contains=vuln_id).select_related()
79+
return models.Vulnerability.objects.filter(cve_id__contains=vuln_id).select_related()
8180

8281
class PackageUpdate(UpdateView):
8382

84-
template_name = "package_update.html"
85-
model = Package
83+
template_name = 'package_update.html'
84+
model = models.Package
8685
fields = ['name', 'type', 'version', 'namespace']
8786

8887
def get_context_data(self, **kwargs):
@@ -95,8 +94,8 @@ def get_context_data(self, **kwargs):
9594

9695
def _package_vulnerabilities(self, package_pk) :
9796

98-
ip = ImpactedPackage.objects.filter(package_id=package_pk).select_related()
99-
rp = ResolvedPackage.objects.filter(package_id=package_pk).select_related()
97+
ip = models.PackageRelatedVulnerability.objects.filter(package_id=package_pk, is_vulnerable=True).select_related()
98+
rp = models.PackageRelatedVulnerability.objects.filter(package_id=package_pk, is_vulnerable=False).select_related()
10099

101100
resolved_vuln = [i.vulnerability for i in rp]
102101
unresolved_vuln = [i.vulnerability for i in ip]
@@ -109,20 +108,20 @@ def get_success_url(self):
109108

110109
class VulnerabilityDetails(ListView):
111110
template_name = 'vulnerability.html'
112-
model = VulnerabilityReference
111+
model = models.VulnerabilityReference
113112

114113
def get_context_data(self, **kwargs):
115114
context = super(VulnerabilityDetails, self).get_context_data(**kwargs)
116-
context['vulnerability'] = Vulnerability.objects.get(id=self.kwargs['pk'])
115+
context['vulnerability'] = models.Vulnerability.objects.get(id=self.kwargs['pk'])
117116
return context
118117

119118
def get_queryset(self):
120-
return VulnerabilityReference.objects.filter(vulnerability_id=self.kwargs['pk'])
119+
return models.VulnerabilityReference.objects.filter(vulnerability_id=self.kwargs['pk'])
121120

122121
class VulnerabilityCreate(CreateView):
123122

124-
template_name = "vulnerability_create.html"
125-
model = Vulnerability
123+
template_name = 'vulnerability_create.html'
124+
model = models.Vulnerability
126125
fields = ['cve_id', 'summary']
127126

128127
def get_success_url(self):
@@ -131,55 +130,60 @@ def get_success_url(self):
131130

132131
class PackageCreate(CreateView):
133132

134-
template_name = "package_create.html"
135-
model = Package
133+
template_name = 'package_create.html'
134+
model = models.Package
136135
fields = ['name','namespace','type','version']
137136

138137
def get_success_url(self):
139138
return reverse('package_view', kwargs={'pk' : self.object.id})
140139

140+
# TODO : Squash ImpactedPackageDelete ResolvedPackageDelete into one
141+
# 'PackageRelatedVulnerablityDelete' view
141142
class ResolvedPackageDelete(DeleteView):
142143

143-
model = ResolvedPackage
144+
model = models.PackageRelatedVulnerability
144145

145146
def get_object(self):
146147
package_id = self.kwargs.get('pid')
147148
vulnerability_id = self.kwargs.get('vid')
148-
return ResolvedPackage.objects.get(package_id=package_id, vulnerability_id=vulnerability_id)
149+
return models.PackageRelatedVulnerability.objects.get(package_id=package_id, vulnerability_id=vulnerability_id, is_vulnerable=False)
149150

150151
def get_success_url(self):
151152
return reverse('package_view', kwargs={'pk' : self.kwargs.get('pid')})
152153

153154
class ImpactedPackageDelete(DeleteView):
154155

155-
model = ImpactedPackage
156+
model = models.PackageRelatedVulnerability
156157

157158
def get_object(self):
158159
package_id = self.kwargs.get('pid')
159160
vulnerability_id = self.kwargs.get('vid')
160-
return ImpactedPackage.objects.get(package_id=package_id, vulnerability_id=vulnerability_id)
161+
return models.PackageRelatedVulnerability.objects.get(package_id=package_id, vulnerability_id=vulnerability_id, is_vulnerable=True)
161162

162163
def get_success_url(self):
163164
return reverse('package_view', kwargs={'pk' : self.kwargs.get('pid')})
164165

165166
class HomePage(View):
166167

167-
template_name = "index.html"
168+
template_name = 'index.html'
168169

169170
def get(self, request):
170171
return render(request, self.template_name)
171172

173+
# TODO : Squash ImpactedPackageCreate ResolvedPackageCreate into one
174+
# 'PackageRelatedVulnerablityCreate' view
172175

173176
class ImpactedPackageCreate(CreateView):
174177

175178
template_name = 'impacted_package_create.html'
176-
model = ImpactedPackage
179+
model = models.PackageRelatedVulnerability
177180
fields = ['vulnerability']
178181

179182
def form_valid(self, form):
180183

181-
package = Package.objects.get(id=self.kwargs['pid'])
184+
package = models.Package.objects.get(id=self.kwargs['pid'])
182185
form.instance.package = package
186+
form.instance.is_vulnerable = True
183187
return super(ImpactedPackageCreate, self).form_valid(form)
184188

185189
def get_success_url(self):
@@ -188,13 +192,14 @@ def get_success_url(self):
188192
class ResolvedPackageCreate(CreateView):
189193

190194
template_name = 'resolved_package_create.html'
191-
model = ResolvedPackage
195+
model = models.PackageRelatedVulnerability
192196
fields = ['vulnerability']
193197

194198
def form_valid(self, form):
195-
196-
package = Package.objects.get(id=self.kwargs['pid'])
199+
print(self.request)
200+
package = models.Package.objects.get(id=self.kwargs['pid'])
197201
form.instance.package = package
202+
form.instance.is_vulnerable = False
198203
return super(ResolvedPackageCreate, self).form_valid(form)
199204

200205
def get_success_url(self):
@@ -203,13 +208,12 @@ def get_success_url(self):
203208
class VulnerabilityReferenceCreate(CreateView):
204209

205210
template_name = 'vulnerability_reference_create.html'
206-
model = VulnerabilityReference
211+
model = models.VulnerabilityReference
207212
fields = ['reference_id','url']
208213

209214
def form_valid(self, form):
210-
form.instance.vulnerability = Vulnerability.objects.get(id=self.kwargs['vid'])
215+
form.instance.vulnerability = models.Vulnerability.objects.get(id=self.kwargs['vid'])
211216
return super(VulnerabilityReferenceCreate, self).form_valid(form)
212217

213218
def get_success_url(self):
214-
return reverse('vulnerability_view', kwargs={'pk': self.kwargs['vid']})
215-
219+
return reverse('vulnerability_view', kwargs={'pk': self.kwargs['vid']})

vulnerablecode/urls.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2017 nexB Inc. and others. All rights reserved.
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
33
# http://nexb.com and https://github.com/nexB/vulnerablecode/
44
# The VulnerableCode software is licensed under the Apache License version 2.0.
55
# Data generated with VulnerableCode require an acknowledgment.
@@ -18,7 +18,7 @@
1818
# OR CONDITIONS OF ANY KIND, either express or implied. No content created from
1919
# VulnerableCode should be considered or used as legal advice. Consult an Attorney
2020
# for any legal advice.
21-
# VulnerableCode is a free software code scanning tool from nexB Inc. and others.
21+
# VulnerableCode is a free software from nexB Inc. and others.
2222
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
2323

2424
from django.contrib import admin

0 commit comments

Comments
 (0)