Beispiel #1
0
def viewletManagerDirective(
    _context, name, permission,
    for_=Interface, layer=IDefaultBrowserLayer, view=IBrowserView,
    provides=interfaces.IViewletManager, class_=None, template=None,
    allowed_interface=None, allowed_attributes=None):

    # If class is not given we use the basic viewlet manager.
    if class_ is None:
        class_ = manager.ViewletManagerBase

    # Iterate over permissions
    if allowed_attributes is None:
        allowed_attributes = ['render', 'update']
    if allowed_interface is not None:
        for interface in allowed_interface:
            allowed_attributes.extend(interface.names())

    # Make sure that the template exists and that all low-level API methods
    # have the right permission.
    if template:
        template = os.path.abspath(str(_context.path(template)))
        if not os.path.isfile(template):
            raise ConfigurationError("No such file", template)
        allowed_attributes.append('__getitem__')

        # Create a new class based on the template and class.
        new_class = manager.ViewletManager(
            name, provides, template=template, bases=(class_, ))
    else:
        # Create a new class based on the class.
        new_class = manager.ViewletManager(name, provides, bases=(class_, ))

    # Register interfaces
    viewmeta._handle_for(_context, for_)
    metaconfigure.interface(_context, view)

    # register a viewlet manager
    _context.action(
        discriminator = ('viewletManager', for_, layer, view, name),
        callable = metaconfigure.handler,
        args = ('provideAdapter',
                (for_, layer, view), provides, name,
                 new_class, _context.info),)
    _context.action(
        discriminator = ('five:protectClass', new_class),
        callable = protectClass,
        args = (new_class, permission)
        )
    if allowed_attributes:
        for attr in allowed_attributes:
            _context.action(
                discriminator = ('five:protectName', new_class, attr),
                callable = protectName,
                args = (new_class, attr, permission)
                )
    _context.action(
        discriminator = ('five:initialize:class', new_class),
        callable = initializeClass,
        args = (new_class,)
        )
Beispiel #2
0
def viewletManagerDirective(
    _context, name, permission,
    for_=Interface, layer=IDefaultBrowserLayer, view=IBrowserView,
    provides=interfaces.IViewletManager, class_=None, template=None,
    allowed_interface=None, allowed_attributes=None):

    # If class is not given we use the basic viewlet manager.
    if class_ is None:
        class_ = manager.ViewletManagerBase

    # Iterate over permissions
    if allowed_attributes is None:
        allowed_attributes = ['render', 'update']
    if allowed_interface is not None:
        for interface in allowed_interface:
            allowed_attributes.extend(interface.names())

    # Make sure that the template exists and that all low-level API methods
    # have the right permission.
    if template:
        template = os.path.abspath(str(_context.path(template)))
        if not os.path.isfile(template):
            raise ConfigurationError("No such file", template)
        allowed_attributes.append('__getitem__')

        # Create a new class based on the template and class.
        new_class = manager.ViewletManager(
            name, provides, template=template, bases=(class_, ))
    else:
        # Create a new class based on the class.
        new_class = manager.ViewletManager(name, provides, bases=(class_, ))

    # Register interfaces
    viewmeta._handle_for(_context, for_)
    zcml.interface(_context, view)

    # register a viewlet manager
    _context.action(
        discriminator = ('viewletManager', for_, layer, view, name),
        callable = zcml.handler,
        args = ('registerAdapter',
                new_class, (for_, layer, view), provides, name,
                _context.info),)
    _context.action(
        discriminator = ('five:protectClass', new_class),
        callable = protectClass,
        args = (new_class, permission)
        )
    if allowed_attributes:
        for attr in allowed_attributes:
            _context.action(
                discriminator = ('five:protectName', new_class, attr),
                callable = protectName,
                args = (new_class, attr, permission)
                )
    _context.action(
        discriminator = ('five:initialize:class', new_class),
        callable = initializeClass,
        args = (new_class,)
        )
