Esempio n. 1
0
def portletManagerDirective(
    _context, name, title, for_=None, description=u'',
    class_=None, schema=None, layer=IDefaultBrowserLayer,
    provides=(), portlettype=IPortlet, **kw):

    # Build a new class
    ManagerClass = PortletManager(
        name, class_, provides, title, description, schema, portlettype, **kw)

    # Set up permission mapping for various accessible attributes
    required = {'__call__': CheckerPublic,
                'browserDefault': CheckerPublic,
                'publishTraverse': CheckerPublic}

    for iname in IPortletManager:
        required[iname] = CheckerPublic

    # security checker
    defineChecker(ManagerClass, Checker(required))

    # security for schema fields
    for iface in (IPortletManagerConfiguration, schema):
        if iface is None:
            continue
        for f_id in iface:
            field = iface[f_id]
            if IField.providedBy(field) and not field.readonly:
                protectSetAttribute(ManagerClass, f_id, 'zojax.ManagePortlets')
            protectName(ManagerClass, f_id, 'zope.Public')

    # register the portlet manager
    adapter(_context, (ManagerClass,),
            IPortletManager, (for_, layer, None), name=name)
Esempio n. 2
0
def ApplySecurity( ctx ):
    # setup security
    #
    for c in ctx.domain_model.__bases__:
        if c is object:
            continue
        protectLikeUnto( ctx.domain_model, c )

    attributes = set([n for n,d in \
                      ctx.domain_interface.namesAndDescriptions(1)])
    attributes = attributes.union(
        set( [ f.get('name') for f in ctx.descriptor.fields] )
        )

    descriptor = ctx.descriptor
    for n in attributes:
        model_field = descriptor.get(n)
        p = model_field and model_field.view_permission or 'zope.Public'
        protectName( ctx.domain_model, n, p )
    
    for n in attributes:
        model_field = descriptor.get(n)
        p = model_field and model_field.edit_permission or 'zope.Public' # 'zope.ManageContent'
        protectSetAttribute( ctx.domain_model, n, p)
        
    for k, v in ctx.domain_model.__dict__.items():
        if isinstance( v, ManagedContainerDescriptor ):
            protectName( ctx.domain_model, k, "zope.Public" )
Esempio n. 3
0
def generate_container_class(ti):
    """Generate a zope3 container class for a domain model.
    """
    type_key = naming.polymorphic_identity(ti.domain_model)
    container_name = naming.container_class_name(type_key)
    container_iname = naming.container_interface_name(type_key)
    base_interfaces = (IAlchemistContainer,
                       )  # !+achetype.container_interface?

    # logging variables
    msg = (ti.domain_model.__name__, CONTAINER_MODULE.__name__, container_name)

    # container class - if we already have one, exit
    if getattr(CONTAINER_MODULE, container_name, None):
        log.info(
            "generate_container_class [model=%s] found container %s.%s, skipping",
            *msg)
        ti.container_class = getattr(CONTAINER_MODULE, container_name)
        return

    container_class = type(
        container_name, (AlchemistContainer, ),
        dict(_class=ti.domain_model, __module__=CONTAINER_MODULE.__name__))
    # set on CONTAINER_MODULE, register on type_info
    setattr(CONTAINER_MODULE, container_name, container_class)
    ti.container_class = container_class
    log.info("generate_container_class [model=%s] generated container %s.%s",
             *msg)

    # container interface - if we already have one, skip creation
    # !+ should always be newly created?
    container_iface = getattr(INTERFACE_MODULE, container_iname, None)
    msg = (ti.domain_model.__name__, CONTAINER_MODULE.__name__,
           container_iname)
    if container_iface is not None:
        assert issubclass(container_iface, IAlchemistContainer)
        log.info(
            "generate_container_class [model=%s] skipping container interface %s.%s for",
            *msg)
    else:
        container_iface = interface.interface.InterfaceClass(
            container_iname,
            bases=base_interfaces,
            __module__=INTERFACE_MODULE.__name__)
        # set on INTERFACE_MODULE, register on type_info
        setattr(INTERFACE_MODULE, container_iname, container_iface)
        ti.container_interface = container_iface
        log.info(
            "generate_container_class [model=%s] generated container interface %s.%s",
            *msg)

    # setup security
    for n, d in container_iface.namesAndDescriptions(all=True):
        protectName(container_class, n, "zope.Public")
    # apply implementedBy
    if not container_iface.implementedBy(container_class):
        interface.classImplements(container_class, container_iface)
