[Checkins] SVN: grok/trunk/src/grok/ Implemented grok.require as a class-level annotation, and a security

Philipp von Weitershausen philikon at philikon.de
Sun Jan 7 05:59:37 EST 2007


Log message for revision 71754:
  Implemented grok.require as a class-level annotation, and a security
  check during publication.
  

Changed:
  U   grok/trunk/src/grok/__init__.py
  U   grok/trunk/src/grok/directive.py
  A   grok/trunk/src/grok/ftests/security/require.py
  U   grok/trunk/src/grok/meta.py
  U   grok/trunk/src/grok/publication.py
  U   grok/trunk/src/grok/templatereg.py

-=-
Modified: grok/trunk/src/grok/__init__.py
===================================================================
--- grok/trunk/src/grok/__init__.py	2007-01-07 10:32:39 UTC (rev 71753)
+++ grok/trunk/src/grok/__init__.py	2007-01-07 10:59:36 UTC (rev 71754)
@@ -35,7 +35,8 @@
 from grok.components import Site, GlobalUtility, LocalUtility
 from grok.components import EditForm, DisplayForm, AddForm
 from grok.directive import (context, name, template, templatedir, provides,
-                            global_utility, local_utility)
+                            global_utility, local_utility, define_permission,
+                            require)
 from grok._grok import do_grok as grok  # Avoid name clash within _grok
 from grok._grok import SubscribeDecorator as subscribe
 from grok.error import GrokError, GrokImportError

Modified: grok/trunk/src/grok/directive.py
===================================================================
--- grok/trunk/src/grok/directive.py	2007-01-07 10:32:39 UTC (rev 71753)
+++ grok/trunk/src/grok/directive.py	2007-01-07 10:59:36 UTC (rev 71754)
@@ -212,3 +212,6 @@
                                         ModuleDirectiveContext())
 local_utility = LocalUtilityDirective('grok.local_utility',
                                       ClassDirectiveContext())
+define_permission = TextDirective('grok.define_permission',
+                                  ModuleDirectiveContext())
+require = TextDirective('grok.require', ClassDirectiveContext())

Added: grok/trunk/src/grok/ftests/security/require.py
===================================================================
--- grok/trunk/src/grok/ftests/security/require.py	2007-01-07 10:32:39 UTC (rev 71753)
+++ grok/trunk/src/grok/ftests/security/require.py	2007-01-07 10:59:36 UTC (rev 71754)
@@ -0,0 +1,38 @@
+"""
+  >>> import grok
+  >>> grok.grok('grok.ftests.security.require')
+
+Viewing a protected view with insufficient privileges will yield
+Unauthorized:
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.open("http://localhost/@@cavepainting")
+  Traceback (most recent call last):
+  HTTPError: HTTP Error 401: Unauthorized
+
+When we log in (e.g. as a manager), we can access the view just fine:
+
+  >>> from zope.app.securitypolicy.rolepermission import rolePermissionManager
+  >>> rolePermissionManager.grantPermissionToRole('grok.ViewPainting',
+  ...                                             'zope.Manager')
+  >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+  >>> browser.handleErrors = False
+  >>> browser.open("http://localhost/@@cavepainting")
+  >>> print browser.contents
+  What a beautiful painting.
+
+"""
+
+import grok
+import zope.interface
+
+grok.define_permission('grok.ViewPainting')
+
+class CavePainting(grok.View):
+
+    grok.context(zope.interface.Interface)
+    grok.require('grok.ViewPainting')
+
+    def render(self):
+        return 'What a beautiful painting.'


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

Modified: grok/trunk/src/grok/meta.py
===================================================================
--- grok/trunk/src/grok/meta.py	2007-01-07 10:32:39 UTC (rev 71753)
+++ grok/trunk/src/grok/meta.py	2007-01-07 10:59:36 UTC (rev 71754)
@@ -6,8 +6,11 @@
 from zope.publisher.interfaces.browser import (IDefaultBrowserLayer,
                                                IBrowserRequest,
                                                IBrowserPublisher)
