Skip to content
Open
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
11 changes: 6 additions & 5 deletions vulntotal/datasources/oss_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@
class OSSDataSource(DataSource):
spdx_license_expression = "TODO"
license_url = "TODO"
api_unauthenticated = "https://ossindex.sonatype.org/api/v3/component-report"
api_authenticated = "https://ossindex.sonatype.org/api/v3/authorized/component-report"
api_unauthenticated = "https://api.guide.sonatype.com/api/v3/component-report"
api_authenticated = "https://api.guide.sonatype.com/api/v3/authorized/component-report"

def fetch_json_response(self, coordinates):
"""Fetch JSON response from OSS Index API for a given list of coordinates.
"""Fetch JSON response from the Sonatype Guide OSS Index compatibility API.

Parameters:
coordinates: A list of strings representing the package coordinates.

Returns:
A dictionary containing the JSON response from the OSS Index API, or None if the response is unsuccessful or an error occurs while fetching data.
A dictionary containing the JSON response from the compatibility API, or None
if the response is unsuccessful or an error occurs while fetching data.
"""
username = os.environ.get("OSS_USERNAME", None)
token = os.environ.get("OSS_TOKEN", None)
Expand Down Expand Up @@ -91,7 +92,7 @@ def supported_ecosystem(cls):

def parse_advisory(component, purl) -> Iterable[VendorData]:
"""
Parse component from OSS Index API and yield VendorData.
Parse component from the Sonatype Guide OSS Index compatibility API and yield VendorData.

Parameters:
component: A list containing a dictionary with component details.
Expand Down
36 changes: 36 additions & 0 deletions vulntotal/tests/test_oss_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import json
from pathlib import Path
from unittest.mock import patch

from commoncode import testcase
from packageurl import PackageURL
Expand All @@ -20,6 +21,41 @@
class TestDeps(testcase.FileBasedTesting):
test_data_dir = str(Path(__file__).resolve().parent / "test_data" / "oss_index")

def test_fetch_json_response_uses_sonatype_guide_compatibility_api(self):
coordinates = ["pkg:pypi/[email protected]"]
datasource = oss_index.OSSDataSource()

with patch.object(oss_index.requests, "post") as mock_post:
mock_response = mock_post.return_value
mock_response.raise_for_status.return_value = None
mock_response.json.return_value = []

assert datasource.fetch_json_response(coordinates) == []

mock_post.assert_called_once_with(
"https://api.guide.sonatype.com/api/v3/component-report",
auth=None,
json={"coordinates": coordinates},
)

def test_fetch_json_response_uses_authenticated_sonatype_guide_compatibility_api(self):
coordinates = ["pkg:pypi/[email protected]"]
datasource = oss_index.OSSDataSource()

with patch.dict(oss_index.os.environ, {"OSS_USERNAME": "user", "OSS_TOKEN": "token"}):
with patch.object(oss_index.requests, "post") as mock_post:
mock_response = mock_post.return_value
mock_response.raise_for_status.return_value = None
mock_response.json.return_value = []

assert datasource.fetch_json_response(coordinates) == []

mock_post.assert_called_once_with(
"https://api.guide.sonatype.com/api/v3/authorized/component-report",
auth=("user", "token"),
json={"coordinates": coordinates},
)

def test_parse_advisory(self):
advisory_file = self.get_test_loc("advisory.json")
with open(advisory_file) as f:
Expand Down