launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #02082
[Merge] lp:~salgado/launchpad/bug-683106 into lp:launchpad
Guilherme Salgado has proposed merging lp:~salgado/launchpad/bug-683106 into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
#683106 ISpecification.all_specifications returns an empty list for anonymous users of the API
https://bugs.launchpad.net/bugs/683106
Add a launchpad.View security adapter for ISpecification so that collections
of it can be seen anonymously on the webservice
--
https://code.launchpad.net/~salgado/launchpad/bug-683106/+merge/42351
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~salgado/launchpad/bug-683106 into lp:launchpad.
=== modified file 'lib/canonical/launchpad/security.py'
--- lib/canonical/launchpad/security.py 2010-11-26 18:12:16 +0000
+++ lib/canonical/launchpad/security.py 2010-12-01 12:05:01 +0000
@@ -44,7 +44,10 @@
from lp.answers.interfaces.faqtarget import IFAQTarget
from lp.answers.interfaces.question import IQuestion
from lp.answers.interfaces.questiontarget import IQuestionTarget
-from lp.blueprints.interfaces.specification import ISpecification
+from lp.blueprints.interfaces.specification import (
+ ISpecification,
+ ISpecificationPublic,
+ )
from lp.blueprints.interfaces.specificationbranch import ISpecificationBranch
from lp.blueprints.interfaces.specificationsubscription import (
ISpecificationSubscription,
@@ -494,6 +497,17 @@
return True
+class AnonymousAccessToISpecificationPublic(AnonymousAuthorization):
+ """Anonymous users have launchpad.View on ISpecificationPublic.
+
+ This is only needed because lazr.restful is hard-coded to check that
+ permission before returning things in a collection.
+ """
+
+ permission = 'launchpad.View'
+ usedfor = ISpecificationPublic
+
+
class EditSpecificationByTargetOwnerOrOwnersOrAdmins(AuthorizationBase):
"""We want everybody "related" to a specification to be able to edit it.
You are related if you have a role on the spec, or if you have a role on
=== modified file 'lib/lp/blueprints/interfaces/specification.py'
--- lib/lp/blueprints/interfaces/specification.py 2010-11-29 18:53:45 +0000
+++ lib/lp/blueprints/interfaces/specification.py 2010-12-01 12:05:01 +0000
@@ -14,6 +14,7 @@
'INewSpecificationTarget',
'INewSpecificationProjectTarget',
'ISpecification',
+ 'ISpecificationPublic',
'ISpecificationSet',
'ISpecificationDelta',
]
=== modified file 'lib/lp/blueprints/tests/test_webservice.py'
--- lib/lp/blueprints/tests/test_webservice.py 2010-11-29 18:53:45 +0000
+++ lib/lp/blueprints/tests/test_webservice.py 2010-12-01 12:05:01 +0000
@@ -5,15 +5,23 @@
__metaclass__ = type
+from zope.security.management import endInteraction
+
from canonical.testing import DatabaseFunctionalLayer
from canonical.launchpad.testing.pages import webservice_for_person
from lp.blueprints.interfaces.specification import (
SpecificationDefinitionStatus,
)
from lp.testing import (
+<<<<<<< TREE
launchpadlib_for,
TestCaseWithFactory,
)
+=======
+ launchpadlib_for, TestCaseWithFactory)
+ launchpadlib_for_anonymous,
+ ws_object,
+>>>>>>> MERGE-SOURCE
class SpecificationWebserviceTestCase(TestCaseWithFactory):
@@ -215,6 +223,18 @@
names = [s.name for s in specifications]
self.assertContentEqual(expected_names, names)
+ def test_anonymous_access_to_collection(self):
+ product = self.factory.makeProduct()
+ self.factory.makeSpecification(product=product, name="spec1")
+ self.factory.makeSpecification(product=product, name="spec2")
+ # Need to endInteraction() because launchpadlib_for_anonymous() will
+ # setup a new one.
+ endInteraction()
+ lplib = launchpadlib_for_anonymous('lplib-test', version='devel')
+ ws_product = ws_object(lplib, product)
+ self.assertNamesOfSpecificationsAre(
+ ["spec1", "spec2"], ws_product.all_specifications)
+
def test_product_all_specifications(self):
product = self.factory.makeProduct()
self.factory.makeSpecification(product=product, name="spec1")
=== modified file 'lib/lp/testing/__init__.py'
--- lib/lp/testing/__init__.py 2010-11-26 10:52:10 +0000
+++ lib/lp/testing/__init__.py 2010-12-01 12:05:01 +0000
@@ -154,6 +154,7 @@
from lp.testing._webservice import (
launchpadlib_credentials_for,
launchpadlib_for,
+ launchpadlib_for_anonymous,
oauth_access_token_for,
)
from lp.testing.fixture import ZopeEventHandlerFixture
=== modified file 'lib/lp/testing/_webservice.py'
--- lib/lp/testing/_webservice.py 2010-10-23 16:44:23 +0000
+++ lib/lp/testing/_webservice.py 2010-12-01 12:05:01 +0000
@@ -8,6 +8,7 @@
__all__ = [
'launchpadlib_credentials_for',
'launchpadlib_for',
+ 'launchpadlib_for_anonymous',
'oauth_access_token_for',
]
@@ -17,6 +18,7 @@
from launchpadlib.credentials import (
AccessToken,
+ AnonymousAccessToken,
Credentials,
)
from launchpadlib.launchpad import Launchpad
@@ -118,6 +120,21 @@
shutil.rmtree(cache, ignore_errors=True)
+def launchpadlib_for_anonymous(
+ consumer_name, version=None, service_root="http://api.launchpad.dev/"):
+ """Create a Launchpad object for the anonymous user.
+
+ :param consumer_name: An OAuth consumer name.
+ :param version: The version of the web service to access.
+ :param service_root: The root URL of the web service to access.
+
+ :return: A launchpadlib.Launchpad object.
+ """
+ token = AnonymousAccessToken()
+ credentials = Credentials(consumer_name, access_token=token)
+ return Launchpad(credentials, service_root, version=version)
+
+
def launchpadlib_for(
consumer_name, person, permission=OAuthPermission.WRITE_PRIVATE,
context=None, version=None, service_root="http://api.launchpad.dev/"):