[Checkins] SVN: five.customerize/branches/plone-3.0-branch/src/five/customerize/ the security check is now deferred until the template/viewlet/portlet is actually called, because it may be looked up during traversal, in which case there's no proper security context yet

Andreas Zeidler az at zitc.de
Thu Jun 12 07:10:42 EDT 2008


Log message for revision 87325:
  the security check is now deferred until the template/viewlet/portlet is actually called, because it may be looked up during traversal, in which case there's no proper security context yet
  
  ps: many thanks to david glick for finally figuring out this long-standing issue! :)
  

Changed:
  U   five.customerize/branches/plone-3.0-branch/src/five/customerize/customerize.txt
  U   five.customerize/branches/plone-3.0-branch/src/five/customerize/utils.py
  U   five.customerize/branches/plone-3.0-branch/src/five/customerize/zpt.py

-=-
Modified: five.customerize/branches/plone-3.0-branch/src/five/customerize/customerize.txt
===================================================================
--- five.customerize/branches/plone-3.0-branch/src/five/customerize/customerize.txt	2008-06-12 09:34:36 UTC (rev 87324)
+++ five.customerize/branches/plone-3.0-branch/src/five/customerize/customerize.txt	2008-06-12 11:10:40 UTC (rev 87325)
@@ -164,10 +164,11 @@
 
 The newly registered adapter has an explicit security check that
 matches the original (in this case 'Manage Five local sites'),
-so the adapter lookup will fail unless logged in:
+so calling it will fail unless logged in:
 
   >>> view = zope.component.getMultiAdapter((item, request),
   ...                                       name=u"customizezpt.html")
+  >>> print view()
   Traceback (most recent call last):
   ...
   Unauthorized: The current user does not have the required "Manage Five local sites" permission

Modified: five.customerize/branches/plone-3.0-branch/src/five/customerize/utils.py
===================================================================
--- five.customerize/branches/plone-3.0-branch/src/five/customerize/utils.py	2008-06-12 09:34:36 UTC (rev 87324)
+++ five.customerize/branches/plone-3.0-branch/src/five/customerize/utils.py	2008-06-12 11:10:40 UTC (rev 87325)
@@ -1,3 +1,5 @@
+from AccessControl import getSecurityManager
+from AccessControl import Unauthorized
 from Products.PageTemplates.PageTemplateFile import PageTemplateFile as Z2PTF
 from zope.pagetemplate.pagetemplatefile import PageTemplateFile as Z3PTF
 from zope.app.pagetemplate.viewpagetemplatefile import BoundPageTemplate
@@ -25,3 +27,11 @@
         pass
     return None, None
 
+
+def checkPermission(permission, context):
+    sm = getSecurityManager()
+    if permission is not None:
+        if not sm.checkPermission(permission, context):
+            raise Unauthorized('The current user does not have the '
+                               'required "%s" permission' % permission)
+

Modified: five.customerize/branches/plone-3.0-branch/src/five/customerize/zpt.py
===================================================================
--- five.customerize/branches/plone-3.0-branch/src/five/customerize/zpt.py	2008-06-12 09:34:36 UTC (rev 87324)
+++ five.customerize/branches/plone-3.0-branch/src/five/customerize/zpt.py	2008-06-12 11:10:40 UTC (rev 87325)
@@ -1,6 +1,4 @@
 import zope.component
-from AccessControl import getSecurityManager
-from AccessControl import Unauthorized
 
 from zope.viewlet.viewlet import ViewletBase
 from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
@@ -9,6 +7,7 @@
 from zope.interface import implements
 
 from five.customerize.interfaces import ITTWViewTemplate
+from five.customerize.utils import checkPermission
 from plone.portlets.interfaces import IPortletRenderer
 from plone.portlets.interfaces import IPortletManager
 
@@ -34,20 +33,18 @@
         #XXX raise a sensible exception if context and request are
         # omitted, IOW, if someone tries to render the template not as
         # a view.
-        sm = getSecurityManager()
-        if self.permission:
-            if not sm.checkPermission(self.permission, context):
-                raise Unauthorized('The current user does not have the '
-                                   'required "%s" permission'
-                                   % self.permission)
+
+        # the security check is now deferred until the template/viewlet/portlet
+        # is actually called, because it may be looked up during traversal,
+        # in which case there's no proper security context yet
         if IPortletManager.providedBy(manager):
             return TTWPortletRenderer(context, request, self, self.view,
-                manager, data)
+                manager, data, self.permission)
         if IViewletManager.providedBy(manager):
             return TTWViewletRenderer(context, request, self, self.view,
-                viewlet, manager)
+                viewlet, manager, self.permission)
         else:
-            return TTWViewTemplateRenderer(context, request, self, self.view)
+            return TTWViewTemplateRenderer(context, request, self, self.view, self.permission)
 
     # overwrite Shared.DC.Scripts.Binding.Binding's before traversal
     # hook that would prevent to look up views for instances of this
@@ -55,6 +52,7 @@
     def __before_publishing_traverse__(self, self2, request):
         pass
 
+
 class TTWViewTemplateRenderer(object):
     """The view object for the TTW View Template.
 
@@ -64,11 +62,12 @@
     (__call__).
     """
 
-    def __init__(self, context, request, template, view):
+    def __init__(self, context, request, template, view, permission=None):
         self.context = context
         self.request = request
         self.template = template
         self.view = view
+        self.permission = permission
 
     def __call__(self, *args, **kwargs):
         """Render the TTWViewTemplate-based view.
@@ -85,6 +84,7 @@
         return template._exec(bound_names, args, kwargs)
 
     def _getView(self):
+        checkPermission(self.permission, self.context)
         view = self.view
         if view is not None:
             # Filesystem-based view templates are trusted code and
@@ -111,7 +111,7 @@
 
     __allow_access_to_unprotected_subobjects__ = True
 
-    def __init__(self, context, request, template, view, viewlet=None, manager=None):
+    def __init__(self, context, request, template, view, viewlet=None, manager=None, permission=None):
         self.context = context
         self.request = request
         self.template = template
@@ -119,6 +119,7 @@
         self.viewlet = viewlet
         self.manager = manager
         self.ttwviewlet = None
+        self.permission = permission
 
     def update(self):
         """ update the viewlet before `render` is called """
@@ -138,6 +139,7 @@
         return template._exec(bound_names, args, kwargs)
 
     def _getViewlet(self):
+        checkPermission(self.permission, self.context)
         if self.ttwviewlet is not None:
             return self.ttwviewlet
         view = self.view
@@ -167,7 +169,7 @@
 
     __allow_access_to_unprotected_subobjects__ = True
 
-    def __init__(self, context, request, template, view, manager=None, data=None):
+    def __init__(self, context, request, template, view, manager=None, data=None, permission=None):
         self.context = context
         self.request = request
         self.template = template
@@ -175,6 +177,7 @@
         self.manager = manager
         self.data = data
         self.renderer = None
+        self.permission = permission
 
     def update(self):
         """ update the portlet before `render` is called """
@@ -194,6 +197,7 @@
         return template._exec(bound_names, args, kwargs)
 
     def _getRenderer(self):
+        checkPermission(self.permission, self.context)
         if self.renderer is not None:
             return self.renderer
         view = self.view
@@ -229,3 +233,4 @@
             components.unregisterAdapter(reg.factory, reg.required,
                                          reg.provided, reg.name)
             break
+



More information about the Checkins mailing list