Skip to content

Commit b8c1eea

Browse files
committed
Enable purl slug for package views #904
* Use purl slug and URL route for packages * Use in forms, urls and templates, including a get_absolute_url() method. * Rename VulnerabiltyForm forms to VulnerabiltySearchForm * Rename PackageForm forms to PackageSearchForm * Use new pagination template includes in search results templates. The pagination is the same repeated at the top and botton of the search results * Display on 20 search results per page. Signed-off-by: Philippe Ombredanne <[email protected]>
1 parent 6504321 commit b8c1eea

File tree

14 files changed

+309
-450
lines changed

14 files changed

+309
-450
lines changed

CHANGELOG.rst

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@ Version v30.0.0
1111
are available.
1212
Because of these extensive changes, it is not possible to migrate existing imported
1313
data to the new schema. You will need instead to restart imports from an empty database
14-
or request access to the new vulnerablecode.io live instance.
15-
You can track the progress in this issue: https://github.com/nexB/vulnerablecode/issues/597
14+
or access the new public.vulnerablecode.io live instance. We also provide a database dump.
15+
16+
- You can track the progress of this refactoring in this issue:
17+
https://github.com/nexB/vulnerablecode/issues/597
1618

1719
- We added new data sources including PYSEC, GitHub and GitLab.
1820

1921
- We improved the documentation including adding development examples for importers and improvers.
2022

2123
- We removed the ability to edit relationships from the UI. The UI is now read-only.
24+
2225
- We replace the web UI with a brand new UI based on the same overall look and feel as ScanCode.io.
2326

2427
- We added support for NixOS as a Linux deployment target.
@@ -42,15 +45,17 @@ Version v30.0.0
4245
- Add new attribute `is_resolved`
4346
- Add namespace filter
4447

45-
- We have provided backward compatibility for `url` and `unresolved_vulnerabilities` for now
48+
- We have provided backward compatibility for `url` and `unresolved_vulnerabilities` for now.
49+
These will be removed in the next major version and should be considered as deprecated.
4650

47-
- There is a new experimental cpe/ API endpoint to lookup for vulnerabilities by CPE and
51+
- There is a new experimental `cpe/` API endpoint to lookup for vulnerabilities by CPE and
4852
another aliases/ endpoint to lookup for vulnerabilities by aliases. These two endpoints will be
4953
replaced by query parameters on the main vulnerabilities/ endpoint when stabilized.
5054

51-
- Added filters for vulnerabilities endpoint to get fixed packages in accordance to the details given in filters:
52-
For example, when you call the endpoint this way ``/api/vulnerabilities?type=pypi&namespace=foo&name=bar``,
53-
you will receive only fixed versioned purls of the type ``pypi``, namespace ``foo`` and name ``bar``.
55+
- Added filters for vulnerabilities endpoint to get fixed packages in accordance
56+
to the details given in filters: For example, when you call the endpoint this way
57+
``/api/vulnerabilities?type=pypi&namespace=foo&name=bar``, you will receive only
58+
fixed versioned purls of the type ``pypi``, namespace ``foo`` and name ``bar``.
5459

5560
- Package endpoint will give fixed packages of only those that
5661
matches type, name, namespace, subpath and qualifiers of the package queried.
@@ -71,8 +76,8 @@ Version v30.0.0
7176

7277
Other:
7378

74-
- we dropped calver to use a plain semver.
75-
- we adopted vers and the new univers library to handle version ranges.
79+
- We dropped calver to use a plain semver.
80+
- We adopted vers and the new univers library to handle version ranges.
7681

7782

7883
Version v20.10

vulnerabilities/forms.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,8 @@
99

1010
from django import forms
1111

12-
from vulnerabilities.models import Package
1312

14-
15-
def get_known_package_types():
16-
"""
17-
Return a list of known package types.
18-
"""
19-
pkg_types = [(i.type, i.type) for i in Package.objects.distinct("type").all()]
20-
pkg_types.append((None, "Any type"))
21-
return pkg_types
22-
23-
24-
class PackageForm(forms.Form):
13+
class PackageSearchForm(forms.Form):
2514

2615
search = forms.CharField(
2716
required=True,
@@ -31,7 +20,7 @@ class PackageForm(forms.Form):
3120
)
3221

3322

34-
class VulnerabilityForm(forms.Form):
23+
class VulnerabilitySearchForm(forms.Form):
3524

