[Checkins] SVN: grok/branches/jw-define-roles-directive/src/grok/ Implement define_role directive.

Jan-Wijbrand Kolman janwijbrand at gmail.com
Thu Jul 26 04:08:50 EDT 2007


Log message for revision 78346:
  Implement define_role directive.

Changed:
  U   grok/branches/jw-define-roles-directive/src/grok/__init__.py
  U   grok/branches/jw-define-roles-directive/src/grok/directive.py
  A   grok/branches/jw-define-roles-directive/src/grok/ftests/security/roles.py
  U   grok/branches/jw-define-roles-directive/src/grok/meta.py
  A   grok/branches/jw-define-roles-directive/src/grok/tests/security/wrong_permissions_argument.py
  A   grok/branches/jw-define-roles-directive/src/grok/tests/security/wrong_permissions_argument_fixture.py

-=-
Modified: grok/branches/jw-define-roles-directive/src/grok/__init__.py
===================================================================
--- grok/branches/jw-define-roles-directive/src/grok/__init__.py	2007-07-26 07:29:48 UTC (rev 78345)
+++ grok/branches/jw-define-roles-directive/src/grok/__init__.py	2007-07-26 08:08:47 UTC (rev 78346)
@@ -37,7 +37,7 @@
 from grok.components import Indexes
 from grok.directive import (context, name, template, templatedir, provides,
                             baseclass, global_utility, local_utility,
-                            define_permission, require, site)
+                            define_permission, define_role, require, site)
 from grok._grok import do_grok as grok  # Avoid name clash within _grok
 from grok._grok import grok_component
 from grok._grok import SubscribeDecorator as subscribe

Modified: grok/branches/jw-define-roles-directive/src/grok/directive.py
===================================================================
--- grok/branches/jw-define-roles-directive/src/grok/directive.py	2007-07-26 07:29:48 UTC (rev 78345)
+++ grok/branches/jw-define-roles-directive/src/grok/directive.py	2007-07-26 08:08:47 UTC (rev 78346)
@@ -13,7 +13,7 @@
 ##############################################################################
 """Grok directives.
 """
-
+import types
 from zope.interface.interfaces import IInterface
 
 from martian.error import GrokImportError
@@ -47,7 +47,7 @@
         if provides is None:
             provides = util.class_annotation(factory, 'grok.provides', None)
         self.provides = provides
-        
+
         if name is u'':
             name = util.class_annotation(factory, 'grok.name', u'')
         self.name = name
@@ -77,6 +77,18 @@
         self.name_in_container = name_in_container
 
 
+class DefineRoleDirective(MultipleTimesDirective):
+
+    def check_arguments(self, id, permissions):
+        if not isinstance(permissions, (types.ListType, types.TupleType)):
+            raise GrokImportError(
+                "You need to pass a list or tuple of permission ids to the "
+                "permissions argument of %s." % self.name)
+
+    def value_factory(self, id, permissions):
+        return (id, permissions)
+
+
 class RequireDirective(BaseTextDirective, SingleValue, MultipleTimesDirective):
 
     def store(self, frame, value):
@@ -93,6 +105,7 @@
             return func
         return decorator
 
+
 # Define grok directives
 name = SingleTextDirective('grok.name', ClassDirectiveContext())
 template = SingleTextDirective('grok.template', ClassDirectiveContext())
@@ -107,6 +120,7 @@
                                       ClassDirectiveContext())
 define_permission = MultipleTextDirective('grok.define_permission',
                                           ModuleDirectiveContext())
+define_role = DefineRoleDirective('grok.define_role', ModuleDirectiveContext())
 require = RequireDirective('grok.require', ClassDirectiveContext())
 site = InterfaceOrClassDirective('grok.site',
                                  ClassDirectiveContext())