Beispiel #3
0
def view(_context, for_=None, interface=None, methods=None,
         class_=None, permission=None, name=None):

    interface = interface or []
    methods = methods or []

    # If there were special permission settings provided, then use them
    if permission == 'zope.Public':
        permission = CheckerPublic

    require = {}
    for attr_name in methods:
        require[attr_name] = permission

    if interface:
        for iface in interface:
            for field_name in iface:
                require[field_name] = permission
            _context.action(
                discriminator = None,
                callable = provideInterface,
                args = ('', for_))

    cdict = getSecurityInfo(class_)

    if name:
        cdict['__name__'] = name
        new_class = makeClass(class_.__name__,
                              (class_, BrowserView), cdict)

        _handle_for(_context, for_)
        # Register the new view.
        _context.action(
            discriminator = ('view', (for_, ), name, ISOAPRequest),
            callable = handler,
            args = ('registerAdapter',
                    new_class, (for_, ISOAPRequest),
                    Interface, name,
                    _context.info)
            )
        _context.action(
            discriminator = ('five:protectClass', new_class),
            callable = protectClass,
            args = (new_class, permission))

        for name in require:
            _context.action(
                discriminator = ('five:protectName', new_class, name),
                callable = protectName,
                args = (new_class, name, permission))

        #else its private:
        allowed = require
        private_attrs = [name for name in dir(new_class)
                         if (not name.startswith('_')) and
                            (name not in allowed) and
                            ismethod(getattr(new_class, name))]
        for attr in private_attrs:
            _context.action(
                discriminator = ('five:protectName', new_class, attr),
                callable = protectName,
                args = (new_class, attr, CheckerPrivateId))

    else:
        for name in require:
            cdict.update({'__page_attribute__': name,
                          '__name__': name})
            new_class = makeClass(class_.__name__,
                                  (class_, ViewMixinForAttributes),
                                  cdict)

            func = getattr(new_class, name)
            if not func.__doc__:
                # cannot test for MethodType/UnboundMethod here
                # because of ExtensionClass
                if hasattr(func, 'im_func'):
                    # you can only set a docstring on functions, not
                    # on method objects
                    func = func.im_func
                func.__doc__ = "Stub docstring to make ZPublisher work"

            _context.action(
                discriminator = ('view', (for_, ), name, ISOAPRequest),
                callable = handler,
                args = ('registerAdapter',
                        new_class,
                        (for_, ISOAPRequest), Interface, name,
                        _context.info))

            _context.action(
                discriminator = ('five:protectClass', new_class),
                callable = protectClass,
                args = (new_class, permission))

            _context.action(
                discriminator = ('five:protectName', new_class, name),
                callable = protectName,
                args = (new_class, name, permission))

            _context.action(
                discriminator = ('five:initialize:class', new_class),
                callable = initializeClass,
                args = (new_class, )
                )

    # Register the used interfaces with the interface service
    if for_ is not None:
        _context.action(
            discriminator = None,
            callable = provideInterface,
            args = ('', for_))
