~launchpad-pqm/launchpad/devel

« back to all changes in this revision

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

[r=sinzui][bug=855670] Add additional checks to the private team
        launchpad.LimitedView security adaptor so more users in defined
        roles can see the team.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1463
1463
        return "IS NULL"
1464
1464
 
1465
1465
 
1466
 
def get_bug_privacy_filter(user):
 
1466
def get_bug_privacy_filter(user, private_only=False):
1467
1467
    """An SQL filter for search results that adds privacy-awareness."""
1468
 
    return get_bug_privacy_filter_with_decorator(user)[0]
 
1468
    return get_bug_privacy_filter_with_decorator(user, private_only)[0]
1469
1469
 
1470
1470
 
1471
1471
def _nocache_bug_decorator(obj):
1489
1489
    return cache_user_can_view_bug
1490
1490
 
1491
1491
 
1492
 
def get_bug_privacy_filter_with_decorator(user):
 
1492
def get_bug_privacy_filter_with_decorator(user, private_only=False):
1493
1493
    """Return a SQL filter to limit returned bug tasks.
1494
1494
 
 
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.
1495
1499
    :return: A SQL filter, a decorator to cache visibility in a resultset that
1496
1500
        returns BugTask objects.
1497
1501
    """
1498
1502
    if user is None:
1499
 
        return "Bug.private = FALSE", _nocache_bug_decorator
 
1503
        return "Bug.private IS FALSE", _nocache_bug_decorator
1500
1504
    admin_team = getUtility(ILaunchpadCelebrities).admin
1501
1505
    if user.inTeam(admin_team):
1502
1506
        return "", _nocache_bug_decorator
 
1507
 
 
1508
    public_bug_filter = ''
 
1509
    if not private_only:
 
1510
        public_bug_filter = 'Bug.private IS FALSE OR'
 
1511
 
1503
1512
    # A subselect is used here because joining through
1504
1513
    # TeamParticipation is only relevant to the "user-aware"
1505
1514
    # part of the WHERE condition (i.e. the bit below.) The
1511
1520
        if features.getFeatureFlag(
1512
1521
            'disclosure.private_bug_visibility_rules.enabled'):
1513
1522
            pillar_privacy_filters = """
1514
 
                UNION
 
1523
                UNION ALL
1515
1524
                SELECT BugTask.bug
1516
1525
                FROM BugTask, Product
1517
1526
                WHERE Product.owner IN (SELECT team FROM teams) AND
1518
1527
                    BugTask.product = Product.id AND
1519
1528
                    BugTask.bug = Bug.id AND
1520
1529
                    Bug.security_related IS False
1521
 
                UNION
 
1530
                UNION ALL
1522
1531
                SELECT BugTask.bug
1523
1532
                FROM BugTask, ProductSeries
1524
1533
                WHERE ProductSeries.owner IN (SELECT team FROM teams) AND
1525
1534
                    BugTask.productseries = ProductSeries.id AND
1526
1535
                    BugTask.bug = Bug.id AND
1527
1536
                    Bug.security_related IS False
1528
 
                UNION
 
1537
                UNION ALL
1529
1538
                SELECT BugTask.bug
1530
1539
                FROM BugTask, Distribution
1531
1540
                WHERE Distribution.owner IN (SELECT team FROM teams) AND
1532
1541
                    BugTask.distribution = Distribution.id AND
1533
1542
                    BugTask.bug = Bug.id AND
1534
1543
                    Bug.security_related IS False
1535
 
                UNION
 
1544
                UNION ALL
1536
1545
                SELECT BugTask.bug
1537
1546
                FROM BugTask, DistroSeries, Distribution
1538
1547
                WHERE Distribution.owner IN (SELECT team FROM teams) AND
1542
1551
                    Bug.security_related IS False
1543
1552
            """
