~launchpad-pqm/launchpad/devel

« back to all changes in this revision

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

  • Committer: Launchpad Patch Queue Manager
  • Date: 2011-06-08 16:34:35 UTC
  • mfrom: (13163.1.5 bug-789383)
  • Revision ID: launchpad@pqm.canonical.com-20110608163435-ttiot3ngrj56urru
[r=gmb][bug=789383] Fixed Bug userCanView to handle anonymous users
        correctly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
583
583
        """See `IBug`."""
584
584
        dn = 'Bug #%d' % self.id
585
585
        if self.name:
586
 
            dn += ' ('+self.name+')'
 
586
            dn += ' (' + self.name + ')'
587
587
        return dn
588
588
 
589
589
    @cachedproperty
755
755
        table = LeftJoin(
756
756
            table,
757
757
            Distribution,
758
 
            OfficialBugTag.distribution_id==Distribution.id)
 
758
            OfficialBugTag.distribution_id == Distribution.id)
759
759
        table = LeftJoin(
760
760
            table,
761
761
            Product,
762
 
            OfficialBugTag.product_id==Product.id)
 
762
            OfficialBugTag.product_id == Product.id)
763
763
        # When this method is typically called it already has the necessary
764
764
        # info in memory, so rather than rejoin with Product etc, we do this
765
765
        # bit in Python. If reviewing performance here feel free to change.
774
774
 
775
775
    def followup_subject(self):
776
776
        """See `IBug`."""
777
 
        return 'Re: '+ self.title
 
777
        return 'Re: ' + self.title
778
778
 
779
779
    @property
780
780
    def has_patches(self):
1463
1463
        # 1 bugmessage -> 1 message -> small N chunks. For now, using a wide
1464
1464
        # query seems fine as we have to join out from bugmessage anyway.
1465
1465
        result = Store.of(self).find((BugMessage, Message, MessageChunk),
1466
 
            Message.id==MessageChunk.messageID,
1467
 
            BugMessage.messageID==Message.id,
1468
 
            BugMessage.bug==self.id,
 
1466
            Message.id == MessageChunk.messageID,
 
1467
            BugMessage.messageID == Message.id,
 
1468
            BugMessage.bug == self.id,
1469
1469
            *ranges)
1470
1470
        result.order_by(BugMessage.index, MessageChunk.sequence)
1471
1471
 
1676
1676
            # Correct the heat for the bug immediately, so that we don't have
1677
1677
            # to wait for the next calculation job for the adjusted heat.
1678
1678
            self.updateHeat()
1679
 
            return True # Changed.
 
1679
            return True  # Changed.
1680
1680
        else:
1681
 
            return False # Not changed.
 
1681
            return False  # Not changed.
1682
1682
 
1683
1683
    def setSecurityRelated(self, security_related):
1684
1684
        """Setter for the `security_related` property."""
1689
1689
            # to wait for the next calculation job for the adjusted heat.
1690
1690
            self.updateHeat()
1691
1691
 
1692
 
            return True # Changed
 
1692
            return True  # Changed
1693
1693
        else:
1694
 
            return False # Unchanged
 
1694
            return False  # Unchanged
1695
1695
 
1696
1696
    def getBugTask(self, target):
1697
1697
        """See `IBug`."""
1709
1709
    def _cached_tags(self):
1710
1710
        return list(Store.of(self).find(
1711
1711
            BugTag.tag,
1712
 
            BugTag.bugID==self.id).order_by(BugTag.tag))
 
1712
            BugTag.bugID == self.id).order_by(BugTag.tag))
1713
1713
 
1714
1714
    def _setTags(self, tags):
1715
1715
        """Set the tags from a list of strings."""
1860
1860
    def userCanView(self, user):