Beispiel #4
0
def page(_context, name, permission, for_,
         layer=IDefaultBrowserLayer, template=None, class_=None,
         allowed_interface=None, allowed_attributes=None,
         attribute='__call__', menu=None, title=None,
         ):

    _handle_menu(_context, menu, title, [for_], name, permission)

    if not (class_ or template):
        raise ConfigurationError("Must specify a class or template")
    if allowed_attributes is None:
        allowed_attributes = []
    if allowed_interface is not None:
        for interface in allowed_interface:
            allowed_attributes.extend(interface.names())

    if attribute != '__call__':
        if template:
            raise ConfigurationError(
                "Attribute and template cannot be used together.")

        if not class_:
            raise ConfigurationError(
                "A class must be provided if attribute is used")

    if template:
        template = os.path.abspath(str(_context.path(template)))
        if not os.path.isfile(template):
            raise ConfigurationError("No such file", template)

    if class_:
        if attribute != '__call__':
            if not hasattr(class_, attribute):
                raise ConfigurationError(
                    "The provided class doesn't have the specified attribute "
                    )
        cdict = getSecurityInfo(class_)
        cdict['__name__'] = name
        if template:
            new_class = makeClassForTemplate(template, bases=(class_, ),
                                             cdict=cdict, name=name)
        elif attribute != "__call__":
            # we're supposed to make a page for an attribute (read:
            # method) and it's not __call__.  We thus need to create a
            # new class using our mixin for attributes.
            cdict.update({'__page_attribute__': attribute})
            new_class = makeClass(class_.__name__,
                                  (class_, ViewMixinForAttributes),
                                  cdict)

            # in case the attribute does not provide a docstring,
            # ZPublisher refuses to publish it.  So, as a workaround,
            # we provide a stub docstring
            func = getattr(new_class, attribute)
            if not func.__doc__:
                # cannot test for MethodType/UnboundMethod here
                # because of ExtensionClass
                if hasattr(func, 'im_func'):
                    # you can only set a docstring on functions, not
                    # on method objects
                    func = func.im_func
                func.__doc__ = "Stub docstring to make ZPublisher work"
        else:
            # we could use the class verbatim here, but we'll execute
            # some security declarations on it so we really shouldn't
            # modify the original.  So, instead we make a new class
            # with just one base class -- the original
            new_class = makeClass(class_.__name__, 
                                  (class_, BrowserView), cdict)

    else:
        # template
        new_class = makeClassForTemplate(template, name=name)

    _handle_for(_context, for_)

    _context.action(
        discriminator = ('view', for_, name, IBrowserRequest, layer),
        callable = handler,
        args = ('registerAdapter',
                new_class, (for_, layer), Interface, name, _context.info),
        )
    _context.action(
        discriminator = ('five:protectClass', new_class),
        callable = protectClass,
        args = (new_class, permission)
        )
    if allowed_attributes:
        for attr in allowed_attributes:
            _context.action(
                discriminator = ('five:protectName', new_class, attr),
                callable = protectName,
                args = (new_class, attr, permission)
                )
    _context.action(
        discriminator = ('five:initialize:class', new_class),
        callable = initializeClass,
        args = (new_class,)
        )
Beispiel #5
0
    def __call__(self):
        (_context, name, for_, permission, layer, class_,
         allowed_interface, allowed_attributes) = self.args

        required = {}

        cdict = {}
        pages = {}

        for pname, attribute, template in self.pages:
            if template:
                cdict[pname] = ViewPageTemplateFile(template)
                if attribute and attribute != name:
                    cdict[attribute] = cdict[pname]
            else:
                if not hasattr(class_, attribute):
                    raise ConfigurationError("Undefined attribute",
                                             attribute)

            attribute = attribute or pname
            required[pname] = permission

            pages[pname] = attribute

        # This should go away, but noone seems to remember what to do. :-(
        if hasattr(class_, 'publishTraverse'):

            def publishTraverse(self, request, name,
                                pages=pages, getattr=getattr):

                if name in pages:
                    return getattr(self, pages[name])
                view = component.queryMultiAdapter((self, request), name=name,
                                                   default=None)
                if view is not None:
                    return view.__of__(self)

                m = class_.publishTraverse.__get__(self).__of__(self)
                return m(request, name)

        else:
            def publishTraverse(self, request, name,
                                pages=pages, getattr=getattr):

                if name in pages:
                    return getattr(self, pages[name])
                view = component.queryMultiAdapter((self, request), name=name,
                                                   default=None)
                if view is not None:
                    return view.__of__(self)

                raise NotFoundError(self, name, request)

        cdict['publishTraverse'] = publishTraverse

        if not hasattr(class_, 'browserDefault'):
            if self.default or self.pages:
                default = self.default or self.pages[0][0]
                cdict['browserDefault'] = (
                    lambda self, request, default=default:
                    (self, (default, ))
                    )
            elif providesCallable(class_):
                cdict['browserDefault'] = (
                    lambda self, request: (self, ())
                    )

        if class_ is not None:
            bases = (class_, ViewMixinForTemplates)
        else:
            bases = (ViewMixinForTemplates,)

        try:
            cname = str(name)
        except:
            cname = "GeneratedClass"
            
        newclass = makeClass(cname, bases, cdict)
        
        _handle_for(_context, for_)

        if self.provides is not None:
            _context.action(
                discriminator = None,
                callable = provideInterface,
                args = ('', self.provides)
                )

        _context.action(
            discriminator = ('view', for_, name, IBrowserRequest, layer,
                             self.provides),
            callable = handler,
            args = ('registerAdapter',
                    newclass, (for_, layer), self.provides, name,
                    _context.info),
            )
