[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/ComponentArchitecture - metaConfigure.py:1.1.2.6

Jim Fulton jim@zope.com
Tue, 4 Jun 2002 12:43:48 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/App/ComponentArchitecture
In directory cvs.zope.org:/tmp/cvs-serv7653/lib/python/Zope/App/ComponentArchitecture

Modified Files:
      Tag: Zope3InWonderland-branch
	metaConfigure.py 
Log Message:
Added permission attribute for service directives. This lets you set
security within the service directive itself.

Added a __Security_checker__ attribute, checked by the ProxyFactory
that specifies a checker to be used for proxies. This allows us to
record the permission requirements on a component without actually
creating a proxy. If this attribute can't be set, we'll go ahead and
create the proxy anyway.




=== Zope3/lib/python/Zope/App/ComponentArchitecture/metaConfigure.py 1.1.2.5 => 1.1.2.6 ===
      import InterfaceChecker, CheckerPublic, NamesChecker, Checker
 
+from Zope.ComponentArchitecture.GlobalServiceManager \
+     import UndefinedService
+
 # 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
 # should always be obtained through the
 # IPlacefulComponentArchitecture interface methods
 
+# But these services aren't placeful! And we need to get at things that
+# normal service clients don't need!   Jim
+
+
+
 def handler(serviceName, methodName, *args, **kwargs):
     method=getattr(getService(None, serviceName), methodName)
     method(*args, **kwargs)
@@ -200,19 +208,46 @@
 def serviceType(_context, id, interface):
     return [
         Action(
-            discriminator = ('serviceType', id),
+            discriminator = ('serviceType', id),        
             callable = managerHandler,
             args = ('defineService', id, _context.resolve(interface)),
             )
         ]
 
+def provideService(serviceType, component, permission):
+    # This is needed so we can add a security proxy.
+    # We have to wait till execution time so we can find out the interface.
+    # Waaaa.
+
+    service_manager = getServiceManager(None)
+
+    if permission:
+        
+        for stype, interface in service_manager.getServiceDefinitions():
+            if stype == serviceType:
+                break
+        else:
+            raise UndefinedService(serviceType)
+
+        if permission == 'Zope.Public':
+            permission = CheckerPublic
+    
+        checker = InterfaceChecker(interface, permission)
+
+        try:
+            component.__Security_checker__ = checker
+        except: # too bad exceptions aren't more predictable
+            component = Proxy(component, checker)
+
+    service_manager.provideService(serviceType, component)
+    
 def service(_context, serviceType, component, permission=None):
     component = _context.resolve(component)
     return [
         Action(
-            discriminator = ('service', serviceType),
-            callable = managerHandler,
-            args = ('provideService', serviceType, component),
+            discriminator = ('service', serviceType),        
+            callable = provideService,
+            args = (serviceType, component, permission),
             )
         ]