~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/bugs/model/bugtask.py

  • Committer: Curtis Hovey
  • Date: 2011-12-18 15:13:07 UTC
  • mto: This revision was merged to the branch mainline in revision 14547.
  • Revision ID: curtis.hovey@canonical.com-20111218151307-sdm2gzobt5tplbe0
Moved badges to lp.app.

Show diffs side-by-side

added added

removed removed

Lines of Context:
71
71
    removeSecurityProxy,
72
72
    )
73
73
 
 
74
from canonical.config import config
 
75
from canonical.database.constants import UTC_NOW
 
76
from canonical.database.datetimecol import UtcDateTimeCol
 
77
from canonical.database.enumcol import EnumCol
 
78
from canonical.database.nl_search import nl_phrase_search
 
79
from canonical.database.sqlbase import (
 
80
    block_implicit_flushes,
 
81
    convert_storm_clause_to_string,
 
82
    cursor,
 
83
    quote,
 
84
    quote_like,
 
85
    SQLBase,
 
86
    sqlvalues,
 
87
    )
 
88
from lp.services.database.decoratedresultset import (
 
89
    DecoratedResultSet,
 
90
    )
 
91
from canonical.launchpad.helpers import shortlist
 
92
from canonical.launchpad.interfaces.lpstorm import IStore
 
93
from canonical.launchpad.searchbuilder import (
 
94
    all,
 
95
    any,
 
96
    greater_than,
 
97
    not_equals,
 
98
    NULL,
 
99
    )
 
100
from canonical.launchpad.webapp.interfaces import (
 
101
    DEFAULT_FLAVOR,
 
102
    ILaunchBag,
 
103
    IStoreSelector,
 
104
    MAIN_STORE,
 
105
    )
74
106
from lp.app.enums import ServiceUsage
75
107
from lp.app.errors import NotFoundError
76
108
from lp.app.interfaces.launchpad import ILaunchpadCelebrities
77
 
from lp.blueprints.model.specification import Specification
78
109
from lp.bugs.interfaces.bug import IBugSet
79
110
from lp.bugs.interfaces.bugattachment import BugAttachmentType
80
111
from lp.bugs.interfaces.bugnomination import BugNominationStatus
131
162
from lp.registry.model.pillar import pillar_sort_key
132
163
from lp.registry.model.sourcepackagename import SourcePackageName
133
164
from lp.services import features
134
 
from lp.services.config import config
135
 
from lp.services.database.constants import UTC_NOW
136
 
from lp.services.database.datetimecol import UtcDateTimeCol
137
 
from lp.services.database.decoratedresultset import DecoratedResultSet
138
 
from lp.services.database.enumcol import EnumCol
139
 
from lp.services.database.lpstorm import IStore
140
 
from lp.services.database.nl_search import nl_phrase_search
141
 
from lp.services.database.sqlbase import (
142
 
    block_implicit_flushes,
143
 
    convert_storm_clause_to_string,
144
 
    cursor,
145
 
    quote,
146
 
    quote_like,
147
 
    SQLBase,
148
 
    sqlvalues,
149
 
    )
150
 
from lp.services.helpers import shortlist
151
165
from lp.services.propertycache import (
152
166
    cachedproperty,
153
167
    get_property_cache,
154
168
    )
155
 
from lp.services.searchbuilder import (
156
 
    all,
157
 
    any,
158
 
    greater_than,
159
 
    not_equals,
160
 
    NULL,
161
 
    )
162
 
from lp.services.webapp.interfaces import (
163
 
    DEFAULT_FLAVOR,
164
 
    ILaunchBag,
165
 
    IStoreSelector,
166
 
    MAIN_STORE,
167
 
    )
168
169
from lp.soyuz.enums import PackagePublishingStatus
 
170
from lp.blueprints.model.specification import Specification
169
171
 
170
172
 