Beispiel #6
0
def controllerDirective(_context,
                        class_,
                        name,
                        permission="zope.Public",
                        for_=zope.interface.Interface,
                        layer=IDefaultBrowserLayer,
                        view=None,
                        **kwargs):

    globalObject = zope.configuration.fields.GlobalObject().bind(_context)
    for key, value in kwargs.items():
        kwargs[key] = globalObject.fromUnicode(value)

    if view is not None:
        viewDirective(_context, view, controller=class_, layer=layer)

    provides = IPagelet
    allowed_interface = None
    allowed_attributes = None

    # Security map dictionary
    required = {}

    # Get the permission; mainly to correctly handle CheckerPublic.
    permission = viewmeta._handle_permission(_context, permission)

    # The class must be specified.
    if not class_:
        raise ConfigurationError("Must specify a class.")

    if not zope.interface.interfaces.IInterface.providedBy(provides):
        raise ConfigurationError("Provides interface provide IInterface.")

    ifaces = list(zope.interface.Declaration(provides).flattened())
    if IPagelet not in ifaces:
        raise ConfigurationError("Provides interface must inherit IPagelet.")

    # Build a new class that we can use different permission settings if we
    # use the class more then once.
    cdict = {}
    cdict['__name__'] = name
    missing = []
    if class_.__required_kwargs__:
        for kwarg in class_.__required_kwargs__:
            if kwarg not in kwargs.keys():
                missing.append(kwarg)
    if missing:
        raise ConfigurationError("Controller requires the following "
                                 "attributes to be set: %s" %
                                 ', '.join(missing))
    cdict.update(kwargs)
    new_class = type(class_.__name__, (class_, BrowserPagelet), cdict)

    # Set up permission mapping for various accessible attributes
    viewmeta._handle_allowed_interface(_context, allowed_interface, permission,
                                       required)
    viewmeta._handle_allowed_attributes(_context, allowed_attributes,
                                        permission, required)
    viewmeta._handle_allowed_attributes(_context, kwargs.keys(), permission,
                                        required)
    viewmeta._handle_allowed_attributes(
        _context,
        ('__call__', 'browserDefault', 'update', 'render', 'publishTraverse'),
        permission, required)

    # Register the interfaces.
    viewmeta._handle_for(_context, for_)

    # provide the custom provides interface if not allready provided
    if not provides.implementedBy(new_class):
        zope.interface.classImplements(new_class, provides)

    # Create the security checker for the new class
    zope.security.checker.defineChecker(
        new_class, zope.security.checker.Checker(required))

    # register pagelet
    _context.action(
        discriminator=('pagelet', for_, layer, name),
        callable=zope.component.zcml.handler,
        args=('registerAdapter', new_class, (for_, layer), provides, name,
              _context.info),
    )
