def serviceDirective( _context, method, accept, factory, for_, permission, layer=IDefaultBrowserLayer, name=u"", ): _handle_for(_context, for_) media_types = parse_accept_header(accept) for media_type in media_types: service_id = register_service(method.upper(), media_type) view_name = service_id + name # We need a service for CORS preflight processing but we don't get the # desired Accept header in the preflight request. Thus we just register # the current service_id for the given method. register_method_for_preflight(method.upper(), service_id) # Create a new class. We'll execute some security declarations on it # and don't want to modify the original class. cdict = getSecurityInfo(factory) cdict["__name__"] = view_name cdict["method"] = method.upper() new_class = type(factory.__name__, (factory, BrowserView), cdict) _context.action( discriminator=("plone.rest:service", method, media_type, for_, name, layer), callable=handler, args=( "registerAdapter", new_class, (for_, layer), Interface, view_name, _context.info, ), ) _context.action( discriminator=("plone.rest:protectClass", new_class), callable=protectClass, args=(new_class, permission), ) _context.action( discriminator=("plone.rest:InitializeClass", new_class), callable=InitializeClass, args=(new_class, ), )
def SimpleViewClass(src, offering=None, used_for=None, bases=(), name=u''): if offering is None: offering = sys._getframe(1).f_globals bases += (ViewMixinForTemplates, ) cdict = {'index': ViewPageTemplateFile(src, offering), '__name__': name} if bases: cdict.update(getSecurityInfo(bases[0])) class_ = type("SimpleViewClass from %s" % src, bases, cdict) if used_for is not None: class_.__used_for__ = used_for return class_
def SimpleViewClass(src, offering=None, used_for=None, bases=(), name=u""): if offering is None: offering = sys._getframe(1).f_globals bases += (ViewMixinForTemplates,) cdict = {"index": ViewPageTemplateFile(src, offering), "__name__": name} if bases: cdict.update(getSecurityInfo(bases[0])) class_ = type("SimpleViewClass from %s" % src, bases, cdict) if used_for is not None: class_.__used_for__ = used_for return class_
def serviceDirective( _context, method, accept, factory, for_, permission, layer=IDefaultBrowserLayer, name=u'', ): _handle_for(_context, for_) media_types = parse_accept_header(accept) for media_type in media_types: service_id = register_service(method.upper(), media_type) view_name = service_id + name # We need a service for CORS preflight processing but we don't get the # desired Accept header in the preflight request. Thus we just register # the current service_id for the given method. register_method_for_preflight(method.upper(), service_id) # Create a new class. We'll execute some security declarations on it # and don't want to modify the original class. cdict = getSecurityInfo(factory) cdict['__name__'] = view_name cdict['method'] = method.upper() new_class = type(factory.__name__, (factory, BrowserView), cdict) _context.action( discriminator=('plone.rest:service', method, media_type, for_, name, layer), callable=handler, args=('registerAdapter', new_class, (for_, layer), Interface, view_name, _context.info), ) _context.action( discriminator=('plone.rest:protectClass', new_class), callable=protectClass, args=(new_class, permission) ) _context.action( discriminator=('plone.rest:InitializeClass', new_class), callable=InitializeClass, args=(new_class,) )
def page( _context, name, permission, for_=Interface, 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, layer) required = {} permission = _handle_permission(_context, permission) if not (class_ or template): raise ConfigurationError("Must specify a class or template") 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) # TODO: new __name__ attribute must be tested if class_: if attribute != '__call__': if not hasattr(class_, attribute): raise ConfigurationError( "The provided class doesn't have the specified attribute ") if template: # class and template new_class = SimpleViewClass(template, bases=(class_, ), name=name) 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(getSecurityInfo(class_)) new_class = type(class_.__name__, ( class_, simple, ), cdict) if attribute != "__call__": # 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" if hasattr(class_, '__implements__'): classImplements(new_class, IBrowserPublisher) else: # template new_class = SimpleViewClass(template, name=name) for n in ('', attribute): required[n] = permission _handle_allowed_interface(_context, allowed_interface, permission, required) _handle_allowed_attributes(_context, allowed_attributes, permission, required) _handle_for(_context, for_) _configure_z2security(_context, new_class, required) _context.action( discriminator=('view', (for_, layer), name, IBrowserRequest), callable=handler, args=('registerAdapter', new_class, (for_, layer), Interface, name, _context.info), )
def __call__(self): (_context, name, (for_, layer), permission, 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 = queryMultiAdapter((self, request), name=name) if view is not None: return view m = class_.publishTraverse.__get__(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 = queryMultiAdapter((self, request), name=name) if view is not None: return view raise NotFound(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: cdict.update(getSecurityInfo(class_)) bases = (class_, simple) else: bases = (simple, ) try: cname = str(name) except: cname = "GeneratedClass" cdict['__name__'] = name newclass = type(cname, bases, cdict) for n in ('', ): required[n] = permission _handle_allowed_interface(_context, allowed_interface, permission, required) _handle_allowed_attributes(_context, allowed_attributes, permission, required) _handle_for(_context, for_) _configure_z2security(_context, newclass, required) if self.provides is not None: _context.action(discriminator=None, callable=provideInterface, args=('', self.provides)) _context.action( discriminator=('view', (for_, layer), name, self.provides), callable=handler, args=('registerAdapter', newclass, (for_, layer), self.provides, name, _context.info), )
def page(_context, name, permission, for_=Interface, layer=IDefaultBrowserLayer, template=None, class_=None, allowed_interface=None, allowed_attributes=None, attribute='__call__', menu=None, title=None, ): name = str(name) # De-unicode _handle_menu(_context, menu, title, [for_], name, permission, layer) required = {} permission = _handle_permission(_context, permission) if not (class_ or template): raise ConfigurationError("Must specify a class or template") 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) # TODO: new __name__ attribute must be tested if class_: if attribute != '__call__': if not hasattr(class_, attribute): raise ConfigurationError( "The provided class doesn't have the specified attribute " ) if template: # class and template new_class = SimpleViewClass(template, bases=(class_, ), name=name) 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(getSecurityInfo(class_)) new_class = type(class_.__name__, (class_, simple,), cdict) if attribute != "__call__": # 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" if hasattr(class_, '__implements__'): classImplements(new_class, IBrowserPublisher) else: # template new_class = SimpleViewClass(template, name=name) for n in ('', attribute): required[n] = permission _handle_allowed_interface(_context, allowed_interface, permission, required) _handle_allowed_attributes(_context, allowed_attributes, permission, required) _handle_for(_context, for_) _configure_z2security(_context, new_class, required) _context.action( discriminator = ('view', (for_, layer), name, IBrowserRequest), callable = handler, args = ('registerAdapter', new_class, (for_, layer), Interface, name, _context.info), )
def __call__(self): (_context, name, (for_, layer), permission, class_, allowed_interface, allowed_attributes) = self.args name = str(name) # De-unicode 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 = queryMultiAdapter((self, request), name=name) if view is not None: return view m = class_.publishTraverse.__get__(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 = queryMultiAdapter((self, request), name=name) if view is not None: return view raise NotFound(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: cdict.update(getSecurityInfo(class_)) bases = (class_, simple) else: bases = (simple,) try: cname = str(name) except: cname = "GeneratedClass" cdict['__name__'] = name newclass = type(cname, bases, cdict) for n in ('',): required[n] = permission _handle_allowed_interface(_context, allowed_interface, permission, required) _handle_allowed_attributes(_context, allowed_attributes, permission, required) _handle_for(_context, for_) _configure_z2security(_context, newclass, required) if self.provides is not None: _context.action( discriminator = None, callable = provideInterface, args = ('', self.provides) ) _context.action( discriminator = ('view', (for_, layer), name, self.provides), callable = handler, args = ('registerAdapter', newclass, (for_, layer), self.provides, name, _context.info), )
def page( _context, name, permission, for_, layer=IDefaultBrowserLayer, template=None, class_=None, allowed_interface=None, allowed_attributes=None, attribute='__call__', menu=None, title=None, ): name = str(name) # De-unicode _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(all=True)) 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)) # Make everything else private allowed = [attribute] + (allowed_attributes or []) 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)) # Protect the class _context.action(discriminator=('five:initialize:class', new_class), callable=InitializeClass, args=(new_class, ))
def page(_context, name, permission, for_, layer=IDefaultBrowserLayer, template=None, class_=None, allowed_interface=None, allowed_attributes=None, attribute='__call__', menu=None, title=None, ): name = str(name) # De-unicode _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(all=True)) 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) ) # Make everything else private allowed = [attribute] + (allowed_attributes or []) 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) ) # Protect the class _context.action( discriminator = ('five:initialize:class', new_class), callable = InitializeClass, args = (new_class,) )