171
173
debbugsseveritymap = {
681
683
        self.destroySelf()
682
684
        del get_property_cache(bug).bugtasks
683
685
 
684
 
        # When a task is deleted, we also delete it's BugNomination entry
685
 
        # if there is one. Sadly, getNominationFor() can return None or
686
 
        # raise NotFoundError so we need to check for both.
687
 
        try:
688
 
            nomination = bug.getNominationFor(target)
689
 
            if nomination is not None:
690
 
                nomination.destroySelf()
691
 
        except NotFoundError:
692
 
            # We don't care if there isn't a nomination
693
 
            pass
694
 
 
695
686
        # When a task is deleted the bug's heat needs to be recalculated.
696
687
        target.recalculateBugHeatCache()
697
688
 
1463
1454
        return "IS NULL"
1464
1455
 
1465
1456
 
1466
 
def get_bug_privacy_filter(user, private_only=False):
 
1457
def get_bug_privacy_filter(user):
1467
1458
    """An SQL filter for search results that adds privacy-awareness."""
1468
 
    return get_bug_privacy_filter_with_decorator(user, private_only)[0]
 
1459
    return get_bug_privacy_filter_with_decorator(user)[0]
1469
1460
 
1470
1461
 
1471
1462
def _nocache_bug_decorator(obj):
1489
1480
    return cache_user_can_view_bug
1490
1481
 
1491
1482
 
1492
 
def get_bug_privacy_filter_with_decorator(user, private_only=False):
 
1483
def get_bug_privacy_filter_with_decorator(user):
1493
1484
    """Return a SQL filter to limit returned bug tasks.
1494
1485
 
1495
 
    :param user: The user whose visible bugs will be filtered.
1496
 
    :param private_only: If a user is specified, this parameter determines
1497
 
        whether only private bugs will be filtered. If True, the returned
1498
 
        filter omits the "Bug.private IS FALSE" clause.
1499
1486
    :return: A SQL filter, a decorator to cache visibility in a resultset that
1500
1487
        returns BugTask objects.
1501
1488
    """
1502
1489
    if user is None:
1503
 
        return "Bug.private IS FALSE", _nocache_bug_decorator
 
1490
        return "Bug.private = FALSE", _nocache_bug_decorator
1504
1491
    admin_team = getUtility(ILaunchpadCelebrities).admin
1505
1492
    if user.inTeam(admin_team):
1506
1493
        return "", _nocache_bug_decorator
1507
 
 
1508
 
    public_bug_filter = ''
1509
 
    if not private_only:
1510
 
        public_bug_filter = 'Bug.private IS FALSE OR'
1511
 
 
1512
1494
    # A subselect is used here because joining through
1513
1495
    # TeamParticipation is only relevant to the "user-aware"
1514
1496
    # part of the WHERE condition (i.e. the bit below.) The
1520
1502
        if features.getFeatureFlag(
1521
1503
            'disclosure.private_bug_visibility_rules.enabled'):
1522
1504
            pillar_privacy_filters = """
1523
 
                UNION ALL
 
1505
                UNION
1524
1506
                SELECT BugTask.bug
1525
1507
                FROM BugTask, Product
1526
1508
                WHERE Product.owner IN (SELECT team FROM teams) AND
1527
1509
                    BugTask.product = Product.id AND
1528
1510
                    BugTask.bug = Bug.id AND
1529
1511
                    Bug.security_related IS False
1530
 
                UNION ALL
 
1512
                UNION
1531
1513
                SELECT BugTask.bug
1532
1514
                FROM BugTask, ProductSeries
1533
1515
                WHERE ProductSeries.owner IN (SELECT team FROM teams) AND
1534
1516
                    BugTask.productseries = ProductSeries.id AND
1535
1517
                    BugTask.bug = Bug.id AND
1536
1518
                    Bug.security_related IS False
1537
 
                UNION ALL
 
1519
                UNION
1538
1520
                SELECT BugTask.bug
1539
1521
                FROM BugTask, Distribution
1540
1522
                WHERE Distribution.owner IN (SELECT team FROM teams) AND
1541
1523
                    BugTask.distribution = Distribution.id AND
1542
1524
                    BugTask.bug = Bug.id AND
1543
1525
                    Bug.security_related IS False
1544
 
                UNION ALL
 
1526
                UNION
1545
1527
                SELECT BugTask.bug
1546
1528
                FROM BugTask, DistroSeries, Distribution
1547
1529
                WHERE Distribution.owner IN (SELECT team FROM teams) AND
1551
1533
                    Bug.security_related IS False
1552
1534
            """
1553
1535
        query = """
1554
 
            (%(public_bug_filter)s EXISTS (
 
1536
            (Bug.private = FALSE OR EXISTS (
1555
1537
                WITH teams AS (
1556
1538
                    SELECT team from TeamParticipation
1557
1539
                    WHERE person = %(personid)s
1560
1542
                FROM BugSubscription
1561
1543
                WHERE BugSubscription.person IN (SELECT team FROM teams) AND
1562
1544
                    BugSubscription.bug = Bug.id
1563
 
                UNION ALL
 
1545
                UNION
1564
1546
                SELECT BugTask.bug
1565
1547
                FROM BugTask
1566
1548
                WHERE BugTask.assignee IN (SELECT team FROM teams) AND
1569
1551
                    ))
1570
1552
            """ % dict(
1571
1553
                    personid=quote(user.id),
1572
 
                    public_bug_filter=public_bug_filter,
1573
1554
                    extra_filters=pillar_privacy_filters)
1574
1555
    else:
1575
1556
        if features.getFeatureFlag(
1576
1557
            'disclosure.private_bug_visibility_rules.enabled'):
1577
1558
            pillar_privacy_filters = """
1578
 
                UNION ALL
 
1559
                UNION
1579
1560
                SELECT BugTask.bug
1580
1561
                FROM BugTask, TeamParticipation, Product
1581
1562
                WHERE TeamParticipation.person = %(personid)s AND
1583
1564
                    BugTask.product = Product.id AND
1584
1565
                    BugTask.bug = Bug.id AND
1585
1566
                    Bug.security_related IS False
1586
 
                UNION ALL
 
1567
                UNION
1587
1568
                SELECT BugTask.bug
1588
1569
                FROM BugTask, TeamParticipation, ProductSeries
1589
1570
                WHERE TeamParticipation.person = %(personid)s AND
1591
1572
                    BugTask.productseries = ProductSeries.id AND
1592
1573
                    BugTask.bug = Bug.id AND
1593
1574
                    Bug.security_related IS False
1594
 
                UNION ALL
 
1575
                UNION
1595
1576
                SELECT BugTask.bug
1596
1577
                FROM BugTask, TeamParticipation, Distribution
1597
1578
                WHERE TeamParticipation.person = %(personid)s AND
1599
1580
                    BugTask.distribution = Distribution.id AND
1600
1581
                    BugTask.bug = Bug.id AND
1601
1582
                    Bug.security_related IS False
1602
 
                UNION ALL
 
1583
                UNION
1603
1584
                SELECT BugTask.bug
1604
1585
                FROM BugTask, TeamParticipation, DistroSeries, Distribution
1605
1586
                WHERE TeamParticipation.person = %(personid)s AND
1610
1591
                    Bug.security_related IS False
1611
1592
            """ % sqlvalues(personid=user.id)
1612
1593
        query = """
1613
 
            (%(public_bug_filter)s EXISTS (
 
1594
            (Bug.private = FALSE OR EXISTS (
1614
1595
                SELECT BugSubscription.bug
1615
1596
                FROM BugSubscription, TeamParticipation
1616
1597
                WHERE TeamParticipation.person = %(personid)s AND
1617
1598
                    TeamParticipation.team = BugSubscription.person AND
1618
1599
                    BugSubscription.bug = Bug.id
1619
 
                UNION ALL
 
1600
                UNION
1620
1601
                SELECT BugTask.bug
1621
1602
                FROM BugTask, TeamParticipation
1622
1603
                WHERE TeamParticipation.person = %(personid)s AND
1626
1607
                    ))
1627
1608
            """ % dict(
1628
1609
                    personid=quote(user.id),
1629
 
                    public_bug_filter=public_bug_filter,
1630
1610
                    extra_filters=pillar_privacy_filters)
1631
1611
    return query, _make_cache_user_can_view_bug(user)
1632
1612
 
2041
2021
        #
2042
2022
        # XXX: kiko 2006-03-16:
2043
2023
        # Is this a good candidate for becoming infrastructure in
2044
 
        # lp.services.database.sqlbase?
 
2024
        # canonical.database.sqlbase?
2045
2025
        for arg_name, arg_value in standard_args.items():
2046
2026
            if arg_value is None:
2047
2027
                continue
2943
2923
    def getStatusCountsForProductSeries(self, user, product_series):
2944
2924
        """See `IBugTaskSet`."""
2945
2925
        if user is None:
2946
 
            bug_privacy_filter = 'AND Bug.private IS FALSE'
 
2926
            bug_privacy_filter = 'AND Bug.private = FALSE'
2947
2927
        else:
2948
2928
            # Since the count won't reveal sensitive information, and
2949
2929
            # since the get_bug_privacy_filter() check for non-admins is