Beispiel #7
0
def page(
    _context,
    name,
    permission,
    for_,
    layer=IDefaultBrowserLayer,
    template=None,
    class_=None,
    allowed_interface=None,
    allowed_attributes=None,
    attribute='__call__',
    menu=None,
    title=None,
):

    _handle_menu(_context, menu, title, [for_], name, permission)

    if not (class_ or template):
        raise ConfigurationError("Must specify a class or template")
    if allowed_attributes is None:
        allowed_attributes = []
    if allowed_interface is not None:
        for interface in allowed_interface:
            allowed_attributes.extend(interface.names())

    if attribute != '__call__':
        if template:
            raise ConfigurationError(
                "Attribute and template cannot be used together.")

        if not class_:
            raise ConfigurationError(
                "A class must be provided if attribute is used")

    if template:
        template = os.path.abspath(str(_context.path(template)))
        if not os.path.isfile(template):
            raise ConfigurationError("No such file", template)

    if class_:
        if attribute != '__call__':
            if not hasattr(class_, attribute):
                raise ConfigurationError(
                    "The provided class doesn't have the specified attribute ")
        cdict = getSecurityInfo(class_)
        cdict['__name__'] = name
        if template:
            new_class = makeClassForTemplate(template,
                                             bases=(class_, ),
                                             cdict=cdict,
                                             name=name)
        elif attribute != "__call__":
            # we're supposed to make a page for an attribute (read:
            # method) and it's not __call__.  We thus need to create a
            # new class using our mixin for attributes.
            cdict.update({'__page_attribute__': attribute})
            new_class = makeClass(class_.__name__,
                                  (class_, ViewMixinForAttributes), cdict)

            # in case the attribute does not provide a docstring,
            # ZPublisher refuses to publish it.  So, as a workaround,
            # we provide a stub docstring
            func = getattr(new_class, attribute)
            if not func.__doc__:
                # cannot test for MethodType/UnboundMethod here
                # because of ExtensionClass
                if hasattr(func, 'im_func'):
                    # you can only set a docstring on functions, not
                    # on method objects
                    func = func.im_func
                func.__doc__ = "Stub docstring to make ZPublisher work"
        else:
            # we could use the class verbatim here, but we'll execute
            # some security declarations on it so we really shouldn't
            # modify the original.  So, instead we make a new class
            # with just one base class -- the original
            new_class = makeClass(class_.__name__, (class_, BrowserView),
                                  cdict)

    else:
        # template
        new_class = makeClassForTemplate(template, name=name)

    _handle_for(_context, for_)

    _context.action(
        discriminator=('view', for_, name, IBrowserRequest, layer),
        callable=handler,
        args=('registerAdapter', new_class, (for_, layer), Interface, name,
              _context.info),
    )
    _context.action(discriminator=('five:protectClass', new_class),
                    callable=protectClass,
                    args=(new_class, permission))
    if allowed_attributes:
        for attr in allowed_attributes:
            _context.action(discriminator=('five:protectName', new_class,
                                           attr),
                            callable=protectName,
                            args=(new_class, attr, permission))
    _context.action(discriminator=('five:initialize:class', new_class),
                    callable=initializeClass,
                    args=(new_class, ))
Beispiel #8
0
    def __call__(self):
        (_context, name, for_, permission, layer, class_, allowed_interface,
         allowed_attributes) = self.args

        required = {}

        cdict = {}
        pages = {}

        for pname, attribute, template in self.pages:
            if template:
                cdict[pname] = ZopeTwoPageTemplateFile(template)
                if attribute and attribute != name:
                    cdict[attribute] = cdict[pname]
            else:
                if not hasattr(class_, attribute):
                    raise ConfigurationError("Undefined attribute", attribute)

            attribute = attribute or pname
            required[pname] = permission

            pages[pname] = attribute

        # This should go away, but noone seems to remember what to do. :-(
        if hasattr(class_, 'publishTraverse'):

            def publishTraverse(self,
                                request,
                                name,
                                pages=pages,
                                getattr=getattr):

                if name in pages:
                    return getattr(self, pages[name])
                view = component.queryMultiAdapter((self, request),
                                                   name=name,
                                                   default=None)
                if view is not None:
                    return view.__of__(self)

                m = class_.publishTraverse.__get__(self).__of__(self)
                return m(request, name)

        else:

            def publishTraverse(self,
                                request,
                                name,
                                pages=pages,
                                getattr=getattr):

                if name in pages:
                    return getattr(self, pages[name])
                view = component.queryMultiAdapter((self, request),
                                                   name=name,
                                                   default=None)
                if view is not None:
                    return view.__of__(self)

                raise NotFoundError(self, name, request)

        cdict['publishTraverse'] = publishTraverse

        if not hasattr(class_, 'browserDefault'):
            if self.default or self.pages:
                default = self.default or self.pages[0][0]
                cdict['browserDefault'] = (
                    lambda self, request, default=default: (self, (default, )))
            elif providesCallable(class_):
                cdict['browserDefault'] = (lambda self, request: (self, ()))

        if class_ is not None:
            bases = (class_, ViewMixinForTemplates)
        else:
            bases = (ViewMixinForTemplates, )

        try:
            cname = str(name)
        except:
            cname = "GeneratedClass"

        newclass = makeClass(cname, bases, cdict)

        _handle_for(_context, for_)

        if self.provides is not None:
            _context.action(discriminator=None,
                            callable=provideInterface,
                            args=('', self.provides))

        _context.action(
            discriminator=('view', for_, name, IBrowserRequest, layer,
                           self.provides),
            callable=handler,
            args=('registerAdapter', newclass, (for_, layer), self.provides,
                  name, _context.info),
        )