1544
1553
        query = """
1545
 
            (Bug.private = FALSE OR EXISTS (
 
1554
            (%(public_bug_filter)s EXISTS (
1546
1555
                WITH teams AS (
1547
1556
                    SELECT team from TeamParticipation
1548
1557
                    WHERE person = %(personid)s
1551
1560
                FROM BugSubscription
1552
1561
                WHERE BugSubscription.person IN (SELECT team FROM teams) AND
1553
1562
                    BugSubscription.bug = Bug.id
1554
 
                UNION
 
1563
                UNION ALL
1555
1564
                SELECT BugTask.bug
1556
1565
                FROM BugTask
1557
1566
                WHERE BugTask.assignee IN (SELECT team FROM teams) AND
1560
1569
                    ))
1561
1570
            """ % dict(
1562
1571
                    personid=quote(user.id),
 
1572
                    public_bug_filter=public_bug_filter,
1563
1573
                    extra_filters=pillar_privacy_filters)
1564
1574
    else:
1565
1575
        if features.getFeatureFlag(
1566
1576
            'disclosure.private_bug_visibility_rules.enabled'):
1567
1577
            pillar_privacy_filters = """
1568
 
                UNION
 
1578
                UNION ALL
1569
1579
                SELECT BugTask.bug
1570
1580
                FROM BugTask, TeamParticipation, Product
1571
1581
                WHERE TeamParticipation.person = %(personid)s AND
1573
1583
                    BugTask.product = Product.id AND
1574
1584
                    BugTask.bug = Bug.id AND
1575
1585
                    Bug.security_related IS False
1576
 
                UNION
 
1586
                UNION ALL
1577
1587
                SELECT BugTask.bug
1578
1588
                FROM BugTask, TeamParticipation, ProductSeries
1579
1589
                WHERE TeamParticipation.person = %(personid)s AND
1581
1591
                    BugTask.productseries = ProductSeries.id AND
1582
1592
                    BugTask.bug = Bug.id AND
1583
1593
                    Bug.security_related IS False
1584
 
                UNION
 
1594
                UNION ALL
1585
1595
                SELECT BugTask.bug
1586
1596
                FROM BugTask, TeamParticipation, Distribution
1587
1597
                WHERE TeamParticipation.person = %(personid)s AND
1589
1599
                    BugTask.distribution = Distribution.id AND
1590
1600
                    BugTask.bug = Bug.id AND
1591
1601
                    Bug.security_related IS False
1592
 
                UNION
 
1602
                UNION ALL
1593
1603
                SELECT BugTask.bug
1594
1604
                FROM BugTask, TeamParticipation, DistroSeries, Distribution
1595
1605
                WHERE TeamParticipation.person = %(personid)s AND
1600
1610
                    Bug.security_related IS False
1601
1611
            """ % sqlvalues(personid=user.id)
1602
1612
        query = """
1603
 
            (Bug.private = FALSE OR EXISTS (
 
1613
            (%(public_bug_filter)s EXISTS (
1604
1614
                SELECT BugSubscription.bug
1605
1615
                FROM BugSubscription, TeamParticipation
1606
1616
                WHERE TeamParticipation.person = %(personid)s AND
1607
1617
                    TeamParticipation.team = BugSubscription.person AND
1608
1618
                    BugSubscription.bug = Bug.id
1609
 
                UNION
 
1619
                UNION ALL
1610
1620
                SELECT BugTask.bug
1611
1621
                FROM BugTask, TeamParticipation
1612
1622
                WHERE TeamParticipation.person = %(personid)s AND
1616
1626
                    ))
1617
1627
            """ % dict(
1618
1628
                    personid=quote(user.id),
 
1629
                    public_bug_filter=public_bug_filter,
1619
1630
                    extra_filters=pillar_privacy_filters)
1620
1631
    return query, _make_cache_user_can_view_bug(user)
1621
1632
 
2932
2943
    def getStatusCountsForProductSeries(self, user, product_series):
2933
2944
        """See `IBugTaskSet`."""
2934
2945
        if user is None:
2935
 
            bug_privacy_filter = 'AND Bug.private = FALSE'
 
2946
            bug_privacy_filter = 'AND Bug.private IS FALSE'
2936
2947
        else:
2937
2948
            # Since the count won't reveal sensitive information, and
2938
2949
            # since the get_bug_privacy_filter() check for non-admins is