[Checkins] SVN: grok/trunk/src/grok/ Fix bug reported by Whit: Local grants wouldn't be honoured by REST views.

Philipp von Weitershausen philikon at philikon.de
Fri May 16 14:55:51 EDT 2008


Log message for revision 86800:
  Fix bug reported by Whit: Local grants wouldn't be honoured by REST views.
  This was due to their lack of setting self.__parent__ (even though there
  existed a piece of code in grok.rest that seemed to "want" to do this, but
  it was never called).
  

Changed:
  U   grok/trunk/src/grok/components.py
  A   grok/trunk/src/grok/ftests/rest/localgrants.py
  U   grok/trunk/src/grok/meta.py
  U   grok/trunk/src/grok/rest.py

-=-
Modified: grok/trunk/src/grok/components.py
===================================================================
--- grok/trunk/src/grok/components.py	2008-05-16 18:53:52 UTC (rev 86799)
+++ grok/trunk/src/grok/components.py	2008-05-16 18:55:51 UTC (rev 86800)
@@ -21,6 +21,7 @@
 import pytz
 import simplejson
 
+import zope.location
 from zope import component
 from zope import interface
 from zope.interface.common import idatetime
@@ -242,11 +243,11 @@
 class XMLRPC(object):
     pass
 
-class REST(object):
+class REST(zope.location.Location):
     interface.implements(interfaces.IREST)
 
     def __init__(self, context, request):
-        self.context = context
+        self.context = self.__parent__ = context
         self.request = request
         self.body = request.bodyStream.getCacheStream().read()
 

Added: grok/trunk/src/grok/ftests/rest/localgrants.py
===================================================================
--- grok/trunk/src/grok/ftests/rest/localgrants.py	                        (rev 0)
+++ grok/trunk/src/grok/ftests/rest/localgrants.py	2008-05-16 18:55:51 UTC (rev 86800)
@@ -0,0 +1,75 @@
+"""
+REST objects, like all views, are properly located objects and will
+therefore honour local grants, for instance.  Let's consider the
+following model in the root folder.  
+
+  >>> root = getRootFolder()
+  >>> root['manfred'] = manfred = Mammoth('manfred')
+
+For this model we have registered a REST GET view that's protected
+with a permission.  Therefore we can't access it as anonymous:
+
+  >>> print http(r'''
+  ... GET /++rest++mammoth/manfred HTTP/1.1
+  ... ''')
+  HTTP/1.1 401 Unauthorized
+  Content-Length: 0
+  Content-Type: text/plain
+  WWW-Authenticate: basic realm="Zope"
+
+However, if we make a (local!) grant, e.g. on the root object, we can
+access the view just fine:
+
+  >>> from zope.securitypolicy.interfaces import IPrincipalPermissionManager
+  >>> root_perms = IPrincipalPermissionManager(root)
+  >>> root_perms.grantPermissionToPrincipal('mammoth.Touch', 'zope.anybody')
+
+With the grant in place we can access it as anonymous:
+
+  >>> print http(r'''
+  ... GET /++rest++mammoth/manfred HTTP/1.1
+  ... ''')
+  HTTP/1.1 200 Ok
+  Content-Length: 7
+  Content-Type: text/plain
+  <BLANKLINE>
+  manfred
+
+In fact, inspecting the view object itself, we see that it is a true
+ILocation and has the appropriate parent pointer:
+
+  >>> from zope.publisher.browser import TestRequest
+  >>> request = TestRequest(skin=MammothRestLayer)
+  >>> from zope.component import getMultiAdapter
+  >>> view = getMultiAdapter((manfred, request), name='GET')
+
+  >>> from zope.location.interfaces import ILocation
+  >>> ILocation.providedBy(view)
+  True
+  >>> view.__parent__ is manfred
+  True
+
+"""
+import grok
+
+class Mammoth(grok.Model):
+
+    def __init__(self, name):
+        self.name = name
+
+class MammothRestLayer(grok.IRESTLayer):
+    pass
+
+class MammothRestProtocol(grok.RESTProtocol):
+    grok.layer(MammothRestLayer)
+    grok.name('mammoth')
+
+class TouchMammoth(grok.Permission):
+    grok.name('mammoth.Touch')
+
+class MammothRest(grok.REST):
+    grok.layer(MammothRestLayer)
+
+    @grok.require(TouchMammoth)
+    def GET(self):
+        return self.context.name


Property changes on: grok/trunk/src/grok/ftests/rest/localgrants.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: grok/trunk/src/grok/meta.py
===================================================================
--- grok/trunk/src/grok/meta.py	2008-05-16 18:53:52 UTC (rev 86799)
+++ grok/trunk/src/grok/meta.py	2008-05-16 18:55:51 UTC (rev 86800)
@@ -51,7 +51,6 @@
 from grok import components, formlib, templatereg
 from grok.util import check_permission, make_checker
 from grok.util import public_methods_from_class
-from grok.rest import RestPublisher
 from grok.interfaces import IRESTSkinType
 from grok.interfaces import IViewletManager as IGrokViewletManager
 
@@ -160,10 +159,8 @@
         for method in methods:
             name = method.__name__
 
-            # Make sure that the class inherits RestPublisher, so that the
-            # views have a location
             method_view = type(
-                factory.__name__, (factory, RestPublisher),
+                factory.__name__, (factory,),
                 {'__call__': method }
                 )
 

Modified: grok/trunk/src/grok/rest.py
===================================================================
--- grok/trunk/src/grok/rest.py	2008-05-16 18:53:52 UTC (rev 86799)
+++ grok/trunk/src/grok/rest.py	2008-05-16 18:55:51 UTC (rev 86800)
@@ -8,22 +8,12 @@
 from zope.interface import Interface
 from zope.interface.interfaces import IInterface
 from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.publisher.interfaces.browser import IBrowserPublisher
 from zope.publisher.interfaces.http import IHTTPRequest
 from zope.app.publication.http import MethodNotAllowed
-import zope.location
 
 from grok.interfaces import IRESTSkinType
 from zope.publisher.browser import applySkin
 
-class RestPublisher(zope.location.Location):
-    grok.implements(IBrowserPublisher)
-
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-        self.__parent__ = self.context
-
 class GrokMethodNotAllowed(MethodNotAllowed):
     pass
 



More information about the Checkins mailing list