Beispiel #9
0
def viewletDirective(
    _context, name, permission,
    for_=Interface, layer=IDefaultBrowserLayer, view=IBrowserView,
    manager=interfaces.IViewletManager, class_=None, template=None,
    attribute='render', allowed_interface=None, allowed_attributes=None,
    **kwargs):

    # Security map dictionary
    required = {}

    # Get the permission; mainly to correctly handle CheckerPublic.
    permission = viewmeta._handle_permission(_context, permission)

    # Either the class or template must be specified.
    if not (class_ or template):
        raise ConfigurationError("Must specify a class or template")

    # Make sure that all the non-default attribute specifications are correct.
    if attribute != 'render':
        if template:
            raise ConfigurationError(
                "Attribute and template cannot be used together.")

        # Note: The previous logic forbids this condition to evere occur.
        if not class_:
            raise ConfigurationError(
                "A class must be provided if attribute is used")

    # Make sure that the template exists and that all low-level API methods
    # have the right permission.
    if template:
        template = os.path.abspath(str(_context.path(template)))
        if not os.path.isfile(template):
            raise ConfigurationError("No such file", template)
        required['__getitem__'] = permission

    # Make sure the has the right form, if specified.
    if class_:
        if attribute != 'render':
            if not hasattr(class_, attribute):
                raise ConfigurationError(
                    "The provided class doesn't have the specified attribute "
                    )
        if template:
            # Create a new class for the viewlet template and class.
            new_class = viewlet.SimpleViewletClass(
                template, bases=(class_, ), attributes=kwargs)
        else:
            if not hasattr(class_, 'browserDefault'):
                cdict = {'browserDefault':
                         lambda self, request: (getattr(self, attribute), ())}
            else:
                cdict = {}

            cdict['__name__'] = name
            cdict['__page_attribute__'] = attribute
            cdict.update(kwargs)
            new_class = type(class_.__name__,
                             (class_, viewlet.SimpleAttributeViewlet), cdict)

        if hasattr(class_, '__implements__'):
            classImplements(new_class, IBrowserPublisher)

    else:
        # Create a new class for the viewlet template alone.
        new_class = viewlet.SimpleViewletClass(template, name=name,
                                               attributes=kwargs)

    # Set up permission mapping for various accessible attributes
    viewmeta._handle_allowed_interface(
        _context, allowed_interface, permission, required)
    viewmeta._handle_allowed_attributes(
        _context, allowed_attributes, permission, required)
    viewmeta._handle_allowed_attributes(
        _context, kwargs.keys(), permission, required)
    viewmeta._handle_allowed_attributes(
        _context,
        (attribute, 'browserDefault', 'update', 'render', 'publishTraverse'),
        permission, required)

    # Register the interfaces.
    viewmeta._handle_for(_context, for_)
    metaconfigure.interface(_context, view)

    # Create the security checker for the new class
    checker.defineChecker(new_class, checker.Checker(required))

    # register viewlet
    _context.action(
        discriminator = ('viewlet', for_, layer, view, manager, name),
        callable = metaconfigure.handler,
        args = ('provideAdapter',
                (for_, layer, view, manager), interfaces.IViewlet,
                 name, new_class, _context.info),)
