1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
# Copyright 2009 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Views to generate CVE reports (as in distro and distroseries/+cve pages)."""
__metaclass__ = type
__all__ = [
'CVEReportView',
]
from zope.component import getUtility
from canonical.launchpad.helpers import shortlist
from canonical.launchpad.searchbuilder import any
from canonical.launchpad.webapp import LaunchpadView
from lp.bugs.browser.bugtask import BugTaskListingItem
from lp.bugs.interfaces.bugtask import (
BugTaskSearchParams,
IBugTaskSet,
RESOLVED_BUGTASK_STATUSES,
UNRESOLVED_BUGTASK_STATUSES,
)
from lp.bugs.interfaces.cve import ICveSet
from lp.services.propertycache import cachedproperty
class BugTaskCve:
"""An object that represents BugTasks and CVEs related to a single bug."""
def __init__(self):
self.bugtasks = []
self.cves = []
@property
def bug(self):
"""Return the bug which this BugTaskCve represents."""
# All the bugtasks we have should represent the same bug.
assert self.bugtasks, "No bugtasks added before calling bug!"
return self.bugtasks[0].bug
class CVEReportView(LaunchpadView):
"""View that builds data to be displayed in CVE reports."""
@cachedproperty
def open_cve_bugtasks(self):
"""Return BugTaskCves for bugs with open bugtasks in the context."""
search_params = BugTaskSearchParams(self.user,
status=any(*UNRESOLVED_BUGTASK_STATUSES))
return self._buildBugTaskCves(search_params)
@cachedproperty
def resolved_cve_bugtasks(self):
"""Return BugTaskCves for bugs with resolved bugtasks in the context."""
search_params = BugTaskSearchParams(self.user,
status=any(*RESOLVED_BUGTASK_STATUSES))
return self._buildBugTaskCves(search_params)
def setContextForParams(self, params):
"""Update the search params for the context for a specific view."""
raise NotImplementedError
def _buildBugTaskCves(self, search_params):
"""Construct a list of BugTaskCve objects, sorted by bug ID."""
search_params.has_cve = True
bugtasks = shortlist(
self.context.searchTasks(search_params),
longest_expected=300)
if not bugtasks:
return []
badge_properties = getUtility(IBugTaskSet).getBugTaskBadgeProperties(
bugtasks)
bugtaskcves = {}
for bugtask in bugtasks:
badges = badge_properties[bugtask]
# Wrap the bugtask in a BugTaskListingItem, to avoid db
# queries being issues when trying to render the badges.
bugtask = BugTaskListingItem(
bugtask,
has_bug_branch=badges['has_branch'],
has_specification=badges['has_specification'],
has_patch=badges['has_patch'])
if not bugtaskcves.has_key(bugtask.bug.id):
bugtaskcves[bugtask.bug.id] = BugTaskCve()
bugtaskcves[bugtask.bug.id].bugtasks.append(bugtask)
bugcves = getUtility(ICveSet).getBugCvesForBugTasks(bugtasks)
for bugcve in bugcves:
assert bugtaskcves.has_key(bugcve.bug.id)
bugtaskcves[bugcve.bug.id].cves.append(bugcve.cve)
# Order the dictionary items by bug ID and then return only the
# bugtaskcve objects.
return [bugtaskcve for bug, bugtaskcve in sorted(bugtaskcves.items())]
|