Esempio n. 4
0
def generate_container_class(ti):
    """Generate a zope3 container class for a domain model.
    """
    type_key = naming.polymorphic_identity(ti.domain_model)
    container_name = naming.container_class_name(type_key)
    container_iname = naming.container_interface_name(type_key)
    base_interfaces = (IAlchemistContainer,)
    
    # logging variables
    msg = (ti.domain_model.__name__, CONTAINER_MODULE.__name__, container_name)
    
    # container class - if we already have one, exit                
    if getattr(CONTAINER_MODULE, container_name, None):
        log.info("generate_container_class [model=%s] found container %s.%s, skipping" % msg)
        ti.container_class = getattr(CONTAINER_MODULE, container_name)
        return
    
    container_class = type(container_name,
        (AlchemistContainer,),
        dict(_class=ti.domain_model, 
            __module__=CONTAINER_MODULE.__name__)
    )
    # set on CONTAINER_MODULE, register on type_info
    setattr(CONTAINER_MODULE, container_name, container_class)
    ti.container_class = container_class
    log.info("generate_container_class [model=%s] generated container %s.%s" % msg)
    
    # container interface - if we already have one, skip creation 
    # !+ should always be newly created?
    container_iface = getattr(INTERFACE_MODULE, container_iname, None)
    msg = (ti.domain_model.__name__, CONTAINER_MODULE.__name__, container_iname)
    if container_iface is not None:
        assert issubclass(container_iface, IAlchemistContainer)
        log.info("generate_container_class [model=%s] skipping container interface %s.%s for" % msg)
    else:
        container_iface = interface.interface.InterfaceClass(
            container_iname,
            bases=base_interfaces,
            __module__=INTERFACE_MODULE.__name__
        )
        # set on INTERFACE_MODULE, register on type_info
        setattr(INTERFACE_MODULE, container_iname, container_iface)
        ti.container_interface = container_iface
        log.info("generate_container_class [model=%s] generated container interface %s.%s" % msg)
    
    # setup security
    for n, d in container_iface.namesAndDescriptions(all=True):
        protectName(container_class, n, "zope.Public")
    # apply implementedBy
    if not container_iface.implementedBy(container_class):
        interface.classImplements(container_class, container_iface)
Esempio n. 5
0
def portletDirective(
    _context, name, title, for_=None, template=u'',
    description=u'', class_=None, provides=IPortlet,
    schema=None, type=IPortlet, manager=None, **kw):

    # Make sure that the template exists
    if template:
        template = os.path.abspath(str(_context.path(template)))
        if not os.path.isfile(template):
            raise ConfigurationError("No such file", template)

    # Build a new class.
    PortletClass = Portlet(
        name, class_, title, description, template, schema, **kw)

    if provides is not IPortlet:
        interface.classImplements(PortletClass, provides)

    # Set up permission mapping for various accessible attributes
    required = {'__call__': CheckerPublic,
                'browserDefault': CheckerPublic,
                'publishTraverse': CheckerPublic}

    for iface in (IPortlet, provides):
        for iname in iface:
            required[iname] = CheckerPublic

    # security checker
    defineChecker(PortletClass, Checker(required))

    # portlet schema
    if schema is not None:
        # security for configuration
        for f_id in schema:
            field = schema[f_id]
            if IField.providedBy(field) and not field.readonly:
                protectSetAttribute(PortletClass, f_id, 'zojax.ManagePortlets')
            protectName(PortletClass, f_id, CheckerPublic)

    # register the portlet
    adapter(_context, (PortletClass,), type,
            (for_, None, manager, None), name=name)