1861
1861
        """See `IBug`.
1862
1862
 
1863
 
        Note that Editing is also controlled by this check,
1864
 
        because we permit editing of any bug one can see.
 
1863
        This method is called by security adapters but only in the case for
 
1864
        authenticated users.  It is also called in other contexts where the
 
1865
        user may be anonymous.
1865
1866
 
1866
1867
        If bug privacy rights are changed here, corresponding changes need
1867
1868
        to be made to the queries which screen for privacy.  See
1868
1869
        Bug.searchAsUser and BugTask.get_bug_privacy_filter_with_decorator.
1869
1870
        """
1870
 
        assert user is not None, "User may not be None"
1871
 
 
1872
 
        if user.id in self._known_viewers:
1873
 
            return True
1874
1871
        if not self.private:
1875
1872
            # This is a public bug.
1876
1873
            return True
 
1874
        # This method may be called for anonymous users.  For private bugs
 
1875
        # always return false for anonymous.
 
1876
        if user is None:
 
1877
            return False
 
1878
        if user.id in self._known_viewers:
 
1879
            return True
 
1880
 
1877
1881
        elif IPersonRoles(user).in_admin:
1878
1882
            # Admins can view all bugs.
1879
1883
            return True
2264
2268
            BugSubscription.bug_notification_level >= self.level,
2265
2269
            BugSubscription.bug == self.bug,
2266
2270
            Not(In(BugSubscription.person_id,
2267
 
                   Select(BugMute.person_id, BugMute.bug_id==self.bug.id))))
 
2271
                   Select(BugMute.person_id, BugMute.bug_id == self.bug.id))))
2268
2272
 
2269
2273
    @cachedproperty
2270
2274
    @freeze(BugSubscriptionSet)
2279
2283
                BugSubscription.bug_id == Bug.id,
2280
2284
                Bug.duplicateof == self.bug,
2281
2285
                Not(In(BugSubscription.person_id,
2282
 
                       Select(BugMute.person_id, BugMute.bug_id==Bug.id))))
 
2286
                       Select(BugMute.person_id, BugMute.bug_id == Bug.id))))
2283
2287
 
2284
2288
    @cachedproperty
2285
2289
    @freeze(BugSubscriptionSet)
2289
2293
        Excludes subscriptions for people who have a direct subscription or
2290
2294
        are also notified for another reason.
2291
2295
        """
2292
 
        self.duplicate_subscriptions.subscribers # Pre-load subscribers.
 
2296
        self.duplicate_subscriptions.subscribers  # Pre-load subscribers.
2293
2297
        higher_precedence = (
2294
2298
            self.direct_subscriptions.subscribers.union(
2295
2299
                self.also_notified_subscribers))
2327
2331
        else:
2328
2332
            muted = IStore(BugMute).find(
2329
2333
                Person,
2330
 
                BugMute.person_id==Person.id,
2331
 
                BugMute.bug==self.bug)
 
2334
                BugMute.person_id == Person.id,
 
2335
                BugMute.bug == self.bug)
2332
2336
            return BugSubscriberSet().union(
2333
2337
                self.structural_subscriptions.subscribers,
2334
2338
                self.all_pillar_owners_without_bug_supervisors,
2581
2585
        #      Transaction.iterSelect() will try to listify the results.
2582
2586
        #      This can be fixed by selecting from Bugs directly, but
2583
2587
        #      that's non-trivial.
2584
 
        # ---: Robert Collins 20100818: if bug_tasks implements IResultSset
 
2588
        # ---: Robert Collins 2010-08-18: if bug_tasks implements IResultSet
2585
2589
        #      then it should be very possible to improve on it, though
2586
2590
        #      DecoratedResultSets would need careful handling (e.g. type
2587
2591
        #      driven callbacks on columns)
2630
2634
            Bug.heat_last_updated == None)
2631
2635
 
2632
2636
        return store.find(
2633
 
            Bug, Bug.duplicateof==None, last_updated_clause).order_by('id')
 
2637
            Bug, Bug.duplicateof == None, last_updated_clause).order_by('id')
2634
2638
 
2635
2639
 
2636
2640
class BugAffectsPerson(SQLBase):