+from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
+from zope.security.checker import NamesChecker, defineChecker
+from zope.security.permission import Permission
+
 from zope.app.publisher.xmlrpc import MethodPublisher
-from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
 from zope.app.container.interfaces import INameChooser
 
 import grok
@@ -63,7 +66,7 @@
 
 class XMLRPCGrokker(grok.ClassGrokker):
     component_class = grok.XMLRPC
-    
+
     def register(self, context, name, factory, module_info, templates):
         view_context = util.determine_class_context(factory, context)
         candidates = [getattr(factory, name) for name in dir(factory)]
@@ -81,6 +84,9 @@
                 interface.Interface,
                 name=method.__name__)
 
+            checker = NamesChecker(['__call__'])
+            defineChecker(method_view, checker)
+
 class ViewGrokker(grok.ClassGrokker):
     component_class = grok.View
 
@@ -159,6 +165,14 @@
                                  provides=interface.Interface,
                                  name=view_name)
 
+        # protect view, public by default
+        permission = util.class_annotation(factory, 'grok.require', None)
+        if permission is None:
+            checker = NamesChecker(['__call__'])
+        else:
+            checker = NamesChecker(['__call__'], permission)
+        defineChecker(factory, checker)
+
 class TraverserGrokker(grok.ClassGrokker):
     component_class = grok.Traverser
 
@@ -278,3 +292,11 @@
             # register utility
             site_manager.registerUtility(utility, provided=info.provides,
                                          name=info.name)
+
+class DefinePermissionGrokker(grok.ModuleGrokker):
+
+    def register(self, context, module_info, templates):
+        permissions = module_info.getAnnotation('grok.define_permission', [])
+        for permission in permissions:
+            # TODO permission title and description
+            component.provideUtility(Permission(permission), name=permission)

Modified: grok/trunk/src/grok/publication.py
===================================================================
--- grok/trunk/src/grok/publication.py	2007-01-07 10:32:39 UTC (rev 71753)
+++ grok/trunk/src/grok/publication.py	2007-01-07 10:59:36 UTC (rev 71754)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2006 Zope Corporation and Contributors.
+# Copyright (c) 2007 Zope Corporation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
@@ -15,6 +15,7 @@
 """
 
 from zope.security.proxy import removeSecurityProxy
+from zope.security.checker import selectChecker
 
 from zope.app.publication.http import BaseHTTPPublication
 from zope.app.publication.browser import BrowserPublication
@@ -33,7 +34,14 @@
             request, ob, name)
         return removeSecurityProxy(result)
 
+    def callObject(self, request, ob):
+        checker = selectChecker(ob)
+        if checker is not None:
+            #import pdb; pdb.set_trace()
+            checker.check(ob, '__call__')
+        return super(ZopePublicationSansProxy, self).callObject(request, ob)
 
+
 class GrokBrowserPublication(ZopePublicationSansProxy, BrowserPublication):
 
     def getDefaultTraversal(self, request, ob):

Modified: grok/trunk/src/grok/templatereg.py
===================================================================
--- grok/trunk/src/grok/templatereg.py	2007-01-07 10:32:39 UTC (rev 71753)
+++ grok/trunk/src/grok/templatereg.py	2007-01-07 10:59:36 UTC (rev 71754)
@@ -2,6 +2,7 @@
 
 from zope import interface, component
 from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+from zope.security.checker import NamesChecker, defineChecker
 
 import grok
 from grok import util
@@ -84,3 +85,7 @@
                                      adapts=(context, IDefaultBrowserLayer),
                                      provides=interface.Interface,
                                      name=name)
+
+            # protect view, public by default
+            checker = NamesChecker(['__call__'])
+            defineChecker(TemplateView, checker)



More information about the Checkins mailing list