[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Publisher/Browser - __init__.py:1.1.2.1 browser-meta.zcml:1.1.2.1 browser.zcml:1.1.2.1 metaConfigure.py:1.1.2.1

Jim Fulton jim@zope.com
Thu, 30 May 2002 14:26:59 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/App/Publisher/Browser
In directory cvs.zope.org:/tmp/cvs-serv20275/lib/python/Zope/App/Publisher/Browser

Added Files:
      Tag: Zope3InWonderland-branch
	__init__.py browser-meta.zcml browser.zcml metaConfigure.py 
Log Message:
Implemented browser:page directives for browser:view, browser:resource. 

Implemented security assertions in view and resource directives.

Changed defaultView so you can omit a factory, which just sets the
default view name without defining a view.

Moved Browser and ComponentArchitecture directive support to App,
because of all of the dependencies on other packages.



=== Added File Zope3/lib/python/Zope/App/Publisher/Browser/__init__.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""Configuration of the browser framework for Zope
"""



=== Added File Zope3/lib/python/Zope/App/Publisher/Browser/browser-meta.zcml ===
<zopeConfigure xmlns='http://namespaces.zope.org/zope'>
  
  <directives namespace="http://namespaces.zope.org/browser">

    <directive 
       name="view" 
       attributes="component, name, for, layer,
                   permission_id, allowed_interface, allowed_attributes"
       handler="Zope.App.Publisher.Browser.metaConfigure.view" >
       <subdirective name="page" 
                     attributes="name attribute permission_id layer" 
       /> 
       <subdirective name="defaultPage" 
                     attributes="name attribute permission_id" 
       /> 
    </directive>

    <directive 
       name="defaultView" 
       attributes="component, name, for, layer"
       handler="Zope.App.Publisher.Browser.metaConfigure.defaultView" />

    <directive
        name="resource"
        attributes="component, name, layer,
                    permission_id, allowed_interface, allowed_attributes"
        handler="Zope.App.Publisher.Browser.metaConfigure.resource">
       <subdirective name="page" 
                     attributes="name attribute permission_id layer" 
       /> 
    </directive>

    <directive name="skin" attributes="name, layers" 
        handler="Zope.App.Publisher.Browser.metaConfigure.skin" />

  </directives>

</zopeConfigure>


=== Added File Zope3/lib/python/Zope/App/Publisher/Browser/browser.zcml ===
<zopeConfigure
   xmlns='http://namespaces.zope.org/zope'
   xmlns:security='http://namespaces.zope.org/security'
>

  <security:protectClass class=".BrowserRequest."
                         permission_id="Zope.Public">
    <security:protect interface=".IBrowserApplicationRequest." />
    <security:protect 
       interface="Zope.ComponentArchitecture.IViewService.IViewRequest" />
  </security:protectClass>

</zopeConfigure>


=== Added File Zope3/lib/python/Zope/App/Publisher/Browser/metaConfigure.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
# 
##############################################################################
"""Browser configuration code

$Id: metaConfigure.py,v 1.1.2.1 2002/05/30 18:26:57 jim Exp $
"""

from Zope.Security.Proxy import Proxy
from Zope.Security.Checker \
     import InterfaceChecker, CheckerPublic, NamesChecker, Checker

from Zope.Configuration.Action import Action
from Zope.Configuration.Exceptions import ConfigurationError

from Zope.Publisher.Browser.IBrowserPresentation import IBrowserPresentation

from Zope.App.ComponentArchitecture.metaConfigure \
     import defaultView as _defaultView, skin as _skin, handler

def defaultView(_context, **__kw):
    return _defaultView(_context,
                        type='Zope.Publisher.Browser.IBrowserPresentation.',
                        **__kw)

def skin(_context, **__kw):
    return _skin(_context,
                 type='Zope.Publisher.Browser.IBrowserPresentation.',
                 **__kw)

class resource:

    type = IBrowserPresentation

    def __init__(self, _context, factory, name=None, layer='',
                 permission_id=None,
                 allowed_interface=None, allowed_attributes=None):

        if ((allowed_attributes or allowed_interface)
            and (not name or not permission_id)):
            raise ConfigurationError(
                "Must use name attribute with allowed_interface or "
                "allowed_attributes"
                )

        if allowed_interface is not None:
            allowed_interface = _context.resolve(allowed_interface)

        self.factory = self._factory(_context, factory)
        self.layer = layer
        self.name = name
        self.permission_id = permission_id
        self.allowed_attributes = allowed_attributes
        self.allowed_interface = allowed_interface
        self.pages = 0

    def _factory(self, _context, factory):
        return _context.resolve(factory)

    def page(self, _context, name, attribute, permission_id=None, layer=None):

        permission_id = permission_id or self.permission_id

        factory = self._pageFactory(self.factory, attribute, permission_id)

        self.pages += 1

        if layer is None:
            layer = self.layer

        return [
            Action(
                discriminator = self._discriminator(name, layer),
                callable = handler,
                args = self._args(name, factory, layer),
                )
            ]

    def _discriminator(self, name, layer):
        return ('resource', name, self.type, layer)

    def _args(self, name, factory, layer):
        return ('Resources', 'provideResource',
                name, self.type, factory, layer)
        
    def _pageFactory(self, factory, attribute, permission_id):
        if permission_id:
            if permission_id == 'Zope.Public':
                permission_id = CheckerPublic

            def pageView(request,
                         factory=factory, attribute=attribute,
                         permission_id=permission_id):
                return Proxy(getattr(factory(request), attribute),
                             NamesChecker(__call__ = permission_id))

        else:

            def pageView(request,
                         factory=factory, attribute=attribute):
                return getattr(factory(request), attribute)

        return pageView

    def __call__(self):
        if not self.name:
            return ()

        permission_id = self.permission_id
        allowed_interface = self.allowed_interface
        allowed_attributes = self.allowed_attributes
        factory = self.factory

        if permission_id:
            if permission_id == 'Zope.Public':
                permission_id = CheckerPublic
            
            if (not allowed_attributes) and (allowed_interface is None):
                if not self.pages:
                    raise ConfigurationError(
                        "Must specify allowed_interface or allowed_names "
                        "to be allowed with permission_id.")

            else:

                require={}
                for name in (allowed_attributes or '').split():
                    require[name] = permission_id
                if allowed_interface:
                    for name in allowed_interface.names(1):
                        require[name] = permission_id

                checker = Checker(require.get)

                factory = self._proxyFactory(factory, checker)


        return [
            Action(
                discriminator = self._discriminator(self.name, self.layer),
                callable = handler,
                args = self._args(self.name, factory, self.layer),
                )
            ]

    def _proxyFactory(self, factory, checker):
        def proxyView(request,
                      factory=factory, checker=checker):
            return Proxy(factory(request), checker)

        return proxyView

class view(resource):

    def __init__(self, _context, factory, name=None, for_=None,
                 layer='',
                 permission_id=None,
                 allowed_interface=None, allowed_attributes=None):

        resource.__init__(self, _context, factory, name, layer,
                          permission_id, allowed_interface, allowed_attributes)


        if for_ is not None:
            for_ = _context.resolve(for_)
        self.for_ = for_

    def defaultPage(self, _context, name, attribute, permission_id=None):

        actions = self.page(_context, name, attribute, permission_id)

        actions += [Action(
            discriminator = ('defaultViewName', self.for_, name, self.type),
            callable = handler,
            args = ('Views','setDefaultViewName', self.for_, self.type, name),
            )]

        return actions

    def _factory(self, _context, factory):
        return map(_context.resolve, factory.strip().split())

    def _discriminator(self, name, layer):
        return ('view', self.for_, name, self.type, layer)

    def _args(self, name, factory, layer):
        return ('Views', 'provideView',
                self.for_, name, self.type, factory, layer)

    def _pageFactory(self, factory, attribute, permission_id):

        factory = factory[:]        
        
        if permission_id:
            if permission_id == 'Zope.Public':
                permission_id = CheckerPublic

            def pageView(context, request,
                         factory=factory[-1], attribute=attribute,
                         permission_id=permission_id):
                return Proxy(getattr(factory(context, request), attribute),
                             NamesChecker(__call__ = permission_id))

        else:

            def pageView(context, request,
                         factory=factory[-1], attribute=attribute):
                return getattr(factory(context, request), attribute)

        factory[-1] = pageView

        return factory

    def _proxyFactory(self, factory, checker):

        factory = factory[:]        

        def proxyView(context, request,
                      factory=factory[-1], checker=checker):
            return Proxy(factory(context, request), checker)

        factory[-1] =  proxyView

        return factory