8000 Lookup in PurlDB by purl in Add Package by tdruez · Pull Request #47 · aboutcode-org/dejacode · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Lookup in PurlDB by purl in Add Package #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ Release notes

### Version 5.0.2-dev

- Lookup in PurlDB by purl in Add Package form.
When a Package URL is available in the context of the "Add Package" form,
for example when using a link from the Vulnerabilities tab,
data is fetched from the PurlDB to initialize the form.
https://github.com/nexB/dejacode/issues/47

### Version 5.0.1

- Improve the stability of the "Check for new Package versions" feature.
Expand Down
47 changes: 47 additions & 0 deletions component_catalog/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3654,6 +3654,53 @@ def test_component_catalog_package_add_view_create_proper(self):
expected = "Package "name.zip" was successfully created."
self.assertContains(response, expected)

@mock.patch("dejacode_toolkit.purldb.PurlDB.request_get")
@mock.patch("dejacode_toolkit.purldb.PurlDB.is_configured")
def test_component_catalog_package_add_view_initial_data(
self, mock_is_configured, mock_request_get
):
self.client.login(username=self.super_user.username, password="secret")
add_url = reverse("component_catalog:package_add")

mock_is_configured.return_value = True
self.dataspace.enable_purldb_access = True
self.dataspace.save()

puyrldb_entry = {
"filename": "abbot-1.4.0.jar",
"release_date": "2015-09-22",
"type": "maven",
"namespace": "abbot",
"name": "abbot",
"version": "1.4.0",
"qualifiers": "",
"subpath": "",
"primary_language": "Java",
"description": "Abbot Java GUI Test Library",
"declared_license_expression": "bsd-new OR eps-1.0 OR apache-2.0 OR mit",
}
mock_request_get.return_value = {
"count": 1,
"results": [puyrldb_entry],
}

response = self.client.get(add_url)
self.assertEqual({}, response.context["form"].initial)

response = self.client.get(add_url + "?package_url=pkg:maven/abbot/abbot@1.4.0")
expected = {
"filename": "abbot-1.4.0.jar",
"release_date": "2015-09-22",
"type": "maven",
"namespace": "abbot",
"name": "abbot",
"version": "1.4.0",
"primary_language": "Java",
"description": "Abbot Java GUI Test Library",
"license_expression": "bsd-new OR eps-1.0 OR apache-2.0 OR mit",
}
self.assertEqual(expected, response.context["form"].initial)

@mock.patch("dje.tasks.scancodeio_submit_scan.delay")
@mock.patch("dejacode_toolkit.scancodeio.ScanCodeIO.is_configured")
def test_component_catalog_package_add_view_create_with_submit_scan(
Expand Down
42 changes: 35 additions & 7 deletions component_catalog/views.py
10000
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core import signing
from django.core.validators import EMPTY_VALUES
from django.db.models import Prefetch
from django.http import FileResponse
from django.http import Http404
Expand All @@ -45,6 +46,7 @@
from natsort import natsorted
from notifications.signals import notify
from packageurl import PackageURL
from packageurl.contrib import purl2url
from packageurl.contrib import url2purl

from component_catalog.filters import ComponentFilterSet
Expand Down Expand Up @@ -1896,26 +1898,52 @@ def get_initial(self):
"""Pre-fill the form with initial data from a PurlDB entry or a `package_url`."""
initial = super().get_initial()

purldb_uuid = self.request.GET.get("purldb_uuid", None)
if purldb_uuid:
purldb_entry = PurlDB(self.request.user).get_package(purldb_uuid)
if purldb_entry := self.get_entry_from_purldb():
purldb_entry["license_expression"] = purldb_entry.get("declared_license_expression")
model_fields = [field.name for field in Package._meta.get_fields()]
model_fields = [
field.name
for field in Package._meta.get_fields()
# Generic keywords are not supported because of validation
if field.name != "keywords"
]
initial_from_purldb_entry = {
field_name: value
for field_name, value in purldb_entry.items()
if value and field_name in model_fields
if value not in EMPTY_VALUES and field_name in model_fields
}
initial.update(initial_from_purldb_entry)
messages.info(self.request, "Initial data fetched from PurlDB.")

package_url = self.request.GET.get("package_url", None)
if package_url:
elif package_url := self.request.GET.get("package_url", None):
purl = PackageURL.from_string(package_url)
package_url_dict = purl.to_dict(encode=True, empty="")
initial.update(package_url_dict)
if download_url := purl2url.get_download_url(package_url):
initial.update({"download_url": download_url})

return initial

def get_entry_from_purldb(self):
user = self.request.user
purldb = PurlDB(user)
is_purldb_enabled = all(
[
purldb.is_configured(),
user.dataspace.enable_purldb_access,
]
)

if not is_purldb_enabled:
return

purldb_uuid = self.request.GET.get("purldb_uuid", None)
package_url = self.request.GET.get("package_url", None)

if purldb_uuid:
return purldb.get_package(purldb_uuid)
elif package_url:
return purldb.get_package_by_purl(package_url)

def get_success_message(self, cleaned_data):
success_message = super().get_success_message(cleaned_data)

Expand Down
5 changes: 5 additions & 0 deletions dejacode_toolkit/purldb.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ def get_package(self, uuid):
"""Get a Package details entry providing its `uuid`."""
return self.request_get(url=f"{self.package_api_url}{uuid}/")

def get_package_by_purl(self, package_url):
"""Get a Package details entry providing its `package_url`."""
if results := self.find_packages({"purl": package_url}):
return results[0]

def find_packages(self, payload, timeout=None):
"""Get Packages details using provided `payload` filters on the PurlDB package list."""
response = self.request_get(self.package_api_url, params=payload, timeout=timeout)
Expand Down
2 changes: 1 addition & 1 deletion dje/templates/includes/messages_alert.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% for message in messages %}
{% if wrapper_classes %}<div class="{{ wrapper_classes }}">{% endif %}
<div class="alert alert-{% if message.level_tag == 'error' %}danger{% else %}{{ message.level_tag }}{% endif %} alert-dismissible" role="alert">
<div class="alert alert-{% if message.level_tag == 'error' %}danger{% elif message.level_tag == 'info' %}primary{% else %}{{ message.level_tag }}{% endif %} alert-dismissible" role="alert">
<strong>{{ message.level_tag|title }}:</strong> {{ message|linebreaksbr }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
Expand Down
5 changes: 4 additions & 1 deletion dje/templates/object_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ <h1 class="header-title">
</div>
</div>

{% include 'includes/form_errors_alert.html' %}
{% block messages-alert %}
{% include 'includes/form_errors_alert.html' %}
{% include 'includes/messages_alert.html' with wrapper_classes='container p-0' %}
{% endblock %}

<div class="card card-border-color card-border-color-primary">
<div class="card-body bg-light p-4">
Expand Down
0