Esempio n. 6
0
def viewModelDirective(
    _context, name, title, for_=interface.Interface, description=u'',
    class_=None, schema=None, layer=IDefaultBrowserLayer, provides=(), **kw):

    # Build a new class
    ViewModelClass = ViewModelType(
        name, class_, provides, title, description, schema, **kw)

    # Set up permission mapping for various accessible attributes
    required = {'__call__': CheckerPublic,
                'context': CheckerPublic,
                'request': CheckerPublic}

    for iname in IViewModel:
        required[iname] = CheckerPublic

    # security checker
    defineChecker(ViewModelClass, Checker(required))

    ifaces = list(provides)
    if schema is not None:
        ifaces.append(schema)

    # security for schema fields
    for iface in ifaces:
        for f_id in iface:
            field = iface[f_id]
            if IField.providedBy(field) and not field.readonly:
                protectSetAttribute(ViewModelClass, f_id, 'zojax.ManageViewModels')
            protectName(ViewModelClass, f_id, 'zope.Public')

    # register pagelet manager
    _context.action(
        discriminator = ('zojax:contentextensions.dynamic', name),
        callable = handler,
        args = ('registerAdapter',
                ViewModelClass, (for_, layer),
                IViewModel, name, _context.info))
Esempio n. 7
0
    def __new__(cls, name, klass, schema, fields, module):
        cname = 'ContentRevision<%s>'%name

        # generate bases
        if klass is None:
            klass = ContentRevision

        if issubclass(klass, ContentRevision):
            bases = (klass,)
        else:
            bases = (klass, ContentRevision)

        # generate fields
        attrs = {'__module__': module}
        for f_id in getFields(schema):
            if f_id in fields:
                attrs[f_id] = fields[f_id]
            else:
                attrs[f_id] = FieldProperty(schema[f_id])

        # create type
        tp = type.__new__(cls, cname, bases, attrs)

        # set schema and implements
        tp.__schema__ = SchemaProperty(schema)

        component.getSiteManager().registerAdapter(
            getContentRevision, (tp,), schema)

        # set class to module
        setattr(sys.modules[module], cname, tp)

        # create security checker
        for n, d in schema.namesAndDescriptions(1):
            protectName(tp, n, 'zope.View')

        for n, d in IContentRevision.namesAndDescriptions(1):
            protectName(tp, n, 'zope.View')

        protectName(tp, '__schema__', 'zope.Public')

        for name, field in getFields(schema).items() + \
                getFields(IContentRevision).items():
            if not field.readonly:
                protectSetAttribute(tp, name, 'zojax.ModifyContent')

        return tp
Esempio n. 8
0
    def testInherited(self):

        class B1(object):
            def g(self): return 'B1.g'

        class B2(object):
            def h(self): return 'B2.h'

        class S(B1, B2):
            pass

        ztapi.provideUtility(IPermission, Permission('B1', ''), 'B1')
        ztapi.provideUtility(IPermission, Permission('S', ''), 'S')
        protectName(B1, 'g', 'B1')
        protectName(S, 'g', 'S')
        protectName(S, 'h', 'S')

        self.assertEqual(selectChecker(B1()).permission_id('g'), 'B1')
        self.assertEqual(selectChecker(B2()).permission_id('h'), None)
        self.assertEqual(selectChecker(S()).permission_id('g'), 'S')
        self.assertEqual(selectChecker(S()).permission_id('h'), 'S')

        self.assertEqual(S().g(), 'B1.g')
        self.assertEqual(S().h(), 'B2.h')
