launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #32971
[Merge] ~ilkeremrekoc/launchpad:add-eximport-endpoints into launchpad:master
İlker Emre Koç has proposed merging ~ilkeremrekoc/launchpad:add-eximport-endpoints into launchpad:master.
Commit message:
WIP: Add vulnerability job list endpoints
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~ilkeremrekoc/launchpad/+git/launchpad/+merge/492479
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~ilkeremrekoc/launchpad:add-eximport-endpoints into launchpad:master.
diff --git a/lib/lp/bugs/interfaces/vulnerability.py b/lib/lp/bugs/interfaces/vulnerability.py
index 9e83bef..80dda47 100644
--- a/lib/lp/bugs/interfaces/vulnerability.py
+++ b/lib/lp/bugs/interfaces/vulnerability.py
@@ -16,6 +16,7 @@ from lazr.restful.declarations import (
REQUEST_USER,
call_with,
collection_default_content,
+ export_read_operation,
export_write_operation,
exported,
exported_as_webservice_collection,
@@ -476,6 +477,47 @@ class IVulnerabilitySet(Interface):
data.
"""
+ @operation_parameters(
+ handler=Choice(
+ title=_("The handler to import or export vulnerability data"),
+ readonly=True,
+ required=True,
+ vocabulary=VulnerabilityHandlerEnum,
+ ),
+ )
+ @call_with(requester=REQUEST_USER)
+ @export_read_operation()
+ @operation_for_version("devel")
+ def getImports(
+ requester,
+ handler,
+ ):
+ """Return the latest 10 import jobs done and their statuses.
+
+ :param handler: Get the import jobs performed by this handler.
+ """
+
+ @operation_parameters(
+ handler=Choice(
+ title=_("The handler to import or export vulnerability data"),
+ readonly=True,
+ required=True,
+ vocabulary=VulnerabilityHandlerEnum,
+ ),
+ )
+ @call_with(requester=REQUEST_USER)
+ @export_read_operation()
+ @operation_for_version("devel")
+ def getExports(
+ requester,
+ handler,
+ ):
+ """Return the latest 10 export jobs done and link to their librarian
+ files.
+
+ :param handler: Get the export jobs performed by this handler.
+ """
+
@collection_default_content()
def empty_list():
"""Return an empty collection of vulnerabilities.
diff --git a/lib/lp/bugs/model/exportvulnerabilityjob.py b/lib/lp/bugs/model/exportvulnerabilityjob.py
index 6fdad6a..487ca57 100644
--- a/lib/lp/bugs/model/exportvulnerabilityjob.py
+++ b/lib/lp/bugs/model/exportvulnerabilityjob.py
@@ -28,7 +28,7 @@ from lp.bugs.interfaces.vulnerabilityjob import (
)
from lp.bugs.model.bug import Bug as BugModel
from lp.bugs.model.cve import Cve as CveModel
-from lp.bugs.model.vulnerability import Vulnerability
+from lp.bugs.model.vulnerability import HANDLER_DISTRIBUTION_MAP, Vulnerability
from lp.bugs.model.vulnerabilityjob import (
VulnerabilityJob,
VulnerabilityJobDerived,
@@ -49,8 +49,6 @@ logger = logging.getLogger(__name__)
HANDLER_EXPORTER_MAP = {VulnerabilityHandlerEnum.SOSS: SOSSExporter}
-HANDLER_DISTRIBUTION_MAP = {VulnerabilityHandlerEnum.SOSS: "soss"}
-
@implementer(IExportVulnerabilityJob)
@provider(IExportVulnerabilityJobSource)
diff --git a/lib/lp/bugs/model/vulnerability.py b/lib/lp/bugs/model/vulnerability.py
index c337b8f..93acc60 100644
--- a/lib/lp/bugs/model/vulnerability.py
+++ b/lib/lp/bugs/model/vulnerability.py
@@ -5,6 +5,7 @@ __all__ = [
"get_vulnerability_privacy_filter",
"Vulnerability",
"VulnerabilitySet",
+ "HANDLER_DISTRIBUTION_MAP",
]
import operator
@@ -12,7 +13,7 @@ from datetime import timezone
from typing import Iterable
from storm.databases.postgres import JSON
-from storm.expr import SQL, Coalesce, Join, Or, Select
+from storm.expr import SQL, Coalesce, Desc, Join, Or, Select
from storm.locals import DateTime, Int, Reference, Unicode
from storm.store import Store
from zope.component import getUtility
@@ -49,6 +50,7 @@ from lp.registry.interfaces.accesspolicy import (
IAccessArtifactGrantSource,
IAccessArtifactSource,
)
+from lp.registry.interfaces.distribution import IDistributionSet
from lp.registry.interfaces.role import IPersonRoles
from lp.registry.model.accesspolicy import reconcile_access_for_artifacts
from lp.registry.model.person import Person
@@ -66,6 +68,8 @@ VULNERABILITY_IMPORT_ENABLED_FEATURE_FLAG = (
"bugs.vulnerability_import_export.enabled"
)
+HANDLER_DISTRIBUTION_MAP = {VulnerabilityHandlerEnum.SOSS: "soss"}
+
@implementer(IVulnerability, IBugLinkTarget)
class Vulnerability(StormBase, BugLinkTargetMixin, InformationTypeMixin):
@@ -473,6 +477,107 @@ class VulnerabilitySet:
return None
+ def _get_jobs_info(self, vulnerability_jobs):
+ # Merge fields from Job and VulnerabilityJob.metadata
+ jobs_info = []
+ for vulnerability_job in vulnerability_jobs:
+ job = vulnerability_job.job
+ if not job:
+ continue
+
+ job_details = {
+ "created_at": job.date_created,
+ "started_at": job.date_started,
+ "finished_at": job.date_finished,
+ }
+ # breakpoint()
+ job_info = dict(
+ vulnerability_job.metadata or {}
+ ).copy() # copy so we don’t mutate the original
+
+ request = job_info.get("request")
+ if request and "information_type" in request:
+ info_type_number = request["information_type"]
+ try:
+ request["information_type"] = InformationType.items[
+ info_type_number
+ ].title
+ except (KeyError, IndexError):
+ request["information_type"] = ""
+
+ job_info["job_details"] = job_details
+ # breakpoint()
+ jobs_info.append(job_info)
+
+ return jobs_info
+
+ def getImports(
+ self,
+ requester,
+ handler,
+ ):
+ from lp.bugs.model.importvulnerabilityjob import ImportVulnerabilityJob
+ from lp.bugs.model.vulnerabilityjob import VulnerabilityJob
+ from lp.bugs.scripts.soss.sossimport import SOSSImporter
+
+ if handler == VulnerabilityHandlerEnum.SOSS:
+ importer = SOSSImporter()
+ else:
+ raise NotFoundError(f"{handler} not found")
+
+ if not importer.checkUserPermissions(requester):
+ raise UnauthorizedVulnerabilityHandler(
+ f"You don't have enough rights to use {handler}"
+ )
+
+ store = IStore(VulnerabilityJob)
+
+ vulnerability_jobs = (
+ store.find(
+ VulnerabilityJob,
+ VulnerabilityJob.job_type
+ == ImportVulnerabilityJob.class_job_type,
+ VulnerabilityJob.handler == handler,
+ )
+ .order_by(Desc(VulnerabilityJob.id))
+ .config(limit=10)
+ )
+
+ return self._get_jobs_info(vulnerability_jobs)
+
+ def getExports(self, requester, handler):
+ from lp.bugs.model.exportvulnerabilityjob import ExportVulnerabilityJob
+ from lp.bugs.model.vulnerabilityjob import VulnerabilityJob
+ from lp.bugs.scripts.soss.sossexport import SOSSExporter
+
+ if handler == VulnerabilityHandlerEnum.SOSS:
+ exporter = SOSSExporter()
+ distribution = getUtility(IDistributionSet).getByName(
+ HANDLER_DISTRIBUTION_MAP[handler]
+ )
+ else:
+ raise NotFoundError(f"{handler} not found")
+
+ if not exporter.checkUserPermissions(requester, distribution):
+ raise UnauthorizedVulnerabilityHandler(
+ f"You don't have enough rights to use {handler}"
+ )
+
+ store = IStore(VulnerabilityJob)
+
+ vulnerability_jobs = (
+ store.find(
+ VulnerabilityJob,
+ VulnerabilityJob.job_type
+ == ExportVulnerabilityJob.class_job_type,
+ VulnerabilityJob.handler == handler,
+ )
+ .order_by(Desc(VulnerabilityJob.id))
+ .config(limit=10)
+ )
+
+ return self._get_jobs_info(vulnerability_jobs)
+
def empty_list(self):
"""See `IVulnerabilitySet`."""
return []
diff --git a/lib/lp/bugs/scripts/soss/sossexport.py b/lib/lp/bugs/scripts/soss/sossexport.py
index 9a75eb6..fddc359 100644
--- a/lib/lp/bugs/scripts/soss/sossexport.py
+++ b/lib/lp/bugs/scripts/soss/sossexport.py
@@ -18,7 +18,9 @@ from lp.bugs.scripts.soss.sossimport import (
PACKAGE_TYPE_MAP,
PRIORITY_ENUM_MAP,
)
+from lp.registry.interfaces.role import IPersonRoles
from lp.registry.model.distribution import Distribution
+from lp.registry.security import SecurityAdminDistribution
__all__ = [
"SOSSExporter",
@@ -160,3 +162,8 @@ class SOSSExporter:
if date_obj and date_obj.tzinfo is not None:
return date_obj.replace(tzinfo=None)
return date_obj
+
+ def checkUserPermissions(self, user, distribution):
+ return SecurityAdminDistribution(distribution).checkAuthenticated(
+ IPersonRoles(user)
+ )
References