class ViewletSecurityGrokker(martian.ClassGrokker): martian.component(five.grok.Viewlet) martian.directive(grokcore.security.require, name='permission') def execute(self, factory, config, permission, **kw): if permission is None: permission = 'zope.Public' attributes = [ 'update', 'render', ] config.action(discriminator=('five:protectClass', factory), callable=protectClass, args=(factory, permission)) for attribute in attributes: config.action(discriminator=('five:protectName', factory, attribute), callable=protectName, args=(factory, attribute, permission)) # Protect the class config.action(discriminator=('five:initialize:class', factory), callable=initializeClass, args=(factory, )) return True
class SiteGrokker(martian.ClassGrokker): """Grokker for subclasses of `grokcore.site.Site`.""" martian.component(grokcore.site.components.BaseSite) martian.priority(500) martian.directive(grokcore.site.local_utility, name='infos') def execute(self, factory, config, infos, **kw): if not infos: return False infos = infos.values() for info in infos: if info.public and not IContainer.implementedBy(factory): raise GrokError( "Cannot set public to True with grok.local_utility as " "the site (%r) is not a container." % factory, factory) # Store the list of info objects in their "natural" order on the # site class. They will be picked up by a subscriber doing the # actual registrations in definition order. factory.__grok_utilities_to_install__ = sorted(infos) adapts = (factory, IObjectAddedEvent) config.action( discriminator=None, callable=grokcore.component.provideHandler, args=(localUtilityRegistrationSubscriber, adapts), ) return True
class AnnotationGrokker(martian.ClassGrokker): """Grokker for components subclassed from `grok.Annotation`. """ martian.component(grokcore.annotation.Annotation) martian.directive(grokcore.annotation.context, name='adapter_context') martian.directive(grokcore.annotation.provides, get_default=default_annotation_provides) martian.directive(grokcore.annotation.name, get_default=default_annotation_name) def execute(self, factory, config, adapter_context, provides, name, **kw): @component.adapter(adapter_context) @interface.implementer(provides) def getAnnotation(context): annotations = IAnnotations(context) try: result = annotations[name] except KeyError: result = factory() annotations[name] = result if result.__parent__ is None: result.__parent__ = context result.__name__ = name return result config.action( discriminator=('adapter', adapter_context, provides, ''), callable=grokcore.component.provideAdapter, args=(getAnnotation, ), ) return True
class AlphaGrokker(martian.ClassGrokker): martian.component(Alpha) martian.priority(1) # we need to go before BetaGrokker def grok(self, name, factory, module_info, config, **kw): print "alpha" return True
class PermissionGrokker(martian.ClassGrokker): martian.component(grokcore.security.Permission) martian.priority(1500) martian.directive(grokcore.component.name) martian.directive(grokcore.component.title, get_default=default_fallback_to_name) martian.directive(grokcore.component.description) def execute(self, factory, config, name, title, description, **kw): if not name: raise GrokError( "A permission needs to have a dotted name for its id. Use " "grok.name to specify one.", factory) # We can safely convert to unicode, since the directives make sure # it is either unicode already or ASCII. permission = factory(unicode(name), unicode(title), unicode(description)) config.action( discriminator=('utility', IPermission, name), callable=grokcore.component.provideUtility, args=(permission, IPermission, name), order=-1 # need to do this early in the process ) return True
class IndexesGrokker(martian.InstanceGrokker): """Grokker for index bundles.""" martian.component(IndexesClass) def grok(self, name, factory, module_info, config, **kw): site = grokcore.site.site.bind().get(factory) context = grokcore.component.context.bind().get( factory, module_info.getModule()) install_on = grokcore.site.install_on.bind( default=IObjectAddedEvent).get(factory) catalog_name = grokcore.component.name.bind().get(factory) if site is None: raise GrokError( "No site specified for grokcore.catalog.Indexes " "subclass in module %r. " "Use grokcore.site.site() to specify." % module_info.getModule(), factory) indexes = getattr(factory, '__grok_indexes__', None) if indexes is None: return False subscriber = IndexesSetupSubscriber(catalog_name, indexes, context, module_info) subscribed = (site, install_on) config.action(discriminator=None, callable=grokcore.component.provideHandler, args=(subscriber, subscribed)) return True
class FormSchemaGrokker(martian.InstanceGrokker): """Grok form schema hints.""" martian.component(Schema.__class__) martian.directive(depends) def execute(self, interface, config, **kw): if not interface.extends(Schema): return False # Copy from temporary to real value directiveSupplied = interface.queryTaggedValue(TEMP_KEY, None) if directiveSupplied is not None: for key, tgv in list(directiveSupplied.items()): existingValue = interface.queryTaggedValue(key, None) if existingValue is not None: if type(existingValue) != type(tgv): # Don't overwrite if we have a different type continue elif isinstance(existingValue, list): existingValue.extend(tgv) tgv = existingValue elif isinstance(existingValue, dict): existingValue.update(tgv) tgv = existingValue interface.setTaggedValue(key, tgv) interface.setTaggedValue(TEMP_KEY, None) return True
class StepGrokker(martian.ClassGrokker): """Grokker to register sub forms. """ martian.component(WizardStep) martian.directive(grokcore.component.context) martian.directive(grokcore.view.layer, default=IDefaultBrowserLayer) martian.directive(grokcore.view.view) martian.directive(grokcore.view.name, get_default=default_view_name) def grok(self, name, factory, module_info, **kw): factory.module_info = module_info return super().grok(name, factory, module_info, **kw) def execute(self, factory, config, context, layer, view, name, **kw): if not factory.__dict__.get('prefix'): factory.prefix = '%s.%s' % (view.prefix, name) adapts = (context, view, layer) config.action( discriminator=('adapter', adapts, IStep, name), callable=grokcore.component.util.provideAdapter, args=(factory, adapts, IStep, name), ) return True
class MenuItemGrokker(martian.ClassGrokker): martian.component(uvc.menus.components.MenuItem) martian.directive(uvc.menus.directives.menu) martian.directive(grokcore.component.context, default=Interface) martian.directive(grokcore.view.layer, default=IDefaultBrowserLayer) martian.directive(grokcore.viewlet.view, default=Interface) martian.directive(grokcore.component.name, get_default=default_view_name) martian.directive(grokcore.security.require, name='permission') def grok(self, name, factory, module_info, **kw): # Need to store the module info object on the view class so that it # can look up the 'static' resource directory. factory.module_info = module_info return super(MenuItemGrokker, self).grok( name, factory, module_info, **kw) def execute(self, factory, config, menu, context, layer, view, name, permission, **kw): # This will be used to support __name__ on the viewlet manager factory.__view_name__ = name config.action( discriminator=('MenuItem', context, layer, view, menu, name), callable=grokcore.component.provideAdapter, args=(factory, (menu, context, layer, view), uvc.menus.components.IMenuEntry , name)) config.action( discriminator=('protectName', factory), callable=make_checker, args=(factory, factory, permission, ['available'])) return True
class GammaGrokker(martian.ClassGrokker): martian.component(Gamma) martian.priority(-1) def grok(self, name, factory, module_info, **kw): print("gamma") return True
class FormTemplateGrokker(grokcore.view.meta.views.TemplateGrokker): martian.component(GrokkedForm) def has_no_render(self, factory): # Unlike the view template grokker, we are happy with the base class # version return getattr(factory, 'render', None) is None
class AttributeTraversableGrokker(martian.MethodGrokker): """""" martian.component(grok.View) def execute(self, factory, method, config, **kw): methods = grok.traversable.bind().get(factory) if methods: name = method.__name__ if name in methods.keys(): permission = "zope.Public" method_view = type( factory.__name__, (factory, BrowserPage), {'__call__': method}) context = grok.context.bind().get(factory) adapts = (factory, IDefaultBrowserLayer) config.action( discriminator=('adapter', adapts, interface.Interface, name), callable=component.provideAdapter, args=(method_view, adapts, interface.Interface, name)) for method_name in IBrowserPage: config.action( discriminator=('protectName', method_view, method_name), callable=protect_getattr, args=(method_view, method_name, permission), ) return True
class ContentGrokker(martian.ClassGrokker): martian.component(DexterityContent) martian.directive(add_permission, default=None) martian.directive(grokcore.component.name, default=None) def execute(self, class_, config, add_permission, name, **kw): # Register class if a meta type was specified. # (most types will probably not need this.) if add_permission: meta_type = getattr(class_, 'meta_type', None) registerClass(config, class_, meta_type, add_permission) # Register a factory utility - defer this to the end of ZCML # processing, since there may have been another utility manually # registered if name: config.action( discriminator=('dexterity:registerFactory', class_, name), callable=register_factory, args=(class_, name), order=9999, ) # Initialise class security config.action(discriminator=('dexterity:registerClass', class_), callable=InitializeClass, args=(class_, )) return True
class BetaGrokker(martian.ClassGrokker): martian.component(Beta) martian.priority(1) def grok(self, name, factory, module_info, **kw): print("beta") return True
class ViewGrokker(martian.ClassGrokker): martian.component(components.View) martian.directive(grokcore.component.context) martian.directive(grokcore.view.layer, default=IDefaultBrowserLayer) martian.directive(grokcore.component.provides, default=interface.Interface) martian.directive(grokcore.component.name, get_default=default_view_name) def execute(self, factory, config, context, layer, provides, name, **kw): # safety belt: make sure that the programmer didn't use # @grok.require on any of the view's methods. methods = util.methods_from_class(factory) for method in methods: if grokcore.security.require.bind().get(method) is not None: raise GrokError( 'The @grok.require decorator is used for ' 'method %r in view %r. It may only be used ' 'for XML-RPC methods.' % (method.__name__, factory), factory) # __view_name__ is needed to support IAbsoluteURL on views factory.__view_name__ = name adapts = (context, layer) config.action( discriminator=('adapter', adapts, provides, name), callable=grokcore.component.provideAdapter, args=(factory, adapts, provides, name), ) return True
class StoreGrokker(martian.ClassGrokker): martian.component(megrok.storm.Store) martian.directive(megrok.storm.storename) martian.directive(megrok.storm.uri) def execute(self, factory, config, storename, uri, **kw): store(config, storename, uri) return True
class ModelGrokker(martian.ClassGrokker): martian.component(megrok.storm.Model) martian.directive(megrok.storm.tablename, get_default=default_tablename) def execute(self, class_, tablename, **kw): class_.__storm_table__ = tablename # we associate the _decl_registry with the metadata object # to make sure it's unique per metadata. A bit of a hack.. return True
class AppRootGrokker(martian.ClassGrokker): martian.component(megrok.storm.AppRoot) martian.directive(megrok.storm.key) martian.directive(megrok.storm.rdb_object) def execute(self, class_, key, rdb_object, **kw): class_.key = key class_.rdb_object = rdb_object return True
class ClassImplementerGrokker(martian.ClassGrokker): martian.component(object) martian.directive(grokcore.component.implements) martian.priority(2000) def execute(self, class_, implements, **kw): if implements is None: return True classImplements(class_, implements) return True
class CheckRequireGrokker(martian.ClassGrokker): """Ensure every grok.View has a grok.require directive""" martian.component(grok.View) martian.directive(grok.require, default=_require_marker) def execute(self, factory, config, require, **kw): if require is _require_marker: raise SecurityError( 'megrok.strictrequire requires %r to use the grok.require ' 'directive!' % factory, factory) return True
class CheckRequireGrokker(martian.ClassGrokker): """Ensure every grok.View has a grok.require directive""" martian.component(grok.View) martian.directive(grok.require, default=_require_marker) def execute(self, factory, config, require, **kw): if os.environ.get('UVC_SEC_CHECK') == '1': if require is _require_marker: context = grok.context.bind().get(factory) uvcsite.log('%r --> %r' % (factory, context)) return True
class CmdGrokker(martian.ClassGrokker): martian.component(Cmd) martian.directive(command) def execute(self, class_, command, **kw): if command is None: return False registry.commands()[command] = class_ class_.name = command return True
class CheckRequireRESTGrokker(martian.MethodGrokker): """Ensure every grok.REST has a grok.require directive""" martian.component(grok.REST) martian.directive(grok.require, default=_require_marker) def execute(self, factory, method, config, require, **kw): if require is _require_marker: raise SecurityError( 'megrok.strictrequire requires %r to use the grok.require ' 'directive on the method: %s!' % (factory, method), factory) return True
class ContainerGrokker(martian.ClassGrokker): martian.component(rdb.Container) def grok(self, name, factory, module_info, config, **kw): rdb_key = rdb.key.bind().get(factory) if rdb_key and hasattr(factory, 'keyfunc'): raise GrokError( "It is not allowed to specify a custom 'keyfunc' method " "for rdb.Container %r, when a rdb.key directive has also " "been given." % factory, factory) return True
class FormGrokker(martian.ClassGrokker): martian.component(components.GrokForm) martian.directive(grokcore.component.context) martian.priority(800) # Must be run before real formlib grokker. def execute(self, factory, config, context, **kw): # Set up form_fields from context class if they haven't been # configured manually already using our version of get_auto_fields if getattr(factory, 'form_fields', None) is None: factory.form_fields = formlib.get_auto_fields(context) return True
class LayoutTemplateGrokker(TemplateGrokker): martian.component(Layout) def has_render(self, factory): render = getattr(factory, 'render', None) base_method = getattr(render, 'base_method', False) return render and not base_method def has_no_render(self, factory): render = getattr(factory, 'render', None) base_method = getattr(render, 'base_method', False) return render is None or base_method
class ActionGrokker(martian.ClassGrokker): martian.component(Subscription) martian.directive(action) def execute(self, class_, action, **kw): if action is None: return False if getattr(class_, 'cmd', None) is None: class_.cmd = _action_decorator_parametrized(class_)(class_.execute) class_._name = action return True
class ViewSecurityGrokker(martian.ClassGrokker): martian.component(components.View) martian.directive(grokcore.security.require, name='permission') def execute(self, factory, config, permission, **kw): for method_name in IBrowserPage: config.action( discriminator=('protectName', factory, method_name), callable=protect_getattr, args=(factory, method_name, permission), ) return True
class AliasGrokker(martian.ClassGrokker): martian.component(Cmd) martian.directive(alias) def execute(self, class_, alias, **kwargs): if not getattr(class_, 'aliases', None): class_.aliases = [] if alias: class_.aliases.append(alias) registry.commands()[alias] = class_ return False
class ClasslevelGrokker(martian.ClassGrokker): """Simple grokker that looks for grokk.require() directives on a class and checks whether the permissione exists.""" martian.component(grokcore.component.Context) martian.directive(directive.require, name='permission') def execute(self, factory, config, permission, **kw): config.action( discriminator=('protectName', factory, 'protected'), callable=util.protect_getattr, args=(factory, 'protected', permission), ) return True