Esempio n. 9
0
def apply_security(ti):
    domain_model, descriptor_model = ti.domain_model, ti.descriptor_model
    type_key = naming.polymorphic_identity(domain_model)
    log.debug("APPLY SECURITY: %s %s", type_key, domain_model)
    # first, "inherit" security settings of super classes i.e. equivalent of 
    # something like <require like_class=".domain.Doc" />
    for c in domain_model.__bases__:
        if c is object:
            continue
        log.debug("    LIKE_CLASS: %s", c)
        protectLikeUnto(domain_model, c)
    
    # !+DECL permissions here--for CUSTOM types only, and SINCE r9946--override
    # what is defined in domain.zcml, as opposed to vice-versa (probably 
    # because CUSTOM types are setup at a later stage). 
    # So (for CUSTOM types only?) we use the parametrized 
    # bungeni.{type_key}.{Mode} as the view/edit permission:
    pv_type = "zope.Public" # view permission, for type
    pe_type = "zope.Public" # edit permission, for type
    if descriptor_model.scope == "custom":
        pv_type = "bungeni.%s.View" % (type_key)
        pe_type = "bungeni.%s.Edit" % (type_key)
    
    # !+SCHEMA_FIELDS(mr, oct-2012) all this seems superfluous anyway, as is 
    # (always?) overwritten further down? Switch to base loop on superset of 
    # names (dir(cls)?) and then decide ONCE on various criteria how to
    # protect the name.
    _view_protected = set() # remember names protected for view
    _edit_protected = set() # remember names protected for edit
    
    # sorted (for clearer logging) list of attr names that are BOTH defined
    # by the db mapped-table schema AND have a dedicated UI Field.
    dts_attrs = [ n for n in ti.derived_table_schema.names(all=True) ]
    df_attrs = [ f.get("name") for f in descriptor_model.fields ]
    attrs = sorted(set(dts_attrs).union(set(df_attrs)))
    
    log.debug("    DTS+Fields: %s, %s", 
        ti.derived_table_schema.__name__, descriptor_model.__name__)
    for n in attrs:
        # !+DECL special cases, do not override domain.zcml...
        if n in ("response_text",):
            continue
        _view_protected.add(n); _edit_protected.add(n)
        pv = pv_type
        pe = pe_type
        model_field = descriptor_model.get(n)
        if model_field:
            if descriptor_model.scope != "custom":
                # !+DECL proceed as before for now
                pv = model_field.view_permission # always "zope.Public"
                pe = model_field.edit_permission # always "zope.ManageContent"
        # !+DECL parametrize all permissions by type AND mode, ensure to grant
        # to appropriate roles. What about non-workflows or non-catalyzed types?
        protectName(domain_model, n, pv)
        protectSetAttribute(domain_model, n, pe)
        DTS = n in dts_attrs and "dts" or "   "
        DF = n in df_attrs and "df" or "  "
        log.debug("         %s %s [%s]  view:%s  edit:%s  %x",
                DTS, DF, n, pv, pe, id(model_field))
        if n not in domain_model.__dict__:
            log.debug("           ---- [%s] !+SCHEMA_FIELDS not in %s.__dict__",
                    n, domain_model)
    
    # container attributes (never a UI Field for these)
    log.debug("      __dict__: %s" % (domain_model))
    for k in sorted(domain_model.__dict__.keys()):
        # !+ if IManagedContainer.providedBy(v): ?
        v = domain_model.__dict__[k]
        if isinstance(v, ManagedContainerDescriptor):
            if k in _view_protected:
                log.debug("           ---- %s RESETTING...", k)
            _view_protected.add(k)
            log.debug("        managed %s view:%s" % (k, "zope.Public"))
        elif isinstance(v, orm.attributes.InstrumentedAttribute):     
            if k in _view_protected:
                log.debug("           ---- %s RESETTING...", k)
            _view_protected.add(k)
            log.debug("   instrumented [%s]  view:%s", k, "zope.Public")
        else:
            log.debug("           ---- [%s] !+SCHEMA_FIELD IN __dict__ but NOT "
                "instrumented OR managed", k)
            continue
        if k not in attrs:
            log.debug("           ---- [%s] !+SCHEMA_FIELDS not in attrs", k)
        protectName(domain_model, k, "zope.Public") #!+pv_type
    
    # Dump permission_id required to getattr/setattr for "custom" types.
    # We only dump the security settings for "custom" types as it only these 
    # are processed AFTER that domain.zcml has been executed (for other types,
    # loaded earlier during app startup, it is the settings in domain.zcml 
    # (executed later during app startup) that ends up applying.
    if descriptor_model.scope == "custom":
        from zope.security import proxy, checker
        dmc = checker.getChecker(proxy.ProxyFactory(domain_model()))
        log.debug("       checker: %s", dmc)
        for n in sorted(_view_protected.union(["response_text"])):
            g = dmc.get_permissions.get(n)
            s = dmc.set_permissions.get(n) #dmc.setattr_permission_id(n)
            log.debug("                [%s]  get:%s  set:%s",
                    n, getattr(g, "__name__", g), s)
Esempio n. 10
0
def defineCheckers():
    # define the appropriate checker for a FileResource for these tests
    from zope.app.security.protectclass import protectName
    from zope.app.publisher.browser.fileresource import FileResource
    protectName(FileResource, '__call__', 'zope.Public')
