launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #29068
[Merge] ~andrey-fedoseev/launchpad:more-vulnerability-dates into launchpad:master
Andrey Fedoseev has proposed merging ~andrey-fedoseev/launchpad:more-vulnerability-dates into launchpad:master with ~andrey-fedoseev/launchpad:uct-upstream as a prerequisite.
Commit message:
Add `Vulnerability.date_notice_issued` and `date_coordinated_release` fields
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~andrey-fedoseev/launchpad/+git/launchpad/+merge/428892
Update the UCT import/export scripts accordingly
Note that this MP includes changes which are also present in other merge proposals:
https://code.launchpad.net/~andrey-fedoseev/launchpad/+git/launchpad/+merge/428152
https://code.launchpad.net/~andrey-fedoseev/launchpad/+git/launchpad/+merge/428533
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~andrey-fedoseev/launchpad:more-vulnerability-dates into launchpad:master.
diff --git a/lib/lp/bugs/interfaces/vulnerability.py b/lib/lp/bugs/interfaces/vulnerability.py
index 9d8292a..474309f 100644
--- a/lib/lp/bugs/interfaces/vulnerability.py
+++ b/lib/lp/bugs/interfaces/vulnerability.py
@@ -282,6 +282,27 @@ class IVulnerabilityEditableAttributes(Interface):
as_of="devel",
)
+ date_notice_issued = exported(
+ Datetime(
+ title=_(
+ "Date when a security notice was issued for this "
+ "vulnerability."
+ ),
+ required=False,
+ readonly=False,
+ ),
+ as_of="devel",
+ )
+
+ date_coordinated_release = exported(
+ Datetime(
+ title=_("Coordinated Release Date."),
+ required=False,
+ readonly=False,
+ ),
+ as_of="devel",
+ )
+
class IVulnerabilityEdit(Interface):
"""`IVulnerability` attributes that require launchpad.Edit."""
@@ -315,6 +336,8 @@ class IVulnerabilitySet(Interface):
mitigation=None,
importance_explanation=None,
date_made_public=None,
+ date_notice_issued=None,
+ date_coordinated_release=None,
):
"""Return a new vulnerability.
@@ -330,6 +353,9 @@ class IVulnerabilitySet(Interface):
:param importance_explanation: Used to explain why our importance
differs from somebody else's CVSS score.
:param date_made_public: The date this vulnerability was made public.
+ :param date_coordinated_release: Date when a security notice was issued
+ for this vulnerability.
+ :param date_notice_issued: Coordinated Release Date.
"""
def findByIds(vulnerability_ids, visible_by_user=None):
diff --git a/lib/lp/bugs/model/vulnerability.py b/lib/lp/bugs/model/vulnerability.py
index d8d00a7..075fba8 100644
--- a/lib/lp/bugs/model/vulnerability.py
+++ b/lib/lp/bugs/model/vulnerability.py
@@ -98,6 +98,12 @@ class Vulnerability(StormBase, BugLinkTargetMixin, InformationTypeMixin):
date_made_public = DateTime(
name="date_made_public", tzinfo=pytz.UTC, allow_none=True
)
+ date_notice_issued = DateTime(
+ name="date_notice_issued", tzinfo=pytz.UTC, allow_none=True
+ )
+ date_coordinated_release = DateTime(
+ name="date_coordinated_release", tzinfo=pytz.UTC, allow_none=True
+ )
creator_id = Int(name="creator", allow_none=False)
creator = Reference(creator_id, "Person.id")
@@ -115,6 +121,8 @@ class Vulnerability(StormBase, BugLinkTargetMixin, InformationTypeMixin):
mitigation=None,
importance_explanation=None,
date_made_public=None,
+ date_notice_issued=None,
+ date_coordinated_release=None,
):
super().__init__()
self.distribution = distribution
@@ -132,6 +140,8 @@ class Vulnerability(StormBase, BugLinkTargetMixin, InformationTypeMixin):
self.mitigation = mitigation
self.importance_explanation = importance_explanation
self.date_made_public = date_made_public
+ self.date_notice_issued = date_notice_issued
+ self.date_coordinated_release = date_coordinated_release
self.date_created = UTC_NOW
@property
@@ -323,6 +333,8 @@ class VulnerabilitySet:
mitigation=None,
importance_explanation=None,
date_made_public=None,
+ date_notice_issued=None,
+ date_coordinated_release=None,
):
"""See `IVulnerabilitySet`."""
store = IStore(Vulnerability)
@@ -338,6 +350,8 @@ class VulnerabilitySet:
information_type=information_type,
importance_explanation=importance_explanation,
date_made_public=date_made_public,
+ date_notice_issued=date_notice_issued,
+ date_coordinated_release=date_coordinated_release,
)
store.add(vulnerability)
vulnerability._reconcileAccess()
diff --git a/lib/lp/bugs/scripts/tests/test_uct.py b/lib/lp/bugs/scripts/tests/test_uct.py
index 00f995d..b0348f5 100644
--- a/lib/lp/bugs/scripts/tests/test_uct.py
+++ b/lib/lp/bugs/scripts/tests/test_uct.py
@@ -162,7 +162,7 @@ class TestUCTRecord(TestCase):
self.assertEqual(load_from.read_text(), saved_to_path.read_text())
-class TextCVE(TestCaseWithFactory):
+class TestCVE(TestCaseWithFactory):
layer = ZopelessDatabaseLayer
maxDiff = None
@@ -296,14 +296,14 @@ class TextCVE(TestCaseWithFactory):
self.cve = CVE(
sequence="CVE-2022-23222",
- crd=datetime.datetime(
- 2020, 1, 14, 8, 15, tzinfo=datetime.timezone.utc
+ date_made_public=datetime.datetime(
+ 2022, 1, 14, 8, 15, tzinfo=datetime.timezone.utc
),
- public_date_at_USN=datetime.datetime(
+ date_notice_issued=datetime.datetime(
2021, 1, 14, 8, 15, tzinfo=datetime.timezone.utc
),
- public_date=datetime.datetime(
- 2022, 1, 14, 8, 15, tzinfo=datetime.timezone.utc
+ date_coordinated_release=datetime.datetime(
+ 2020, 1, 14, 8, 15, tzinfo=datetime.timezone.utc
),
distro_packages=[
CVE.DistroPackage(
@@ -485,9 +485,9 @@ class TestUCTImporterExporter(TestCaseWithFactory):
)
self.cve = CVE(
sequence="CVE-2022-23222",
- crd=None,
- public_date=self.now,
- public_date_at_USN=None,
+ date_made_public=self.now,
+ date_notice_issued=self.now,
+ date_coordinated_release=self.now,
distro_packages=[
CVE.DistroPackage(
package=self.ubuntu_package,
@@ -683,6 +683,13 @@ class TestUCTImporterExporter(TestCaseWithFactory):
self.assertEqual(
cve.date_made_public, vulnerability.date_made_public
)
+ self.assertEqual(
+ cve.date_notice_issued, vulnerability.date_notice_issued
+ )
+ self.assertEqual(
+ cve.date_coordinated_release,
+ vulnerability.date_coordinated_release,
+ )
self.assertEqual([bug], vulnerability.bugs)
def checkLaunchpadCve(self, lp_cve: CveModel, cve: CVE):
@@ -693,10 +700,12 @@ class TestUCTImporterExporter(TestCaseWithFactory):
def checkCVE(self, expected: CVE, actual: CVE):
self.assertEqual(expected.sequence, actual.sequence)
- self.assertEqual(expected.crd, actual.crd)
- self.assertEqual(expected.public_date, actual.public_date)
+ self.assertEqual(expected.date_made_public, actual.date_made_public)
+ self.assertEqual(
+ expected.date_notice_issued, actual.date_notice_issued
+ )
self.assertEqual(
- expected.public_date_at_USN, actual.public_date_at_USN
+ expected.date_coordinated_release, actual.date_coordinated_release
)
self.assertListEqual(expected.distro_packages, actual.distro_packages)
self.assertListEqual(expected.series_packages, actual.series_packages)
@@ -970,14 +979,27 @@ class TestUCTImporterExporter(TestCaseWithFactory):
importer.import_cve(self.cve)
self.assertIsNone(importer._find_existing_bug(self.cve, self.lp_cve))
- def test_naive_date_made_public(self):
+ def test_naive_dates(self):
cve = self.cve
- cve.public_date = cve.public_date.replace(tzinfo=None)
- bug = self.importer.create_bug(cve, self.lp_cve)
- self.assertEqual(
- UTC,
- bug.vulnerabilities[0].date_made_public.tzinfo,
+ cve.date_made_public = cve.date_made_public.replace(tzinfo=None)
+ cve.date_notice_issued = cve.date_notice_issued.replace(tzinfo=None)
+ cve.date_coordinated_release = cve.date_coordinated_release.replace(
+ tzinfo=None
)
+ bug = self.importer.create_bug(cve, self.lp_cve)
+ for date in (
+ bug.vulnerabilities[0].date_made_public,
+ bug.vulnerabilities[0].date_notice_issued,
+ bug.vulnerabilities[0].date_coordinated_release,
+ ):
+ self.assertEqual(UTC, date.tzinfo)
+ self.importer.update_bug(bug, cve, self.lp_cve)
+ for date in (
+ bug.vulnerabilities[0].date_made_public,
+ bug.vulnerabilities[0].date_notice_issued,
+ bug.vulnerabilities[0].date_coordinated_release,
+ ):
+ self.assertEqual(UTC, date.tzinfo)
def test_make_cve_from_bug(self):
self.importer.import_cve(self.cve)
diff --git a/lib/lp/bugs/scripts/uct/models.py b/lib/lp/bugs/scripts/uct/models.py
index 440f79d..4234fdd 100644
--- a/lib/lp/bugs/scripts/uct/models.py
+++ b/lib/lp/bugs/scripts/uct/models.py
@@ -483,9 +483,9 @@ class CVE:
def __init__(
self,
sequence: str,
- crd: Optional[datetime],
- public_date: Optional[datetime],
- public_date_at_USN: Optional[datetime],
+ date_made_public: Optional[datetime],
+ date_notice_issued: Optional[datetime],
+ date_coordinated_release: Optional[datetime],
distro_packages: List[DistroPackage],
series_packages: List[SeriesPackage],
upstream_packages: List[UpstreamPackage],
@@ -502,9 +502,9 @@ class CVE:
cvss: List[CVSS],
):
self.sequence = sequence
- self.crd = crd
- self.public_date = public_date
- self.public_date_at_USN = public_date_at_USN
+ self.date_made_public = date_made_public
+ self.date_notice_issued = date_notice_issued
+ self.date_coordinated_release = date_coordinated_release
self.distro_packages = distro_packages
self.series_packages = series_packages
self.upstream_packages = upstream_packages
@@ -614,9 +614,9 @@ class CVE:
return cls(
sequence=uct_record.candidate,
- crd=uct_record.crd,
- public_date=uct_record.public_date,
- public_date_at_USN=uct_record.public_date_at_USN,
+ date_made_public=uct_record.public_date,
+ date_notice_issued=uct_record.public_date_at_USN,
+ date_coordinated_release=uct_record.crd,
distro_packages=distro_packages,
series_packages=series_packages,
upstream_packages=upstream_packages,
@@ -728,9 +728,9 @@ class CVE:
bugs=self.bug_urls,
cvss=self.cvss,
candidate=self.sequence,
- crd=self.crd,
- public_date=self.public_date,
- public_date_at_USN=self.public_date_at_USN,
+ crd=self.date_coordinated_release,
+ public_date=self.date_made_public,
+ public_date_at_USN=self.date_notice_issued,
description=self.description,
discovered_by=self.discovered_by,
mitigation=self.mitigation,
@@ -741,10 +741,6 @@ class CVE:
packages=list(packages_by_name.values()),
)
- @property
- def date_made_public(self):
- return self.crd or self.public_date_at_USN or self.public_date
-
@cachedproperty
def affected_distributions(self) -> Set[Distribution]:
return {p.package.distribution for p in self.distro_packages}
diff --git a/lib/lp/bugs/scripts/uct/uctexport.py b/lib/lp/bugs/scripts/uct/uctexport.py
index 45366a9..b4c3b87 100644
--- a/lib/lp/bugs/scripts/uct/uctexport.py
+++ b/lib/lp/bugs/scripts/uct/uctexport.py
@@ -165,9 +165,9 @@ class UCTExporter:
return CVE(
sequence="CVE-{}".format(lp_cve.sequence),
- crd=None, # TODO: fix this
- public_date=vulnerability.date_made_public,
- public_date_at_USN=None, # TODO: fix this
+ date_made_public=vulnerability.date_made_public,
+ date_notice_issued=vulnerability.date_notice_issued,
+ date_coordinated_release=vulnerability.date_coordinated_release,
distro_packages=distro_packages,
series_packages=series_packages,
upstream_packages=upstream_packages,
diff --git a/lib/lp/bugs/scripts/uct/uctimport.py b/lib/lp/bugs/scripts/uct/uctimport.py
index 13639b5..3af3ad7 100644
--- a/lib/lp/bugs/scripts/uct/uctimport.py
+++ b/lib/lp/bugs/scripts/uct/uctimport.py
@@ -297,21 +297,15 @@ class UCTImporter:
:param distribution: a `Distribution` affected by the vulnerability
:return: a Vulnerability
"""
- date_made_public = cve.date_made_public
- if date_made_public.tzinfo is None:
- date_made_public = date_made_public.replace(tzinfo=timezone.utc)
vulnerability = getUtility(IVulnerabilitySet).new(
distribution=distribution,
- creator=bug.owner,
- cve=lp_cve,
status=cve.status,
- description=cve.ubuntu_description,
- notes=cve.notes,
- mitigation=cve.mitigation,
importance=cve.importance,
+ creator=bug.owner,
information_type=InformationType.PUBLICSECURITY,
- date_made_public=date_made_public,
+ cve=lp_cve,
) # type: Vulnerability
+ self._update_vulnerability(vulnerability, cve)
vulnerability.linkBug(bug, bug.owner)
@@ -334,12 +328,28 @@ class UCTImporter:
:param vulnerability: `Vulnerability` model to be updated
:param cve: `CVE` with information from UCT
"""
+ date_made_public = cve.date_made_public
+ if date_made_public.tzinfo is None:
+ date_made_public = date_made_public.replace(tzinfo=timezone.utc)
+ date_notice_issued = cve.date_notice_issued
+ if date_notice_issued.tzinfo is None:
+ date_notice_issued = date_notice_issued.replace(
+ tzinfo=timezone.utc
+ )
+ date_coordinated_release = cve.date_coordinated_release
+ if date_coordinated_release.tzinfo is None:
+ date_coordinated_release = date_coordinated_release.replace(
+ tzinfo=timezone.utc
+ )
+
vulnerability.status = cve.status
vulnerability.description = cve.ubuntu_description
vulnerability.notes = cve.notes
vulnerability.mitigation = cve.mitigation
vulnerability.importance = cve.importance
- vulnerability.date_made_public = cve.date_made_public
+ vulnerability.date_made_public = date_made_public
+ vulnerability.date_notice_issued = date_notice_issued
+ vulnerability.date_coordinated_release = date_coordinated_release
def _assign_bug_tasks(
self, bug: BugModel, assignee: Optional[Person]