Beispiel #10
0
def viewletManagerDirective(
    _context, name, permission,
    for_=Interface, layer=IDefaultBrowserLayer, view=IBrowserView,
    provides=interfaces.IViewletManager, class_=None, template=None,
    allowed_interface=None, allowed_attributes=None):

    # A list of attributes available under the provided permission
    required = {}

    # Get the permission; mainly to correctly handle CheckerPublic.
    permission = viewmeta._handle_permission(_context, permission)

    # If class is not given we use the basic viewlet manager.
    if class_ is None:
        class_ = manager.ViewletManagerBase

    # Make sure that the template exists and that all low-level API methods
    # have the right permission.
    if template:
        template = os.path.abspath(str(_context.path(template)))
        if not os.path.isfile(template):
            raise ConfigurationError("No such file", template)
        required['__getitem__'] = permission

        # Create a new class based on the template and class.
        new_class = manager.ViewletManager(
            provides, template=template, bases=(class_, ))
    else:
        # Create a new class based on the class.
        new_class = manager.ViewletManager(provides, bases=(class_, ))

    # Register some generic attributes with the security dictionary
    for attr_name in ('browserDefault', 'update', 'render', 'publishTraverse'):
        required[attr_name] = permission

    # Register the ``provides`` interface and register fields in the security
    # dictionary
    viewmeta._handle_allowed_interface(
        _context, (provides,), permission, required)

    # Register the allowed interface and add the field's security entries
    viewmeta._handle_allowed_interface(
        _context, allowed_interface, permission, required)

    # Register single allowed attributes in the security dictionary
    viewmeta._handle_allowed_attributes(
        _context, allowed_attributes, permission, required)

    # Register interfaces
    viewmeta._handle_for(_context, for_)
    metaconfigure.interface(_context, view)

    # Create a checker for the viewlet manager
    checker.defineChecker(new_class, checker.Checker(required))

    # register a viewlet manager
    _context.action(
        discriminator = ('viewletManager', for_, layer, view, name),
        callable = metaconfigure.handler,
        args = ('provideAdapter',
                (for_, layer, view), provides, name,
                 new_class, _context.info),)
Beispiel #11
0
def viewletDirective(
    _context, name, permission,
    for_=Interface, layer=IDefaultBrowserLayer, view=IBrowserView,
    manager=interfaces.IViewletManager, class_=None, template=None,
    attribute='render', allowed_interface=None, allowed_attributes=None,
    **kwargs):

    # Either the class or template must be specified.
    if not (class_ or template):
        raise ConfigurationError("Must specify a class or template")

    # Make sure that all the non-default attribute specifications are correct.
    if attribute != 'render':
        if template:
            raise ConfigurationError(
                "Attribute and template cannot be used together.")

        # Note: The previous logic forbids this condition to evere occur.
        if not class_:
            raise ConfigurationError(
                "A class must be provided if attribute is used")

    # Iterate over permissions
    if allowed_attributes is None:
        allowed_attributes = ['render', 'update']
    if allowed_interface is not None:
        for interface in allowed_interface:
            allowed_attributes.extend(interface.names())

    # Make sure that the template exists and that all low-level API methods
    # have the right permission.
    if template:
        template = os.path.abspath(str(_context.path(template)))
        if not os.path.isfile(template):
            raise ConfigurationError("No such file", template)
        allowed_attributes.append('__getitem__')

    # Make sure the has the right form, if specified.
    if class_:
        if attribute != 'render':
            if not hasattr(class_, attribute):
                raise ConfigurationError(
                    "The provided class doesn't have the specified attribute "
                    )
        if template:
            # Create a new class for the viewlet template and class.
            new_class = viewlet.SimpleViewletClass(
                template, bases=(class_, ), attributes=kwargs)
        else:
            if not hasattr(class_, 'browserDefault'):
                cdict = {'browserDefault':
                         lambda self, request: (getattr(self, attribute), ())}
            else:
                cdict = {}

            cdict['__name__'] = name
            cdict['__page_attribute__'] = attribute
            cdict.update(kwargs)
            new_class = type(class_.__name__,
                             (class_, viewlet.SimpleAttributeViewlet), cdict)

        if hasattr(class_, '__implements__'):
            classImplements(new_class, IBrowserPublisher)

    else:
        # Create a new class for the viewlet template alone.
        new_class = viewlet.SimpleViewletClass(template, name=name,
                                               attributes=kwargs)

    # Register the interfaces.
    viewmeta._handle_for(_context, for_)
    metaconfigure.interface(_context, view)

    # register viewlet
    _context.action(
        discriminator = ('viewlet', for_, layer, view, manager, name),
        callable = metaconfigure.handler,
        args = ('provideAdapter',
                (for_, layer, view, manager), interfaces.IViewlet,
                 name, new_class, _context.info),)

    _context.action(
        discriminator = ('five:protectClass', new_class),
        callable = protectClass,
        args = (new_class, permission)
        )
    if allowed_attributes:
        for attr in allowed_attributes:
            _context.action(
                discriminator = ('five:protectName', new_class, attr),
                callable = protectName,
                args = (new_class, attr, permission)
                )
    _context.action(
        discriminator = ('five:initialize:class', new_class),
        callable = initializeClass,
        args = (new_class,)
        )
