Skip to content

Commit 5cb180c

Browse files
committed
Migrate pysec importer to aboutcode pipeline
Signed-off-by: Keshav Priyadarshi <[email protected]>
1 parent 2bac2e0 commit 5cb180c

File tree

5 files changed

+76
-56
lines changed

5 files changed

+76
-56
lines changed

vulnerabilities/importers/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
from vulnerabilities.importers import oss_fuzz
2727
from vulnerabilities.importers import postgresql
2828
from vulnerabilities.importers import project_kb_msr2019
29-
from vulnerabilities.importers import pysec
3029
from vulnerabilities.importers import redhat
3130
from vulnerabilities.importers import retiredotnet
3231
from vulnerabilities.importers import ruby
@@ -42,9 +41,9 @@
4241
from vulnerabilities.pipelines import npm_importer
4342
from vulnerabilities.pipelines import nvd_importer
4443
from vulnerabilities.pipelines import pypa_importer
44+
from vulnerabilities.pipelines import pysec_importer
4545

4646
IMPORTERS_REGISTRY = [
47-
pysec.PyPIImporter,
4847
alpine_linux.AlpineImporter,
4948
openssl.OpensslImporter,
5049
redhat.RedhatImporter,
@@ -78,6 +77,7 @@
7877
gitlab_importer.GitLabImporterPipeline,
7978
github_importer.GitHubAPIImporterPipeline,
8079
nvd_importer.NVDImporterPipeline,
80+
pysec_importer.PyPIImporterPipeline,
8181
]
8282

8383
IMPORTERS_REGISTRY = {

vulnerabilities/importers/pysec.py

Lines changed: 0 additions & 44 deletions
This file was deleted.

vulnerabilities/pipelines/pypa_importer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# See https://github.com/aboutcode-org/vulnerablecode for support or download.
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
9-
import logging
9+
1010
from pathlib import Path
1111
from typing import Iterable
1212

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
3+
# VulnerableCode is a trademark of nexB Inc.
4+
# SPDX-License-Identifier: Apache-2.0
5+
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
6+
# See https://github.com/aboutcode-org/vulnerablecode for support or download.
7+
# See https://aboutcode.org for more information about nexB OSS projects.
8+
#
9+
import json
10+
import logging
11+
from io import BytesIO
12+
from typing import Iterable
13+
from zipfile import ZipFile
14+
15+
import requests
16+
17+
from vulnerabilities.importer import AdvisoryData
18+
from vulnerabilities.importers.osv import parse_advisory_data
19+
from vulnerabilities.pipelines import VulnerableCodeBaseImporterPipeline
20+
21+
22+
class PyPIImporterPipeline(VulnerableCodeBaseImporterPipeline):
23+
"""Collect advisories from PyPI."""
24+
25+
pipeline_id = "pysec_importer"
26+
27+
license_url = "https://github.com/pypa/advisory-database/blob/main/LICENSE"
28+
url = "https://osv-vulnerabilities.storage.googleapis.com/PyPI/all.zip"
29+
spdx_license_expression = "CC-BY-4.0"
30+
importer_name = "PyPI Importer"
31+
32+
@classmethod
33+
def steps(cls):
34+
return (
35+
cls.fetch_zip,
36+
cls.collect_and_store_advisories,
37+
cls.import_new_advisories,
38+
)
39+
40+
def fetch_zip(self):
41+
self.log(f"Fetching `{self.url}`")
42+
self.advisory_zip = requests.get(self.url).content
43+
44+
def advisories_count(self) -> int:
45+
with ZipFile(BytesIO(self.advisory_zip)) as zip:
46+
advisory_count = sum(1 for file in zip.namelist() if file.startswith("PYSEC-"))
47+
return advisory_count
48+
49+
def collect_advisories(self) -> Iterable[AdvisoryData]:
50+
"""Yield AdvisoryData using a zipped data dump of OSV data"""
51+
with ZipFile(BytesIO(self.advisory_zip)) as zip_file:
52+
for file_name in zip_file.namelist():
53+
if not file_name.startswith("PYSEC-"):
54+
self.log(
55+
f"Unsupported PyPI advisory data file: {file_name}",
56+
level=logging.ERROR,
57+
)
58+
continue
59+
with zip_file.open(file_name) as f:
60+
vul_info = json.load(f)
61+
yield parse_advisory_data(
62+
raw_data=vul_info,
63+
supported_ecosystems=["pypi"],
64+
advisory_url=self.url,
65+
)

vulnerabilities/tests/test_pysec.py renamed to vulnerabilities/tests/pipelines/test_pysec_importer_pipeline.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,52 +7,51 @@
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
99
import json
10-
import os
10+
from pathlib import Path
1111
from unittest import TestCase
1212

1313
from vulnerabilities.importers.osv import parse_advisory_data
1414
from vulnerabilities.tests.util_tests import VULNERABLECODE_REGEN_TEST_FIXTURES as REGEN
1515
from vulnerabilities.tests.util_tests import check_results_against_json
1616

17-
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
18-
TEST_DATA = os.path.join(BASE_DIR, "test_data/pysec")
17+
TEST_DATA = Path(__file__).parent.parent / "test_data" / "pysec"
1918

2019

2120
class TestPyPIImporter(TestCase):
2221
def test_to_advisories_with_summary(self):
23-
with open(os.path.join(TEST_DATA, "pysec-advisories_with_summary.json")) as f:
22+
with open(TEST_DATA / "pysec-advisories_with_summary.json") as f:
2423
mock_response = json.load(f)
2524
results = parse_advisory_data(mock_response, ["pypi"], "https://test.com").to_dict()
2625

27-
expected_file = os.path.join(TEST_DATA, "pysec-advisories_with_summary-expected.json")
26+
expected_file = TEST_DATA / "pysec-advisories_with_summary-expected.json"
2827
check_results_against_json(
2928
results=results,
3029
expected_file=expected_file,
3130
regen=REGEN,
3231
)
3332

3433
def test_to_advisories_without_summary(self):
35-
with open(os.path.join(TEST_DATA, "pysec-advisories_without_summary.json")) as f:
34+
with open(TEST_DATA / "pysec-advisories_without_summary.json") as f:
3635
mock_response = json.load(f)
3736

3837
results = parse_advisory_data(mock_response, ["pypi"], "https://test.com").to_dict()
3938

40-
expected_file = os.path.join(TEST_DATA, "pysec-advisories_without_summary-expected.json")
39+
expected_file = TEST_DATA / "pysec-advisories_without_summary-expected.json"
4140
check_results_against_json(
4241
results=results,
4342
expected_file=expected_file,
4443
regen=REGEN,
4544
)
4645

4746
def test_to_advisories_with_cwe(self):
48-
with open(os.path.join(TEST_DATA, "pysec-advisory_with_cwe.json")) as f:
47+
with open(TEST_DATA / "pysec-advisory_with_cwe.json") as f:
4948
mock_response = json.load(f)
5049

5150
results = parse_advisory_data(
5251
raw_data=mock_response, supported_ecosystems=["pypi"], advisory_url="https://tes.com"
5352
).to_dict()
5453

55-
expected_file = os.path.join(TEST_DATA, "pysec-advisories_with_cwe-expected.json")
54+
expected_file = TEST_DATA / "pysec-advisories_with_cwe-expected.json"
5655
check_results_against_json(
5756
results=results,
5857
expected_file=expected_file,

0 commit comments

Comments
 (0)