[Zope3-checkins] CVS: Zope3/src/zope/app/component - meta.zcml:1.5 metaconfigure.py:1.12

Philipp von Weitershausen philikon@philikon.de
Fri, 20 Jun 2003 18:00:22 -0400


Update of /cvs-repository/Zope3/src/zope/app/component
In directory cvs.zope.org:/tmp/cvs-serv12841

Modified Files:
	meta.zcml metaconfigure.py 
Log Message:
Added a "permission" attribute to the "factory" directive. Before,
custom factories were missing a security proxy wrapping in which case they
wouldn't appear in a browser menu, for example.


=== Zope3/src/zope/app/component/meta.zcml 1.4 => 1.5 ===
--- Zope3/src/zope/app/component/meta.zcml:1.4	Tue May 27 08:55:52 2003
+++ Zope3/src/zope/app/component/meta.zcml	Fri Jun 20 18:00:21 2003
@@ -11,7 +11,7 @@
     <directive name="utility" attributes="component provides permission name"
        handler="zope.app.component.metaconfigure.utility" />
 
-    <directive name="factory" attributes="component id"
+    <directive name="factory" attributes="component id permission"
        handler="zope.app.component.metaconfigure.factory" />
 
     <directive 


=== Zope3/src/zope/app/component/metaconfigure.py 1.11 => 1.12 ===
--- Zope3/src/zope/app/component/metaconfigure.py:1.11	Thu Jun 19 13:13:53 2003
+++ Zope3/src/zope/app/component/metaconfigure.py	Fri Jun 20 18:00:21 2003
@@ -13,16 +13,19 @@
 ##############################################################################
 
 from zope.configuration.exceptions import ConfigurationError
-from zope.security.proxy import Proxy
+from zope.security.proxy import Proxy, ProxyFactory
 from zope.component import getService, getServiceManager
 from zope.app.services.servicenames import Adapters, Interfaces, Skins
 from zope.app.services.servicenames import Views, Resources, Factories
 from zope.app.component.globalinterfaceservice import interfaceService
 from zope.configuration.action import Action
-from zope.security.checker import InterfaceChecker, CheckerPublic, Checker
+from zope.security.checker import InterfaceChecker, CheckerPublic, \
+     Checker, NamesChecker
 from zope.app.security.registries.permissionregistry import permissionRegistry
 from zope.component.service import UndefinedService
 
+PublicPermission = 'zope.Public'
+
 # I prefer the indirection (using getService and getServiceManager vs.
 # directly importing the various services)  not only because it makes
 # unit tests easier, but also because it reinforces that the services
@@ -76,7 +79,7 @@
     factory = map(_context.resolve, factory.split())
 
     if permission is not None:
-        if permission == 'zope.Public':
+        if permission == PublicPermission:
             permission = CheckerPublic
         checker = InterfaceChecker(provides, permission)
         factory.append(lambda c: Proxy(c, checker))
@@ -119,7 +122,7 @@
         component = _context.resolve(component)
 
     if permission is not None:
-        if permission == 'zope.Public':
+        if permission == PublicPermission:
             permission = CheckerPublic
         checker = InterfaceChecker(provides, permission)
 
@@ -141,7 +144,7 @@
         ]
 
 
-def factory(_context, component, id=None):
+def factory(_context, component, id=None, permission=None):
     if id is None:
         id = component
 
@@ -150,16 +153,33 @@
     return [
         Action(
             discriminator = ('factory', id),
-            callable = handler,
-            args = (Factories, 'provideFactory', id, component),
+            callable = provideFactory,
+            args = (id, component, permission),
             )
         ]
 
+def provideFactory(name, factory, permission):
+    # make sure the permission is defined
+    if permission is not None:
+        permissionRegistry.ensurePermissionDefined(permission)
+
+    if permission == PublicPermission:
+        permission = CheckerPublic
+
+    if permission:
+        # XXX should getInterfaces be public, as below?
+        factory = ProxyFactory(factory,
+                               NamesChecker(('getInterfaces',),
+                                            __call__=permission))
+
+    getService(None, Factories).provideFactory(name, factory)
+
+
 def _checker(_context, permission, allowed_interface, allowed_attributes):
     if (not allowed_attributes) and (not allowed_interface):
         allowed_attributes = "__call__"
 
-    if permission == 'zope.Public':
+    if permission == PublicPermission:
         permission = CheckerPublic
 
     require={}
@@ -344,7 +364,7 @@
         else:
             raise UndefinedService(serviceType)
 
-        if permission == 'zope.Public':
+        if permission == PublicPermission:
             permission = CheckerPublic
 
         checker = InterfaceChecker(interface, permission)