Beispiel #12
0
def viewletDirective(_context,
                     name,
                     permission,
                     for_=Interface,
                     layer=IDefaultBrowserLayer,
                     view=IBrowserView,
                     manager=interfaces.IViewletManager,
                     class_=None,
                     template=None,
                     attribute='render',
                     allowed_interface=None,
                     allowed_attributes=None,
                     **kwargs):

    # Either the class or template must be specified.
    if not (class_ or template):
        raise ConfigurationError("Must specify a class or template")

    # Make sure that all the non-default attribute specifications are correct.
    if attribute != 'render':
        if template:
            raise ConfigurationError(
                "Attribute and template cannot be used together.")

        # Note: The previous logic forbids this condition to evere occur.
        if not class_:
            raise ConfigurationError(
                "A class must be provided if attribute is used")

    # Iterate over permissions
    if allowed_attributes is None:
        allowed_attributes = ['render', 'update']
    if allowed_interface is not None:
        for interface in allowed_interface:
            allowed_attributes.extend(interface.names())

    # Make sure that the template exists and that all low-level API methods
    # have the right permission.
    if template:
        template = os.path.abspath(str(_context.path(template)))
        if not os.path.isfile(template):
            raise ConfigurationError("No such file", template)
        allowed_attributes.append('__getitem__')

    # Make sure the has the right form, if specified.
    if class_:
        if attribute != 'render':
            if not hasattr(class_, attribute):
                raise ConfigurationError(
                    "The provided class doesn't have the specified attribute ")
        if template:
            # Create a new class for the viewlet template and class.
            new_class = viewlet.SimpleViewletClass(template,
                                                   bases=(class_, ),
                                                   attributes=kwargs)
        else:
            if not hasattr(class_, 'browserDefault'):
                cdict = {
                    'browserDefault':
                    lambda self, request: (getattr(self, attribute), ())
                }
            else:
                cdict = {}

            cdict['__name__'] = name
            cdict['__page_attribute__'] = attribute
            cdict.update(kwargs)
            new_class = type(class_.__name__,
                             (class_, viewlet.SimpleAttributeViewlet), cdict)

        if hasattr(class_, '__implements__'):
            classImplements(new_class, IBrowserPublisher)

    else:
        # Create a new class for the viewlet template alone.
        new_class = viewlet.SimpleViewletClass(template,
                                               name=name,
                                               attributes=kwargs)

    # Register the interfaces.
    viewmeta._handle_for(_context, for_)
    metaconfigure.interface(_context, view)

    # register viewlet
    _context.action(
        discriminator=('viewlet', for_, layer, view, manager, name),
        callable=metaconfigure.handler,
        args=('provideAdapter', (for_, layer, view, manager),
              interfaces.IViewlet, name, new_class, _context.info),
    )

    _context.action(discriminator=('five:protectClass', new_class),
                    callable=protectClass,
                    args=(new_class, permission))
    if allowed_attributes:
        for attr in allowed_attributes:
            _context.action(discriminator=('five:protectName', new_class,
                                           attr),
                            callable=protectName,
                            args=(new_class, attr, permission))
    _context.action(discriminator=('five:initialize:class', new_class),
                    callable=initializeClass,
                    args=(new_class, ))