launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #33152
[Merge] ~ines-almeida/launchpad:add-uct-handler-get-imports-exports into launchpad:master
Ines Almeida has proposed merging ~ines-almeida/launchpad:add-uct-handler-get-imports-exports into launchpad:master.
Commit message:
Add UCT as optional handler for getImports & getExports
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~ines-almeida/launchpad/+git/launchpad/+merge/494673
Besides the modified tests, all tests with 'cve' and 'test_uct' in the name passed
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~ines-almeida/launchpad:add-uct-handler-get-imports-exports into launchpad:master.
diff --git a/lib/lp/bugs/model/tests/test_vulnerability.py b/lib/lp/bugs/model/tests/test_vulnerability.py
index 0e00d1c..2e49aa8 100644
--- a/lib/lp/bugs/model/tests/test_vulnerability.py
+++ b/lib/lp/bugs/model/tests/test_vulnerability.py
@@ -12,6 +12,7 @@ from zope.component import getUtility
from zope.security.interfaces import Unauthorized
from zope.security.proxy import removeSecurityProxy
+from testscenarios.testcase import WithScenarios
from lp.app.enums import InformationType
from lp.app.errors import (
IncompatibleArguments,
@@ -39,6 +40,7 @@ from lp.bugs.model.importvulnerabilityjob import ImportVulnerabilityJob
from lp.bugs.model.vulnerability import (
VULNERABILITY_EXPORT_HANDLER_ENABLED_FEATURE_FLAG,
VULNERABILITY_IMPORT_HANDLER_ENABLED_FEATURE_FLAG,
+ IDistributionSet,
UnauthorizedVulnerabilityHandler,
)
from lp.bugs.model.vulnerabilitysubscription import VulnerabilitySubscription
@@ -1614,45 +1616,85 @@ class TestVulnerabilitySetWebService(TestCaseWithFactory):
self.assertEqual(200, response.status)
-class TestVulnerabilityGetJobs(TestCaseWithFactory):
+class TestVulnerabilityGetJobs(WithScenarios, TestCaseWithFactory):
"""Tests for collecting export vulnerability job info."""
layer = LaunchpadZopelessLayer
+
+ scenarios = [
+ ("soss", {
+ "handler": VulnerabilityHandlerEnum.SOSS,
+ "name": "soss",
+ "distribution_name": "soss",
+ "cve_key": "2025-1979",
+ }),
+ ("uct", {
+ "handler": VulnerabilityHandlerEnum.UCT,
+ "name": "uct",
+ "distribution_name": "ubuntu",
+ "cve_key": "2025-0001",
+ })
+ ]
+
def setUp(self):
super().setUp()
self.requester = self.factory.makePerson()
- self.handler = VulnerabilityHandlerEnum.SOSS
- self.cve_path = (
- Path(__file__).parent
- / ".."
- / ".."
- / "scripts"
- / "soss"
- / "tests"
- / "sampledata"
- / "CVE-2025-1979"
- )
self.repository = self.factory.makeGitRepository()
self.refs = self.factory.makeGitRefs(
repository=self.repository,
paths=("ref/heads/main", "ref/tags/v1.0"),
)
+
+ if self.name == "uct":
+ self.distribution = getUtility(IDistributionSet).getByName(self.distribution_name)
+ self.distribution.security_admin = self.requester
+
+ # Create data from UCT CVE file
+ distroseries = self.factory.makeDistroSeries(
+ name="xenial",
+ distribution=self.distribution,
+ )
+ sourcepackagename = self.factory.makeSourcePackageName("gbrowse")
+ sp = self.factory.makeSourcePackage(
+ distroseries=distroseries,
+ publish=True,
+ sourcepackagename=sourcepackagename,
+ )
+
+ else:
+ self.distribution = self.factory.makeDistribution(
+ name=self.distribution_name,
+ owner=self.requester,
+ )
def _create_import_job(self):
"""Helper to create a single ImportVulnerabilityJob."""
- with open(self.cve_path, encoding="utf-8") as file:
+
+ cve_name = "CVE-" + self.cve_key
+ cve_path = (
+ Path(__file__).parent
+ / ".."
+ / ".."
+ / "scripts"
+ / self.name
+ / "tests"
+ / "sampledata"
+ / cve_name
+ )
+
+ with open(cve_path, "rb") as file:
self.useFixture(
GitHostingFixture(
blob=file.read(),
refs=self.refs,
- diff_stats={"added": ["cves/CVE-2025-1979"]},
+ diff_stats={"added": [f"cves/{cve_name}"]},
)
)
job = getUtility(IImportVulnerabilityJobSource).create(
- handler=VulnerabilityHandlerEnum.SOSS,
+ handler=self.handler,
git_repository=self.repository.id,
git_ref="ref/tags/v1.0",
git_paths=["cves"],
@@ -1673,15 +1715,14 @@ class TestVulnerabilityGetJobs(TestCaseWithFactory):
import_job.job.complete()
job = getUtility(IExportVulnerabilityJobSource).create(
- handler=VulnerabilityHandlerEnum.SOSS,
+ handler=self.handler,
)
return job
def test_getImports(self):
"""Test getImports function runs as expected."""
- self.factory.makeCVE("2025-1979")
- self.factory.makeDistribution(name="soss", owner=self.requester)
+ self.factory.makeCVE(self.cve_key)
job = self._create_import_job()
@@ -1710,8 +1751,7 @@ class TestVulnerabilityGetJobs(TestCaseWithFactory):
def test_getImports_full(self):
"""Test retrieval of exactly 10 import jobs."""
- self.factory.makeCVE("2025-1979")
- self.factory.makeDistribution(name="soss", owner=self.requester)
+ self.factory.makeCVE(self.cve_key)
jobs = []
@@ -1748,8 +1788,7 @@ class TestVulnerabilityGetJobs(TestCaseWithFactory):
def test_getImports_more_than_10(self):
"""Test that only the last 10 import jobs are returned."""
- self.factory.makeCVE("2025-1979")
- self.factory.makeDistribution(name="soss", owner=self.requester)
+ self.factory.makeCVE(self.cve_key)
jobs = []
@@ -1787,8 +1826,13 @@ class TestVulnerabilityGetJobs(TestCaseWithFactory):
def test_getImports_unauthenticated(self):
"""Test imports fail when requester lacks handler rights."""
- self.factory.makeCVE("2025-1979")
- self.factory.makeDistribution(name="soss")
+ self.factory.makeCVE(self.cve_key)
+
+ # Remove permissions
+ if self.name == "uct":
+ self.distribution.security_admin = self.factory.makePerson()
+ else:
+ self.distribution.owner = self.factory.makePerson()
job = self._create_import_job()
@@ -1804,8 +1848,7 @@ class TestVulnerabilityGetJobs(TestCaseWithFactory):
def test_getExports(self):
"""Test getExports function runs as expected."""
- self.factory.makeCVE("2025-1979")
- self.factory.makeDistribution(name="soss", owner=self.requester)
+ self.factory.makeCVE(self.cve_key)
job = self._create_export_job()
@@ -1835,9 +1878,7 @@ class TestVulnerabilityGetJobs(TestCaseWithFactory):
def test_getExports_full(self):
"""Test retrieval of exactly 10 export jobs."""
- self.factory.makeCVE("2025-1979")
- self.factory.makeDistribution(name="soss", owner=self.requester)
-
+ self.factory.makeCVE(self.cve_key)
jobs = []
for _ in range(10):
@@ -1873,8 +1914,7 @@ class TestVulnerabilityGetJobs(TestCaseWithFactory):
def test_getExports_more_than_10(self):
"""Test that only the last 10 export jobs are returned."""
- self.factory.makeCVE("2025-1979")
- self.factory.makeDistribution(name="soss", owner=self.requester)
+ self.factory.makeCVE(self.cve_key)
jobs = []
@@ -1913,8 +1953,13 @@ class TestVulnerabilityGetJobs(TestCaseWithFactory):
def test_getExports_unauthenticated(self):
"""Test exports fail when requester lacks handler rights."""
- self.factory.makeCVE("2025-1979")
- self.factory.makeDistribution(name="soss")
+ self.factory.makeCVE(self.cve_key)
+
+ # Remove permissions
+ if self.name == "uct":
+ self.distribution.security_admin = self.factory.makePerson()
+ else:
+ self.distribution.owner = self.factory.makePerson()
job = self._create_export_job()
diff --git a/lib/lp/bugs/model/vulnerability.py b/lib/lp/bugs/model/vulnerability.py
index ffc3402..81807c3 100644
--- a/lib/lp/bugs/model/vulnerability.py
+++ b/lib/lp/bugs/model/vulnerability.py
@@ -576,14 +576,21 @@ class VulnerabilitySet:
):
from lp.bugs.model.importvulnerabilityjob import ImportVulnerabilityJob
from lp.bugs.model.vulnerabilityjob import VulnerabilityJob
- from lp.bugs.scripts.soss.sossimport import SOSSImporter
distribution = getUtility(IDistributionSet).getByName(
HANDLER_DISTRIBUTION_MAP.get(handler)
)
if handler == VulnerabilityHandlerEnum.SOSS:
+ from lp.bugs.scripts.soss.sossimport import SOSSImporter
+
importer = SOSSImporter(distribution)
+
+ elif handler == VulnerabilityHandlerEnum.UCT:
+ from lp.bugs.scripts.uct.uctimport import UCTImporter
+
+ importer = UCTImporter(distribution)
+
else:
raise NotFoundError(f"{handler} not found")
@@ -616,6 +623,11 @@ class VulnerabilitySet:
exporter = SOSSExporter()
+ elif handler == VulnerabilityHandlerEnum.UCT:
+ from lp.bugs.scripts.uct.uctexport import UCTExporter
+
+ exporter = UCTExporter()
+
else:
raise NotFoundError(f"{handler} not found")
diff --git a/lib/lp/bugs/scripts/uct/tests/sampledata/CVE-2025-0001 b/lib/lp/bugs/scripts/uct/tests/sampledata/CVE-2025-0001
new file mode 100644
index 0000000..a65c6f4
--- /dev/null
+++ b/lib/lp/bugs/scripts/uct/tests/sampledata/CVE-2025-0001
@@ -0,0 +1,21 @@
+Candidate: CVE-2025-0001
+PublicDate: 2025-01-01 06:00:00 UTC
+References:
+ https://www.cve.org/CVERecord?id=CVE-2025-0001
+Description:
+ Test description for this test CVE
+Ubuntu-Description:
+Notes:
+Bugs:
+Priority: high
+ This has a high priority because it is a vulnerability that allows a remote
+ attacker to execute code in a machine, and it looks to be easily exploitable
+ given that it involves regular functionalities provided by the application.
+Discovered-by:
+Assigned-to:
+CVSS:
+ nvd: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H [9.8 CRITICAL]
+
+Patches_gbrowse:
+upstream_gbrowse: released (2.56+dfsg-1)
+xenial_gbrowse: ignored (end of standard support)
diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py
index 8b22e09..95ae12e 100644
--- a/lib/lp/testing/factory.py
+++ b/lib/lp/testing/factory.py
@@ -5958,7 +5958,7 @@ class LaunchpadObjectFactory(ObjectFactory):
def makeCVE(
self,
- sequence,
+ sequence=None,
description=None,
cvestate=CveStatus.CANDIDATE,
date_made_public=None,
@@ -5966,6 +5966,9 @@ class LaunchpadObjectFactory(ObjectFactory):
cvss=None,
):
"""Create a new CVE record."""
+ if sequence is None:
+ sequence = "2000-%04i" % self.getUniqueInteger()
+
if description is None:
description = self.getUniqueUnicode()