Added: grok/branches/jw-define-roles-directive/src/grok/ftests/security/roles.py
===================================================================
--- grok/branches/jw-define-roles-directive/src/grok/ftests/security/roles.py	                        (rev 0)
+++ grok/branches/jw-define-roles-directive/src/grok/ftests/security/roles.py	2007-07-26 08:08:47 UTC (rev 78346)
@@ -0,0 +1,89 @@
+"""
+  >>> import grok
+  >>> grok.grok('grok.ftests.security.roles')
+
+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
+  >>> browser.open("http://localhost/@@editcavepainting")
+  Traceback (most recent call last):
+  HTTPError: HTTP Error 401: Unauthorized
+  >>> browser.open("http://localhost/@@erasecavepainting")
+  Traceback (most recent call last):
+  HTTPError: HTTP Error 401: Unauthorized
+
+When we log in (e.g. as a manager), we can access the views just fine:
+
+  >>> from zope.app.securitypolicy.principalrole import principalRoleManager
+  >>> principalRoleManager.assignRoleToPrincipal(
+  ...    'grok.PaintingOwner', 'zope.mgr')
+  >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+  >>> browser.handleErrors = False
+  >>> browser.open("http://localhost/@@cavepainting")
+  >>> print browser.contents
+  What a beautiful painting.
+
+  >>> browser.open("http://localhost/@@editcavepainting")
+  >>> print browser.contents
+  Let's make it even prettier.
+
+  >>> browser.open("http://localhost/@@erasecavepainting")
+  >>> print browser.contents
+  Oops, mistake, let's erase it.
+
+  >>> browser.open("http://localhost/@@approvecavepainting")
+  Traceback (most recent call last):
+  ...
+  Unauthorized: (<grok.ftests.security.roles.ApproveCavePainting object at ...>,
+  '__call__', 'grok.ApprovePainting')
+
+"""
+
+import grok
+import zope.interface
+
+grok.define_permission('grok.ViewPainting')
+grok.define_permission('grok.EditPainting')
+grok.define_permission('grok.ErasePainting')
+grok.define_permission('grok.ApprovePainting')
+
+grok.define_role(
+    'grok.PaintingOwner',
+    ('grok.ViewPainting', 'grok.EditPainting', 'grok.ErasePainting'))
+
+class CavePainting(grok.View):
+
+    grok.context(zope.interface.Interface)
+    grok.require('grok.ViewPainting')
+
+    def render(self):
+        return 'What a beautiful painting.'
+
+class EditCavePainting(grok.View):
+
+    grok.context(zope.interface.Interface)
+    grok.require('grok.EditPainting')
+
+    def render(self):
+        return 'Let\'s make it even prettier.'
+
+class EraseCavePainting(grok.View):
+
+    grok.context(zope.interface.Interface)
+    grok.require('grok.ErasePainting')
+
+    def render(self):
+        return 'Oops, mistake, let\'s erase it.'
+
+class ApproveCavePainting(grok.View):
+
+    grok.context(zope.interface.Interface)
+    grok.require('grok.ApprovePainting')
+
+    def render(self):
+        return 'Painting owners cannot approve their paintings.'

Modified: grok/branches/jw-define-roles-directive/src/grok/meta.py
===================================================================
--- grok/branches/jw-define-roles-directive/src/grok/meta.py	2007-07-26 07:29:48 UTC (rev 78345)
+++ grok/branches/jw-define-roles-directive/src/grok/meta.py	2007-07-26 08:08:47 UTC (rev 78346)
@@ -23,6 +23,9 @@
 from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
 from zope.security.permission import Permission
 from zope.security.interfaces import IPermission
+from zope.app.securitypolicy.role import Role
+from zope.app.securitypolicy.rolepermission import rolePermissionManager
+
 from zope.annotation.interfaces import IAnnotations
 
 from zope.app.publisher.xmlrpc import MethodPublisher
@@ -509,6 +512,20 @@
         return True
 
 
+class DefineRoleGrokker(martian.GlobalGrokker):
+
+    priority = 1500
+
+    def grok(self, name, module, context, module_info, templates):
+        role_infos = module_info.getAnnotation('grok.define_role', [])
+        for role_id, permissions in role_infos:
+            component.provideUtility(
+                Role(role_id, title=role_id), name=role_id)
+            for permission in permissions:
+                rolePermissionManager.grantPermissionToRole(permission, role_id)
+        return True
+
+
 class AnnotationGrokker(martian.ClassGrokker):
     component_class = grok.Annotation
 

Copied: grok/branches/jw-define-roles-directive/src/grok/tests/security/wrong_permissions_argument.py (from rev 78343, grok/branches/jw-define-roles-directive/src/grok/tests/security/view_decorator.py)
===================================================================
--- grok/branches/jw-define-roles-directive/src/grok/tests/security/wrong_permissions_argument.py	                        (rev 0)
+++ grok/branches/jw-define-roles-directive/src/grok/tests/security/wrong_permissions_argument.py	2007-07-26 08:08:47 UTC (rev 78346)
@@ -0,0 +1,12 @@
+"""
+The grok.define_role needs a sequence of permission ids::
+
+  >>> grok.grok('grok.tests.security.wrong_permissions_argument_fixture')
+  Traceback (most recent call last):
+  GrokImportError: You need to pass a list or tuple of permission ids to
+  the permissions argument of grok.define_role.
+
+
+"""
+
+import grok

Added: grok/branches/jw-define-roles-directive/src/grok/tests/security/wrong_permissions_argument_fixture.py
===================================================================
--- grok/branches/jw-define-roles-directive/src/grok/tests/security/wrong_permissions_argument_fixture.py	                        (rev 0)
+++ grok/branches/jw-define-roles-directive/src/grok/tests/security/wrong_permissions_argument_fixture.py	2007-07-26 08:08:47 UTC (rev 78346)
@@ -0,0 +1,2 @@
+import grok
+grok.define_role('caveman.Firemaker', 'use.Matches')



More information about the Checkins mailing list