3625
search = forms.CharField(
3726
required=True,

vulnerabilities/models.py

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@
1212
import logging
1313

1414
from django.conf import settings
15-
from django.core.exceptions import ValidationError
1615
from django.core.validators import MaxValueValidator
1716
from django.core.validators import MinValueValidator
1817
from django.db import models
1918
from django.dispatch import receiver
2019
from django.urls import reverse
21-
from packageurl import PackageURL
2220
from packageurl.contrib.django.models import PackageURLMixin
2321
from rest_framework.authtoken.models import Token
2422

@@ -98,7 +96,7 @@ def get_absolute_url(self):
9896
"""
9997
Return this Vulnerability details URL.
10098
"""
101-
return reverse("vulnerability_view", args=[self.vulnerability_id])
99+
return reverse("vulnerability_details", args=[self.vulnerability_id])
102100

103101

104102
class VulnerabilityReference(models.Model):
@@ -155,10 +153,6 @@ class Package(PackageURLMixin):
155153
A software package with related vulnerabilities.
156154
"""
157155

158-
vulnerabilities = models.ManyToManyField(
159-
to="Vulnerability", through="PackageRelatedVulnerability"
160-
)
161-
162156
# Remove the `qualifers` and `set_package_url` overrides after
163157
# https://github.com/package-url/packageurl-python/pull/35
164158
# https://github.com/package-url/packageurl-python/pull/67
@@ -171,6 +165,14 @@ class Package(PackageURLMixin):
171165
null=False,
172166
)
173167

168+
vulnerabilities = models.ManyToManyField(
169+
to="Vulnerability", through="PackageRelatedVulnerability"
170+
)
171+
172+
@property
173+
def purl(self):
174+
return self.package_url
175+
174176
class Meta:
175177
unique_together = (
176178
"type",
@@ -221,28 +223,11 @@ def is_vulnerable(self):
221223
"""
222224
return self.vulnerable_to.exists()
223225

224-
def set_package_url(self, package_url):
225-
"""
226-
Set each field values to the values of the provided `package_url` string
227-
or PackageURL object. Existing values are overwritten including setting
228-
values to None for provided empty values.
229-
"""
230-
if not isinstance(package_url, PackageURL):
231-
package_url = PackageURL.from_string(package_url)
232-
233-
for field_name, value in package_url.to_dict().items():
234-
model_field = self._meta.get_field(field_name)
235-
236-
if value and len(value) > model_field.max_length:
237-
raise ValidationError(f'Value too long for field "{field_name}".')
238-
239-
setattr(self, field_name, value or None)
240-
241226
def get_absolute_url(self):
242227
"""
243228
Return this Package details URL.
244229
"""
245-
return reverse("package_view", args=[self.package_url])
230+
return reverse("package_details", args=[self.purl])
246231

247232

248233
class PackageRelatedVulnerability(models.Model):
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<nav class="pagination is-centered is-small" aria-label="pagination">
2+
{% if page_obj.has_previous %}
3+
<a href="?page={{ page_obj.previous_page_number }}&search={{ search }}" class="pagination-previous">Previous</a>
4+
{% else %}
5+
<a class="pagination-previous" disabled>Previous</a>
6+
{% endif %}
7+
8+
{% if page_obj.has_next %}
9+
<a href="?page={{ page_obj.next_page_number }}&search={{ search }}" class="pagination-next">Next</a>
10+
{% else %}
11+
<a class="pagination-next" disabled>Next</a>
12+
{% endif %}
13+
14+
<ul class="pagination-list">
15+
{% if page_obj.number != 1%}
16+
<li>
17+
<a href="?page=1&search={{ search }}" class="pagination-link" aria-label="Goto page 1">1</a>
18+
</li>
19+
{% if page_obj.number > 2 %}
20+
<li>
21+
<span class="pagination-ellipsis">&hellip;</span>
22+
</li>
23+
{% endif %}
24+
{% endif %}
25+
<li>
26+
<a class="pagination-link is-current" aria-label="Page {{ page_obj.number }}" aria-current="page">{{ page_obj.number }}</a>
27+
</li>
28+
{% if page_obj.number != page_obj.paginator.num_pages %}
29+
{% if page_obj.next_page_number != page_obj.paginator.num_pages %}
30+
<li>
31+
<span class="pagination-ellipsis">&hellip;</span>
32+
</li>
33+
{% endif %}
34+
<li>
35+
<a href="?page={{ page_obj.paginator.num_pages }}&search={{ search }}" class="pagination-link" aria-label="Goto page {{ page_obj.paginator.num_pages }}">{{ page_obj.paginator.num_pages }}</a>
36+
</li>
37+
{% endif %}
38+
</ul>
39+
</nav>

0 commit comments

Comments
 (0)