launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #06278
[Merge] lp:~wallyworld/launchpad/private-bug-visibility-741234 into lp:launchpad
Ian Booth has proposed merging lp:~wallyworld/launchpad/private-bug-visibility-741234 into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #741234 in Launchpad itself: "product:+code-index merge proposal queries do not show private bugs visible by assignment"
https://bugs.launchpad.net/launchpad/+bug/741234
For more details, see:
https://code.launchpad.net/~wallyworld/launchpad/private-bug-visibility-741234/+merge/91975
== Implementation ==
The core issue was that BugBranchSet.getBranchesWithVisibleBugs() executed a Storm query which did not check for bugs assigned to the user. But this code is really just a pseudo duplicate of other bug visibility stuff that lives elsewhere. So I refactored it to use the bug module's get_privacy_filter() method which does the right thing by definition - it's the method used in the security adaptor etc.
The other issue was that there was duplication in the BranchListingItem class - overridden methods which are never called but also attempt to determine whether badges should be shown. This duplicate code was deleted, and in actual fact produced potentially more sql so was not as efficient anyway.
== QA ==
Link a private bug to a branch. Assign a user to a private bug task (ensuring they can not previously have seen the bug). Log in as that user and ensure there is a bug badge on the code listing page showing the branch to which the bug is linked.
== Tests ==
Added two new tests to TestBugBranchSet:
- test_getBranchesWithVisibleBugs_shows_private_bugs_to_assignee
- test_getBranchesWithVisibleBugs_shows_private_bugs_to_admins
The second test above tests functionality which was previously never tested AFAICT.
== Lint ==
Bit of drive by lint done also.
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/bugs/model/bugbranch.py
lib/lp/bugs/tests/test_bugbranch.py
lib/lp/code/browser/branchlisting.py
./lib/lp/bugs/tests/test_bugbranch.py
50: local variable 'bug_b' is assigned to but never used
--
https://code.launchpad.net/~wallyworld/launchpad/private-bug-visibility-741234/+merge/91975
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wallyworld/launchpad/private-bug-visibility-741234 into lp:launchpad.
=== modified file 'lib/lp/bugs/model/bugbranch.py'
--- lib/lp/bugs/model/bugbranch.py 2011-12-30 06:14:56 +0000
+++ lib/lp/bugs/model/bugbranch.py 2012-02-08 04:32:18 +0000
@@ -16,23 +16,15 @@
IntCol,
StringCol,
)
-from storm.expr import (
- And,
- Exists,
- Or,
- Select,
- )
-from zope.component import getUtility
from zope.interface import implements
-from lp.app.interfaces.launchpad import ILaunchpadCelebrities
from lp.bugs.interfaces.bugbranch import (
IBugBranch,
IBugBranchSet,
)
+from lp.bugs.model.bugtask import get_bug_privacy_filter
from lp.code.interfaces.branchtarget import IHasBranchTarget
from lp.registry.interfaces.person import validate_public_person
-from lp.registry.model.teammembership import TeamParticipation
from lp.services.database.constants import UTC_NOW
from lp.services.database.datetimecol import UtcDateTimeCol
from lp.services.database.lpstorm import IStore
@@ -73,52 +65,27 @@
implements(IBugBranchSet)
def getBugBranch(self, bug, branch):
- "See `IBugBranchSet`."
+ """See `IBugBranchSet`."""
return BugBranch.selectOneBy(bugID=bug.id, branchID=branch.id)
def getBranchesWithVisibleBugs(self, branches, user):
"""See `IBugBranchSet`."""
# Avoid circular imports.
from lp.bugs.model.bug import Bug
- from lp.bugs.model.bugsubscription import BugSubscription
branch_ids = [branch.id for branch in branches]
- if branch_ids == []:
+ if not branch_ids:
return []
- admins = getUtility(ILaunchpadCelebrities).admin
- if user is None:
- # Anonymous visitors only get to know about public bugs.
- visible = And(
- Bug.id == BugBranch.bugID,
- Bug.private == False)
- elif user.inTeam(admins):
- # Administrators know about all bugs.
- visible = True
- else:
- # Anyone else can know about public bugs plus any private
- # ones they may be directly or indirectly subscribed to.
- subscribed = And(
- TeamParticipation.teamID == BugSubscription.person_id,
- TeamParticipation.personID == user.id,
- Bug.id == BugSubscription.bug_id)
-
- visible = And(
- Bug.id == BugBranch.bugID,
- Or(
- Bug.private == False,
- Exists(Select(
- columns=[True],
- tables=[BugSubscription, TeamParticipation],
- where=subscribed))))
-
+ visible = get_bug_privacy_filter(user) or True
return IStore(BugBranch).find(
BugBranch.branchID,
BugBranch.branch_id.is_in(branch_ids),
+ Bug.id == BugBranch.bugID,
visible).config(distinct=True)
def getBugBranchesForBugTasks(self, tasks):
- "See IBugBranchSet."
+ """See `IBugBranchSet`."""
bug_ids = [task.bugID for task in tasks]
if not bug_ids:
return []
=== modified file 'lib/lp/bugs/tests/test_bugbranch.py'
--- lib/lp/bugs/tests/test_bugbranch.py 2012-01-01 02:58:52 +0000
+++ lib/lp/bugs/tests/test_bugbranch.py 2012-02-08 04:32:18 +0000
@@ -8,6 +8,7 @@
from zope.component import getUtility
from zope.security.interfaces import Unauthorized
+from lp.app.interfaces.launchpad import ILaunchpadCelebrities
from lp.bugs.interfaces.bugbranch import (
IBugBranch,
IBugBranchSet,
@@ -130,6 +131,30 @@
self.assertContentEqual(
[branch.id], utility.getBranchesWithVisibleBugs([branch], user))
+ def test_getBranchesWithVisibleBugs_shows_private_bugs_to_assignee(self):
+ # getBranchesWithVisibleBugs will show private bugs to their
+ # assignees.
+ branch = self.factory.makeBranch()
+ bug = self.factory.makeBug(private=True)
+ user = self.factory.makePerson()
+ with celebrity_logged_in('admin'):
+ bug.default_bugtask.transitionToAssignee(user)
+ bug.linkBranch(branch, self.factory.makePerson())
+ utility = getUtility(IBugBranchSet)
+ self.assertContentEqual(
+ [branch.id], utility.getBranchesWithVisibleBugs([branch], user))
+
+ def test_getBranchesWithVisibleBugs_shows_private_bugs_to_admins(self):
+ # getBranchesWithVisibleBugs will show private bugs to admins.
+ branch = self.factory.makeBranch()
+ bug = self.factory.makeBug(private=True)
+ with celebrity_logged_in('admin'):
+ bug.linkBranch(branch, self.factory.makePerson())
+ utility = getUtility(IBugBranchSet)
+ admin = getUtility(ILaunchpadCelebrities).admin
+ self.assertContentEqual(
+ [branch.id], utility.getBranchesWithVisibleBugs([branch], admin))
+
def test_getBugBranchesForBugTasks(self):
# IBugBranchSet.getBugBranchesForBugTasks returns all of the BugBranch
# objects associated with the given bug tasks.
=== modified file 'lib/lp/code/browser/branchlisting.py'
--- lib/lp/code/browser/branchlisting.py 2012-01-06 11:08:30 +0000
+++ lib/lp/code/browser/branchlisting.py 2012-02-08 04:32:18 +0000
@@ -147,32 +147,10 @@
class BranchBadges(HasBadgeBase):
badges = "private", "bug", "blueprint", "warning", "mergeproposal"
- def isBugBadgeVisible(self):
- """Show a bug badge if the branch is linked to bugs."""
- # Only show the badge if at least one bug is visible by the user.
- for bug in self.context.linked_bugs:
- # Stop on the first visible one.
- if check_permission('launchpad.View', bug):
- return True
- return False
-
- def isBlueprintBadgeVisible(self):
- """Show a blueprint badge if the branch is linked to blueprints."""
- # When specs get privacy, this will need to be adjusted.
- return self.context.spec_links.count() > 0
-
def isWarningBadgeVisible(self):
"""Show a warning badge if there are mirror failures."""
return self.context.mirror_failures > 0
- def isMergeproposalBadgeVisible(self):
- """Show a proposal badge if there are any landing targets."""
- for proposal in self.context.landing_targets:
- # Stop on the first visible one.
- if check_permission('launchpad.View', proposal):
- return True
- return False
-
def getBadge(self, badge_name):
"""See `IHasBadges`."""
if badge_name == "warning":