Abel Deuring has proposed merging lp:~adeuring/launchpad/bug-1079116 into 
lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~adeuring/launchpad/bug-1079116/+merge/136991

This branch fixes bug 1079116: https://code.launchpad.net/~ broken if the user 
had worked on private projects but has no longer access to these projects

The cause of the error: A user may have an artfiact grant for a proprietary 
branch that is the official branch of a series of a proprieatry product. If the 
user does not have a policy grant for the product, accessing the series object 
in lp.code.browser.branchlisting.BranchListingItemsMixin.product_series_map 
fails.

product_series_map builds a dictionary branch_id -> [product_series, ...]; I 
simply added a filter so that only series instances are added which the user 
can view. The method series.userCanView() is anyway called by the security 
adapter, so there are no additional queries involved.

test:

./bin/test code -vvt test_proprietary_branch_for_series_artifact_grant

no lint
-- 
https://code.launchpad.net/~adeuring/launchpad/bug-1079116/+merge/136991
Your team Launchpad code reviewers is requested to review the proposed merge of 
lp:~adeuring/launchpad/bug-1079116 into lp:launchpad.
=== modified file 'lib/lp/code/browser/branchlisting.py'
--- lib/lp/code/browser/branchlisting.py	2012-10-09 00:04:10 +0000
+++ lib/lp/code/browser/branchlisting.py	2012-11-29 16:58:27 +0000
@@ -340,7 +340,11 @@
             self._visible_branch_ids)
         result = {}
         for series in series_resultset:
-            result.setdefault(series.branch.id, []).append(series)
+            # Some products may be proprietary or embargoed, and users
+            # do not need to have access to them, while they may have
+            # artifact grants for the series branch.
+            if series.userCanView(self.view_user):
+                result.setdefault(series.branch.id, []).append(series)
         return result
 
     def getProductSeries(self, branch):

=== modified file 'lib/lp/code/browser/tests/test_branchlisting.py'
--- lib/lp/code/browser/tests/test_branchlisting.py	2012-10-18 12:40:40 +0000
+++ lib/lp/code/browser/tests/test_branchlisting.py	2012-11-29 16:58:27 +0000
@@ -20,6 +20,8 @@
 from testtools.matchers import Not
 from zope.component import getUtility
 
+from lp.app.enums import InformationType
+from lp.app.interfaces.services import IService
 from lp.code.browser.branchlisting import (
     BranchListingSort,
     BranchListingView,
@@ -31,7 +33,10 @@
 from lp.code.model.seriessourcepackagebranch import (
     SeriesSourcePackageBranchSet,
     )
-from lp.registry.enums import PersonVisibility
+from lp.registry.enums import (
+    PersonVisibility,
+    SharingPermission,
+    )
 from lp.registry.interfaces.person import IPerson
 from lp.registry.interfaces.personproduct import IPersonProductFactory
 from lp.registry.interfaces.pocket import PackagePublishingPocket
@@ -41,6 +46,7 @@
 from lp.services.webapp import canonical_url
 from lp.services.webapp.servers import LaunchpadTestRequest
 from lp.testing import (
+    admin_logged_in,
     BrowserTestCase,
     login_person,
     normalize_whitespace,
@@ -258,6 +264,57 @@
         # The correct template is used for batch requests.
         self._test_batch_template(self.barney)
 
+    def test_proprietary_branch_for_series_user_has_artifact_grant(self):
+        # A user can be the owner of a branch which is the series
+        # branch of a proprietary product, and the user may only have
+        # an access grant for the branch but no policy grant for the
+        # product. In this case, the branch owner does get any information
+        #about the series.
+        product_owner = self.factory.makePerson()
+        product = self.factory.makeProduct(
+            owner=product_owner, information_type=InformationType.PROPRIETARY)
+        branch_owner = self.factory.makePerson()
+        sharing_service = getUtility(IService, 'sharing')
+        with person_logged_in(product_owner):
+            # The branch owner needs to have a policy grant at first
+            # so that they can create the branch.
+            sharing_service.sharePillarInformation(
+                product, branch_owner, product_owner,
+                {InformationType.PROPRIETARY: SharingPermission.ALL})
+            proprietary_branch = self.factory.makeProductBranch(
+                product, owner=branch_owner, name='special-branch',
+                information_type=InformationType.PROPRIETARY)
+            series = self.factory.makeProductSeries(
+                product=product, branch=proprietary_branch)
+            sharing_service.deletePillarGrantee(
+                product, branch_owner, product_owner)
+        # Admin help is needed: Product owners do not have the
+        # permission to create artifact grants for branches they
+        # do not own, and the branch owner does have the permission
+        # to issue grants related to the product.
+        with admin_logged_in():
+            sharing_service.ensureAccessGrants(
+                [branch_owner], product_owner, branches=[proprietary_branch])
+
+        with person_logged_in(branch_owner):
+            view = create_initialized_view(
+                branch_owner, name="+branches", rootsite='code',
+                principal=branch_owner)
+            self.assertIn(proprietary_branch, view.branches().batch)
+            # The product series related to the branch is not returned
+            # for the branch owner.
+            self.assertEqual(
+                [], view.branches().getProductSeries(proprietary_branch))
+
+        with person_logged_in(product_owner):
+            # The product series related to the branch is returned
+            # for the product owner.
+            view = create_initialized_view(
+                branch_owner, name="+branches", rootsite='code',
+                principal=branch_owner)
+            self.assertEqual(
+                [series], view.branches().getProductSeries(proprietary_branch))
+
 
 class TestSimplifiedPersonBranchesView(TestCaseWithFactory):
 

_______________________________________________
Mailing list: https://launchpad.net/~launchpad-reviewers
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~launchpad-reviewers
More help   : https://help.launchpad.net/ListHelp

Reply via email to