def __enter__(self): super(NpmDataSource, self).__enter__() if not getattr(self, "_added_files", None): self._added_files, self._updated_files = self.file_changes( recursive=True, file_ext="json", subdir="./vuln/npm") self._versions = NpmVersionAPI() self.set_api(self.collect_packages())
class NpmDataSource(GitDataSource): def __enter__(self): super(NpmDataSource, self).__enter__() if not getattr(self, "_added_files", None): self._added_files, self._updated_files = self.file_changes( recursive=True, file_ext="json", subdir="./vuln/npm" ) self._versions = NpmVersionAPI() self.set_api(self.collect_packages()) def updated_advisories(self) -> Set[Advisory]: files = self._updated_files.union(self._added_files) advisories = [] for f in files: processed_data = self.process_file(f) if processed_data: advisories.extend(processed_data) return self.batch_advisories(advisories) def set_api(self, packages): asyncio.run(self._versions.load_api(packages)) def collect_packages(self): packages = set() files = self._updated_files.union(self._added_files) for f in files: data = load_json(f) packages.add(data["module_name"].strip()) return packages @property def versions(self): # quick hack to make it patchable return self._versions def process_file(self, file) -> List[Advisory]: record = load_json(file) advisories = [] package_name = record["module_name"].strip() all_versions = self.versions.get(package_name) aff_range = record.get("vulnerable_versions", "") fixed_range = record.get("patched_versions", "") impacted_versions, resolved_versions = categorize_versions( all_versions, aff_range, fixed_range ) impacted_purls = _versions_to_purls(package_name, impacted_versions) resolved_purls = _versions_to_purls(package_name, resolved_versions) vuln_reference = [ Reference( url=NPM_URL.format(f'/-/npm/v1/advisories/{record["id"]}'), reference_id=record["id"], ) ] for cve_id in record.get("cves") or [""]: advisories.append( Advisory( summary=record.get("overview", ""), cve_id=cve_id, impacted_package_urls=impacted_purls, resolved_package_urls=resolved_purls, vuln_references=vuln_reference, ) ) return advisories
from unittest.mock import patch import zipfile from django.test import TestCase from vulnerabilities import models from vulnerabilities.import_runner import ImportRunner from vulnerabilities.package_managers import NpmVersionAPI from vulnerabilities.importers.npm import categorize_versions BASE_DIR = os.path.dirname(os.path.abspath(__file__)) TEST_DATA = os.path.join(BASE_DIR, 'test_data/') MOCK_VERSION_API = NpmVersionAPI( cache={ 'jquery': {'3.4', '3.8'}, 'kerberos': {'0.5.8', '1.2'}, '@hapi/subtext': {'3.7', '4.1.1', '6.1.3', '7.0.0', '7.0.5'}, }) @patch('vulnerabilities.importers.NpmDataSource._update_from_remote') class NpmImportTest(TestCase): tempdir = None @classmethod def setUpClass(cls) -> None: cls.tempdir = tempfile.mkdtemp() zip_path = os.path.join(TEST_DATA, 'npm.zip') with zipfile.ZipFile(zip_path, "r") as zip_ref:
from django.test import TestCase from vulnerabilities import models from vulnerabilities.import_runner import ImportRunner from vulnerabilities.package_managers import NpmVersionAPI from vulnerabilities.importers.npm import categorize_versions BASE_DIR = os.path.dirname(os.path.abspath(__file__)) TEST_DATA = os.path.join(BASE_DIR, "test_data/") MOCK_VERSION_API = NpmVersionAPI( cache={ "jquery": {"3.4.0", "3.8.0"}, "kerberos": {"0.5.8", "1.2.0"}, "@hapi/subtext": {"3.7.0", "4.1.1", "6.1.3", "7.0.0", "7.0.5"}, } ) @patch("vulnerabilities.importers.NpmDataSource._update_from_remote") class NpmImportTest(TestCase): tempdir = None @classmethod def setUpClass(cls) -> None: cls.tempdir = tempfile.mkdtemp() zip_path = os.path.join(TEST_DATA, "npm.zip")