Esempio n. 11
0
def apply_security(ti):
    domain_model, descriptor_model = ti.domain_model, ti.descriptor_model
    type_key = naming.polymorphic_identity(domain_model)
    log.debug("APPLY SECURITY: %s %s", type_key, domain_model)
    # first, "inherit" security settings of super classes i.e. equivalent of 
    # something like <require like_class=".domain.Doc" />
    for c in domain_model.__bases__:
        if c is object:
            continue
        log.debug("    LIKE_CLASS: %s", c)
        protectLikeUnto(domain_model, c)
    
    # !+DECL permissions here--for CUSTOM types only, and SINCE r9946--override
    # what is defined in domain.zcml, as opposed to vice-versa (probably 
    # because CUSTOM types are setup at a later stage). 
    # So (for CUSTOM types only?) we use the parametrized 
    # bungeni.{type_key}.{Mode} as the view/edit permission:
    pv_type = "zope.Public" # view permission, for type
    pe_type = "zope.Public" # edit permission, for type
    if descriptor_model.scope == "custom":
        pv_type = "bungeni.%s.View" % (type_key)
        pe_type = "bungeni.%s.Edit" % (type_key)
    
    # !+SCHEMA_FIELDS(mr, oct-2012) all this seems superfluous anyway, as is 
    # (always?) overwritten further down? Switch to base loop on superset of 
    # names (dir(cls)?) and then decide ONCE on various criteria how to
    # protect the name.
    _view_protected = set() # remember names protected for view
    _edit_protected = set() # remember names protected for edit
    
    # sorted (for clearer logging) list of attr names that are BOTH defined
    # by the db mapped-table schema AND have a dedicated UI Field.
    dts_attrs = [ n for n in ti.derived_table_schema.names(all=True) ]
    df_attrs = [ f.get("name") for f in descriptor_model.fields ]
    attrs = sorted(set(dts_attrs).union(set(df_attrs)))
    
    log.debug("    DTS+Fields: %s, %s", 
        ti.derived_table_schema.__name__, descriptor_model.__name__)
    for n in attrs:
        # !+DECL special cases, do not override domain.zcml...
        if n in ("response_text",):
            continue
        _view_protected.add(n); _edit_protected.add(n)
        pv = pv_type
        pe = pe_type
        model_field = descriptor_model.get(n)
        if model_field:
            if descriptor_model.scope != "custom":
                # !+DECL proceed as before for now
                pv = model_field.view_permission # always "zope.Public"
                pe = model_field.edit_permission # always "zope.ManageContent"
        # !+DECL parametrize all permissions by type AND mode, ensure to grant
        # to appropriate roles. What about non-workflows or non-catalyzed types?
        protectName(domain_model, n, pv)
        protectSetAttribute(domain_model, n, pe)
        DTS = n in dts_attrs and "dts" or "   "
        DF = n in df_attrs and "df" or "  "
        log.debug("         %s %s [%s]  view:%s  edit:%s  %x",
                DTS, DF, n, pv, pe, id(model_field))
        if n not in domain_model.__dict__:
            log.debug("           ---- [%s] !+SCHEMA_FIELDS not in %s.__dict__",
                    n, domain_model)
    
    # container attributes (never a UI Field for these)
    log.debug("      __dict__: %s" % (domain_model))
    for k in sorted(domain_model.__dict__.keys()):
        # !+ if IManagedContainer.providedBy(v): ?
        v = domain_model.__dict__[k]
        if isinstance(v, ManagedContainerDescriptor):
            if k in _view_protected:
                log.debug("           ---- %s RESETTING...", k)
            _view_protected.add(k)
            log.debug("        managed %s view:%s" % (k, "zope.Public"))
        elif isinstance(v, orm.attributes.InstrumentedAttribute):     
            if k in _view_protected:
                log.debug("           ---- %s RESETTING...", k)
            _view_protected.add(k)
            log.debug("   instrumented [%s]  view:%s", k, "zope.Public")
        else:
            log.debug("           ---- [%s] !+SCHEMA_FIELD IN __dict__ but NOT "
                "instrumented OR managed", k)
            continue
        if k not in attrs:
            log.debug("           ---- [%s] !+SCHEMA_FIELDS not in attrs", k)
        protectName(domain_model, k, "zope.Public") #!+pv_type
    
    # Dump permission_id required to getattr/setattr for "custom" types.
    # We only dump the security settings for "custom" types as it only these 
    # are processed AFTER that domain.zcml has been executed (for other types,
    # loaded earlier during app startup, it is the settings in domain.zcml 
    # (executed later during app startup) that ends up applying.
    if descriptor_model.scope == "custom":
        from zope.security import proxy, checker
        dmc = checker.getChecker(proxy.ProxyFactory(domain_model()))
        log.debug("       checker: %s", dmc)
        for n in sorted(_view_protected.union(["response_text"])):
            g = dmc.get_permissions.get(n)
            s = dmc.set_permissions.get(n) #dmc.setattr_permission_id(n)
            log.debug("                [%s]  get:%s  set:%s",
                    n, getattr(g, "__name__", g), s)
Esempio n. 12
0
def defineCheckers():
    # define the appropriate checker for a FileResource for these tests
    from zope.app.security.protectclass import protectName
    from zope.app.publisher.browser.fileresource import FileResource
    protectName(FileResource, '__call__', 'zope.Public')
Esempio n. 13
0
def GenerateContainer( ctx,
                       container_name=None,
                       container_iname=None,
                       base_interfaces=() ):
        """
        generate a zope3 container class for a domain model
        """

        # create container
        container_name = container_name or \
                         ctx.domain_model.__name__ + 'Container'
        
        # allow passing in dotted python path
        if isinstance( ctx.container_module, (str, unicode) ):
            ctx.container_module = resolve( ctx.container_module )
        
        # if not present use the domain class's module
        elif ctx.container_module is None:
            ctx.container_module = resolve( ctx.domain_model.__module__ )
        
        # sanity check we have a module for the container
        assert isinstance(ctx.container_module, types.ModuleType ), "Invalid Container"
        
        # logging variables
        msg = ( ctx.domain_model.__name__, 
                ctx.container_module.__name__, 
                container_name )
                
        
        # if we already have a container class, exit                
        if getattr( ctx.container_module, container_name, None ):
            if ctx.echo:
                ctx.logger.debug("%s: found container %s.%s, skipping"%msg )
            ctx.container_class = getattr( ctx.container_module, container_name )
            return
            
        if ctx.echo:
            ctx.logger.debug("%s: generated container %s.%s"%msg )
        
        # if we already have a container class, exit        
        container_class = type( container_name,
                                (AlchemistContainer,),
                                dict(_class=ctx.domain_model,
                                     __module__=ctx.container_module.__name__ )
                                )
        
        setattr( ctx.container_module, container_name, container_class)
        
        # save container class on catalyst context
        ctx.container_class = container_class
        
        # interface for container
        container_iname = container_iname or "I%s"%container_name
        
        # if the interface module is none, then use the nearest one to the domain class
        if ctx.interface_module is None:
            ispec = ctx.domain_model.__module__.rsplit('.',1)[0]+'.interfaces'
            ctx.interface_module = resolve( ispec )
        
        msg = ( ctx.domain_model.__name__,
                ctx.container_module.__name__,
                container_iname )
        
        # if we already have a container interface class, skip creation
        container_interface = getattr( ctx.interface_module, container_iname, None )
        if container_interface is not None:
            assert issubclass( container_interface, IAlchemistContainer )
            if ctx.echo:
                ctx.logger.debug("%s: skipping container interface %s.%s for"%msg )
        else:
            if ctx.echo:
                ctx.logger.debug("%s: generated container interface %s.%s"%msg )            
            # ensure that our base interfaces include alchemist container 
            if base_interfaces:
                assert isinstance( base_interfaces, tuple )
                found = False
                for bi in base_interfaces:
                    found = issubclass( bi, IAlchemistContainer )
                    if found: break
                if not found:
                    base_interfaces = base_interfaces + ( IAlchemistContainer,)
            else:
                base_interfaces = ( IAlchemistContainer, )

            # create interface
            container_interface = InterfaceClass( container_iname,
                                                  bases = base_interfaces,
                                                  __module__ = ctx.interface_module.__name__
                                                  )
            # store container interface for catalyst
            ctx.container_interface = container_interface

            setattr( ctx.interface_module, container_iname, container_interface )

        # setup security
        for n,d in container_interface.namesAndDescriptions(1):
            protectName( container_class, n, "zope.Public")

        if not container_interface.implementedBy(container_class):
            interface.classImplements(container_class, container_interface)
            
        ctx.container_interface = container_interface