[Checkins] SVN: grokcore.security/trunk/src/grokcore/security/ Get
rid of a lot of Grok-only stuff
Philipp von Weitershausen
philikon at philikon.de
Mon Jul 28 16:46:10 EDT 2008
Log message for revision 88900:
Get rid of a lot of Grok-only stuff
Changed:
U grokcore.security/trunk/src/grokcore/security/__init__.py
U grokcore.security/trunk/src/grokcore/security/components.py
U grokcore.security/trunk/src/grokcore/security/directive.py
D grokcore.security/trunk/src/grokcore/security/formlib.py
D grokcore.security/trunk/src/grokcore/security/index.py
U grokcore.security/trunk/src/grokcore/security/interfaces.py
U grokcore.security/trunk/src/grokcore/security/meta.py
U grokcore.security/trunk/src/grokcore/security/meta.zcml
D grokcore.security/trunk/src/grokcore/security/publication.py
D grokcore.security/trunk/src/grokcore/security/rest.py
D grokcore.security/trunk/src/grokcore/security/templatereg.py
D grokcore.security/trunk/src/grokcore/security/templates/
U grokcore.security/trunk/src/grokcore/security/testing.py
D grokcore.security/trunk/src/grokcore/security/tests/adapter/
D grokcore.security/trunk/src/grokcore/security/tests/annotation/
D grokcore.security/trunk/src/grokcore/security/tests/application/
D grokcore.security/trunk/src/grokcore/security/tests/baseclass/
D grokcore.security/trunk/src/grokcore/security/tests/catalog/
D grokcore.security/trunk/src/grokcore/security/tests/conflict/
D grokcore.security/trunk/src/grokcore/security/tests/container/
D grokcore.security/trunk/src/grokcore/security/tests/error/
D grokcore.security/trunk/src/grokcore/security/tests/event/
D grokcore.security/trunk/src/grokcore/security/tests/form/
D grokcore.security/trunk/src/grokcore/security/tests/json/
D grokcore.security/trunk/src/grokcore/security/tests/order/
D grokcore.security/trunk/src/grokcore/security/tests/static/
D grokcore.security/trunk/src/grokcore/security/tests/template/
D grokcore.security/trunk/src/grokcore/security/tests/testsetup/
D grokcore.security/trunk/src/grokcore/security/tests/traversal/
D grokcore.security/trunk/src/grokcore/security/tests/utility/
D grokcore.security/trunk/src/grokcore/security/tests/view/
D grokcore.security/trunk/src/grokcore/security/tests/viewlet/
D grokcore.security/trunk/src/grokcore/security/tests/xmlrpc/
D grokcore.security/trunk/src/grokcore/security/tests/zcml/
-=-
Modified: grokcore.security/trunk/src/grokcore/security/__init__.py
===================================================================
--- grokcore.security/trunk/src/grokcore/security/__init__.py 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/__init__.py 2008-07-28 20:46:10 UTC (rev 88900)
@@ -14,52 +14,10 @@
"""Grok
"""
-from zope.interface import implements
-from zope.component import adapts
-from zope.event import notify
-from zope.app.component.hooks import getSite
-from zope.lifecycleevent import (
- IObjectCreatedEvent, ObjectCreatedEvent,
- IObjectModifiedEvent, ObjectModifiedEvent,
- IObjectCopiedEvent, ObjectCopiedEvent)
+from grokcore.security.components import Permission, Public
+from grokcore.security.directive import require
-from zope.app.container.contained import (
- IObjectAddedEvent, ObjectAddedEvent,
- IObjectMovedEvent, ObjectMovedEvent,
- IObjectRemovedEvent, ObjectRemovedEvent,
- IContainerModifiedEvent, ContainerModifiedEvent)
-from martian import ClassGrokker, InstanceGrokker, GlobalGrokker
-from grokcore.component import Adapter, MultiAdapter, GlobalUtility
-from grok.components import Model, View
-from grok.components import XMLRPC, REST, JSON
-from grok.components import PageTemplate, PageTemplateFile, Traverser
-from grok.components import Container, OrderedContainer
-from grok.components import Site, LocalUtility, Annotation
-from grok.components import Application, Form, AddForm, EditForm, DisplayForm
-from grok.components import Indexes
-from grok.components import Permission, Role, Public
-from grok.components import Skin, IGrokLayer
-from grok.components import RESTProtocol, IRESTLayer
-from grok.interfaces import IRESTSkinType
-from grok.components import ViewletManager, Viewlet
-
-from martian import baseclass
-from grokcore.component.directive import (
- context, name, title, description, provides, global_utility, direct)
-from grok.directive import (
- template, templatedir, local_utility, permissions, require, site,
- layer, viewletmanager, view, traversable, order)
-from grokcore.component.decorators import subscribe, adapter, implementer
-from martian.error import GrokError, GrokImportError
-
-# BBB These two functions are meant for test fixtures and should be
-# imported from grok.testing, not from grok.
-from grok.testing import grok, grok_component
-
-from grok.formlib import action, AutoFields, Fields
-from grok.util import url
-
# Our __init__ provides the grok API directly so using 'import grok' is enough.
from grok.interfaces import IGrokAPI
from zope.interface import moduleProvides
Modified: grokcore.security/trunk/src/grokcore/security/components.py
===================================================================
--- grokcore.security/trunk/src/grokcore/security/components.py 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/components.py 2008-07-28 20:46:10 UTC (rev 88900)
@@ -13,750 +13,9 @@
##############################################################################
"""Grok components"""
-import sys
-import os
-import persistent
-import datetime
-import warnings
-import pytz
-import simplejson
-
-import zope.location
-from zope import component
-from zope import interface
-from zope.interface.common import idatetime
from zope.security.permission import Permission
-from zope.securitypolicy.role import Role
-from zope.publisher.browser import BrowserPage
-from zope.publisher.interfaces import NotFound
-from zope.publisher.interfaces.browser import IBrowserPublisher
-from zope.publisher.interfaces.http import IHTTPRequest
-from zope.publisher.publish import mapply
-from zope.pagetemplate import pagetemplate, pagetemplatefile
-from zope.formlib import form
-from zope.annotation.interfaces import IAttributeAnnotatable
-from zope.app.pagetemplate.engine import TrustedAppPT
-from zope.app.publisher.browser import getDefaultViewName
-from zope.app.publisher.browser import directoryresource
-from zope.app.publisher.browser.pagetemplateresource import \
- PageTemplateResourceFactory
-from zope.app.container.btree import BTreeContainer
-from zope.app.container.contained import Contained
-from zope.app.container.interfaces import IReadContainer, IObjectAddedEvent
-from zope.app.container.interfaces import IOrderedContainer
-from zope.app.container.contained import notifyContainerModified
-from persistent.list import PersistentList
-from zope.app.component.site import SiteManagerContainer
-from zope.app.component.site import LocalSiteManager
-
-from zope.viewlet.manager import ViewletManagerBase
-from zope.viewlet.viewlet import ViewletBase
-
-import grok
-import z3c.flashmessage.interfaces
-import martian.util
-
-from grok import interfaces, formlib, util
-
-
-class Model(Contained, persistent.Persistent):
- # XXX Inheritance order is important here. If we reverse this,
- # then containers can't be models anymore because no unambigous MRO
- # can be established.
- interface.implements(IAttributeAnnotatable, interfaces.IContext)
-
-
-class Container(BTreeContainer):
- interface.implements(IAttributeAnnotatable, interfaces.IContainer)
-
-
-class OrderedContainer(Container):
- interface.implements(IOrderedContainer)
-
- def __init__(self):
- super(OrderedContainer, self).__init__()
- self._order = PersistentList()
-
- def keys(self):
- # Return a copy of the list to prevent accidental modifications.
- return self._order[:]
-
- def __iter__(self):
- return iter(self.keys())
-
- def values(self):
- return (self[key] for key in self._order)
-
- def items(self):
- return ((key, self[key]) for key in self._order)
-
- def __setitem__(self, key, object):
- foo = self.has_key(key)
- # Then do whatever containers normally do.
- super(OrderedContainer, self).__setitem__(key, object)
- if not foo:
- self._order.append(key)
-
- def __delitem__(self, key):
- # First do whatever containers normally do.
- super(OrderedContainer, self).__delitem__(key)
- self._order.remove(key)
-
- def updateOrder(self, order):
- if set(order) != set(self._order):
- raise ValueError("Incompatible key set.")
-
- self._order = PersistentList()
- self._order.extend(order)
- notifyContainerModified(self)
-
-
-class Site(SiteManagerContainer):
- pass
-
- at component.adapter(Site, IObjectAddedEvent)
-def addSiteHandler(site, event):
- sitemanager = LocalSiteManager(site)
- # LocalSiteManager creates the 'default' folder in its __init__.
- # It's not needed anymore in new versions of Zope 3, therefore we
- # remove it
- del sitemanager['default']
- site.setSiteManager(sitemanager)
-
-
-class Application(Site):
- """A top-level application object."""
- interface.implements(interfaces.IApplication)
-
-
-class LocalUtility(Model):
- pass
-
-
-class Annotation(persistent.Persistent):
- pass
-
-
-class ViewBase(object):
- def __init__(self, context, request):
- self.context = context
- self.request = request
-
-class View(BrowserPage):
- interface.implements(interfaces.IGrokView)
-
- def __init__(self, context, request):
- super(View, self).__init__(context, request)
- self.__name__ = self.__view_name__
- self.static = component.queryAdapter(
- self.request,
- interface.Interface,
- name=self.module_info.package_dotted_name
- )
-
- @property
- def response(self):
- return self.request.response
-
- def __call__(self):
- mapply(self.update, (), self.request)
- if self.request.response.getStatus() in (302, 303):
- # A redirect was triggered somewhere in update(). Don't
- # continue rendering the template or doing anything else.
- return
-
- template = getattr(self, 'template', None)
- if template is not None:
- return self._render_template()
- return mapply(self.render, (), self.request)
-
- def _render_template(self):
- return self.template.render(self)
-
- def default_namespace(self):
- namespace = {}
- namespace['context'] = self.context
- namespace['request'] = self.request
- namespace['static'] = self.static
- namespace['view'] = self
- return namespace
-
- def namespace(self):
- return {}
-
- def __getitem__(self, key):
- # This is BBB code for Zope page templates only:
- if not isinstance(self.template, PageTemplate):
- raise AttributeError("View has no item %s" % key)
-
- value = self.template._template.macros[key]
- # When this deprecation is done with, this whole __getitem__ can
- # be removed.
- warnings.warn("Calling macros directly on the view is deprecated. "
- "Please use context/@@viewname/macros/macroname\n"
- "View %r, macro %s" % (self, key),
- DeprecationWarning, 1)
- return value
-
-
- def url(self, obj=None, name=None, data=None):
- """Return string for the URL based on the obj and name. The data
- argument is used to form a CGI query string.
- """
- if isinstance(obj, basestring):
- if name is not None:
- raise TypeError(
- 'url() takes either obj argument, obj, string arguments, '
- 'or string argument')
- name = obj
- obj = None
-
- if name is None and obj is None:
- # create URL to view itself
- obj = self
- elif name is not None and obj is None:
- # create URL to view on context
- obj = self.context
-
- if data is None:
- data = {}
- else:
- if not isinstance(data, dict):
- raise TypeError('url() data argument must be a dict.')
-
- return util.url(self.request, obj, name, data=data)
-
- def application_url(self, name=None):
- obj = self.context
- while obj is not None:
- if isinstance(obj, Application):
- return self.url(obj, name)
- obj = obj.__parent__
- raise ValueError("No application found.")
-
- def redirect(self, url):
- return self.request.response.redirect(url)
-
- def update(self):
- pass
-
- def flash(self, message, type='message'):
- source = component.getUtility(
- z3c.flashmessage.interfaces.IMessageSource, name='session')
- source.send(message, type)
-
-
-class XMLRPC(object):
- pass
-
-class REST(zope.location.Location):
- interface.implements(interfaces.IREST)
-
- def __init__(self, context, request):
- self.context = self.__parent__ = context
- self.request = request
- self.body = request.bodyStream.getCacheStream().read()
-
- @property
- def response(self):
- return self.request.response
-
-## def GET(self):
-## raise GrokMethodNotAllowed(self.context, self.request)
-
-## def POST(self):
-## raise GrokMethodNotAllowed(self.context, self.request)
-
-## def PUT(self):
-## raise GrokMethodNotAllowed(self.context, self.request)
-
-## def DELETE(self):
-## raise GrokMethodNotAllowed(self.context, self.request)
-
-class JSON(BrowserPage):
-
- def __call__(self):
- view_name = self.__view_name__
- method = getattr(self, view_name)
- method_result = mapply(method, (), self.request)
- return simplejson.dumps(method_result)
-
-
-class BaseTemplate(object):
- """Any sort of page template"""
-
- interface.implements(interfaces.ITemplate)
-
- __grok_name__ = ''
- __grok_location__ = ''
-
- def __repr__(self):
- return '<%s template in %s>' % (self.__grok_name__,
- self.__grok_location__)
-
- def _annotateGrokInfo(self, name, location):
- self.__grok_name__ = name
- self.__grok_location__ = location
-
- def _initFactory(self, factory):
- pass
-
-
-class GrokTemplate(BaseTemplate):
- """A slightly more advanced page template
-
- This provides most of what a page template needs and is a good base for
- writing your own page template"""
-
- def __init__(self, string=None, filename=None, _prefix=None):
-
- # __grok_module__ is needed to make defined_locally() return True for
- # inline templates
- # XXX unfortunately using caller_module means that care must be taken
- # when GrokTemplate is subclassed. You can not do a super().__init__
- # for example.
- self.__grok_module__ = martian.util.caller_module()
-
- if not (string is None) ^ (filename is None):
- raise AssertionError(
- "You must pass in template or filename, but not both.")
-
- if string:
- self.setFromString(string)
- else:
- if _prefix is None:
- module = sys.modules[self.__grok_module__]
- _prefix = os.path.dirname(module.__file__)
- self.setFromFilename(filename, _prefix)
-
- def __repr__(self):
- return '<%s template in %s>' % (self.__grok_name__,
- self.__grok_location__)
-
- def _annotateGrokInfo(self, name, location):
- self.__grok_name__ = name
- self.__grok_location__ = location
-
- def _initFactory(self, factory):
- pass
-
- def namespace(self, view):
- # By default use the namespaces that are defined as the
- # default by the view implementation.
- return view.default_namespace()
-
- def getNamespace(self, view):
- namespace = self.namespace(view)
- namespace.update(view.namespace())
- return namespace
-
-class TrustedPageTemplate(TrustedAppPT, pagetemplate.PageTemplate):
- pass
-
-class TrustedFilePageTemplate(TrustedAppPT, pagetemplatefile.PageTemplateFile):
- pass
-
-class PageTemplate(GrokTemplate):
-
- def setFromString(self, string):
- zpt = TrustedPageTemplate()
- if martian.util.not_unicode_or_ascii(string):
- raise ValueError("Invalid page template. Page templates must be "
- "unicode or ASCII.")
- zpt.write(string)
- self._template = zpt
-
- def setFromFilename(self, filename, _prefix=None):
- self._template = TrustedFilePageTemplate(filename, _prefix)
-
- def _initFactory(self, factory):
- factory.macros = self._template.macros
-
- def render(self, view):
- namespace = self.getNamespace(view)
- template = self._template
- namespace.update(template.pt_getContext())
- return template.pt_render(namespace)
-
-class PageTemplateFile(PageTemplate):
- # For BBB
- def __init__(self, filename, _prefix=None):
- self.__grok_module__ = martian.util.caller_module()
- if _prefix is None:
- module = sys.modules[self.__grok_module__]
- _prefix = os.path.dirname(module.__file__)
- self.setFromFilename(filename, _prefix)
-
-class DirectoryResource(directoryresource.DirectoryResource):
- # We subclass this, because we want to override the default factories for
- # the resources so that .pt and .html do not get created as page
- # templates
-
- resource_factories = {}
- for type, factory in (directoryresource.DirectoryResource.
- resource_factories.items()):
- if factory is PageTemplateResourceFactory:
- continue
- resource_factories[type] = factory
-
-
-class DirectoryResourceFactory(object):
- # We need this to allow hooking up our own GrokDirectoryResource
- # and to set the checker to None (until we have our own checker)
-
- def __init__(self, path, name):
- # XXX we're not sure about the checker=None here
- self.__dir = directoryresource.Directory(path, None, name)
- self.__name = name
-
- def __call__(self, request):
- resource = DirectoryResource(self.__dir, request)
- resource.__name__ = self.__name
- return resource
-
-
-class Traverser(object):
- interface.implements(IBrowserPublisher)
-
- def __init__(self, context, request):
- self.context = context
- self.request = request
-
- def browserDefault(self, request):
- # if we have a RESTful request, we will handle
- # GET, POST and HEAD differently (PUT and DELETE are handled already
- # but not on the BrowserRequest layer but the HTTPRequest layer)
- if IRESTLayer.providedBy(request):
- rest_view = component.getMultiAdapter(
- (self.context, self.request),
- name=request.method)
- return rest_view, ()
- view_name = getDefaultViewName(self.context, request)
- view_uri = "@@%s" % view_name
- return self.context, (view_uri,)
-
- def publishTraverse(self, request, name):
- subob = self.traverse(name)
- if subob is not None:
- return util.safely_locate_maybe(subob, self.context, name)
-
- traversable_dict = grok.traversable.bind().get(self.context)
- if traversable_dict:
- if name in traversable_dict:
- subob = getattr(self.context, traversable_dict[name])
- if callable(subob):
- subob = subob()
- return util.safely_locate_maybe(subob, self.context, name)
-
- # XXX Special logic here to deal with containers. It would be
- # good if we wouldn't have to do this here. One solution is to
- # rip this out and make you subclass ContainerTraverser if you
- # wanted to override the traversal behaviour of containers.
- if IReadContainer.providedBy(self.context):
- item = self.context.get(name)
- if item is not None:
- return item
-
- view = component.queryMultiAdapter((self.context, request), name=name)
- if view is not None:
- return view
-
- raise NotFound(self.context, name, request)
-
- def traverse(self, name):
- # this will be overridden by subclasses
- pass
-
-
-class ContextTraverser(Traverser):
- component.adapts(interfaces.IContext, IHTTPRequest)
-
- def traverse(self, name):
- traverse = getattr(self.context, 'traverse', None)
- if traverse:
- return traverse(name)
-
-
-class ContainerTraverser(Traverser):
- component.adapts(interfaces.IContainer, IHTTPRequest)
-
- def traverse(self, name):
- traverse = getattr(self.context, 'traverse', None)
- if traverse:
- result = traverse(name)
- if result is not None:
- return result
- # try to get the item from the container
- return self.context.get(name)
-
-
-default_form_template = PageTemplateFile(os.path.join(
- 'templates', 'default_edit_form.pt'))
-default_form_template.__grok_name__ = 'default_edit_form'
-default_display_template = PageTemplateFile(os.path.join(
- 'templates', 'default_display_form.pt'))
-default_display_template.__grok_name__ = 'default_display_form'
-
-
-class GrokForm(object):
- """Mix-in to consolidate zope.formlib's forms with grok.View and to
- add some more useful methods.
-
- The consolidation needs to happen because zope.formlib's Forms have
- update/render methods which have different meanings than
- grok.View's update/render methods. We deal with this issue by
- 'renaming' zope.formlib's update() to update_form() and by
- disallowing subclasses to have custom render() methods."""
-
- def update(self):
- """Subclasses can override this method just like on regular
- grok.Views. It will be called before any form processing
- happens."""
-
- def update_form(self):
- """Update the form, i.e. process form input using widgets.
-
- On zope.formlib forms, this is what the update() method is.
- In grok views, the update() method has a different meaning.
- That's why this method is called update_form() in grok forms."""
- super(GrokForm, self).update()
-
- def render(self):
- """Render the form, either using the form template or whatever
- the actions returned in form_result."""
- # if the form has been updated, it will already have a result
- if self.form_result is None:
- if self.form_reset:
- # we reset, in case data has changed in a way that
- # causes the widgets to have different data
- self.resetForm()
- self.form_reset = False
- self.form_result = self._render_template()
-
- return self.form_result
-
- # Mark the render() method as a method from the base class. That
- # way we can detect whether somebody overrides render() in a
- # subclass (which we don't allow).
- render.base_method = True
-
- def __call__(self):
- mapply(self.update, (), self.request)
- if self.request.response.getStatus() in (302, 303):
- # A redirect was triggered somewhere in update(). Don't
- # continue rendering the template or doing anything else.
- return
-
- self.update_form()
- return self.render()
-
-
-class Form(GrokForm, form.FormBase, View):
- # We're only reusing the form implementation from zope.formlib, we
- # explicitly don't want to inherit the interface semantics (mostly
- # for the different meanings of update/render).
- interface.implementsOnly(interfaces.IGrokForm)
-
- template = default_form_template
-
- def applyData(self, obj, **data):
- return formlib.apply_data_event(obj, self.form_fields, data,
- self.adapters)
-
- # BBB -- to be removed in June 2007
- def applyChanges(self, obj, **data):
- warnings.warn("The 'applyChanges' method on forms is deprecated "
- "and will disappear by June 2007. Please use "
- "'applyData' instead.", DeprecationWarning, 2)
- return bool(self.applyData(obj, **data))
-
-
-class AddForm(Form):
- pass
-
-
-class EditForm(GrokForm, form.EditFormBase, View):
- # We're only reusing the form implementation from zope.formlib, we
- # explicitly don't want to inherit the interface semantics (mostly
- # for the different meanings of update/render).
- interface.implementsOnly(interfaces.IGrokForm)
-
- template = default_form_template
-
- def applyData(self, obj, **data):
- return formlib.apply_data_event(obj, self.form_fields, data,
- self.adapters, update=True)
-
- # BBB -- to be removed in June 2007
- def applyChanges(self, obj, **data):
- warnings.warn("The 'applyChanges' method on forms is deprecated "
- "and will disappear by June 2007. Please use "
- "'applyData' instead.", DeprecationWarning, 2)
- return bool(self.applyData(obj, **data))
-
- @formlib.action("Apply")
- def handle_edit_action(self, **data):
- if self.applyData(self.context, **data):
- formatter = self.request.locale.dates.getFormatter(
- 'dateTime', 'medium')
-
- try:
- time_zone = idatetime.ITZInfo(self.request)
- except TypeError:
- time_zone = pytz.UTC
-
- self.status = "Updated on %s" % formatter.format(
- datetime.datetime.now(time_zone)
- )
- else:
- self.status = 'No changes'
-
-
-class DisplayForm(GrokForm, form.DisplayFormBase, View):
- # We're only reusing the form implementation from zope.formlib, we
- # explicitly don't want to inherit the interface semantics (mostly
- # for the different meanings of update/render).
- interface.implementsOnly(interfaces.IGrokForm)
-
- template = default_display_template
-
-
-class IndexesClass(object):
- def __init__(self, name, bases=(), attrs=None):
- if attrs is None:
- return
- indexes = {}
- for name, value in attrs.items():
- # Ignore everything that's not an index definition object
- # except for values set by directives
- if '.' in name:
- setattr(self, name, value)
- continue
- if not interfaces.IIndexDefinition.providedBy(value):
- continue
- indexes[name] = value
- self.__grok_indexes__ = indexes
- # __grok_module__ is needed to make defined_locally() return True for
- # inline templates
- self.__grok_module__ = martian.util.caller_module()
-
-Indexes = IndexesClass('Indexes')
-
class Permission(Permission):
pass
Public = 'zope.Public'
-
-class Role(Role):
- pass
-
-class IGrokLayer(interface.Interface):
- pass
-
-class IRESTLayer(interface.Interface):
- pass
-
-class Skin(object):
- pass
-
-class RESTProtocol(object):
- pass
-
-class ViewletManager(ViewletManagerBase):
- interface.implements(interfaces.IViewletManager)
-
- template = None
-
- def __init__(self, context, request, view):
- super(ViewletManager, self).__init__(context, request, view)
- self.context = context
- self.request = request
- self.view = view
- self.__name__ = self.__view_name__
- self.static = component.queryAdapter(
- self.request,
- interface.Interface,
- name=self.module_info.package_dotted_name
- )
-
- def sort(self, viewlets):
- """Sort the viewlets.
-
- ``viewlets`` is a list of tuples of the form (name, viewlet).
- """
- # In Grok, the default order of the viewlets is determined by
- # util.sort_components. util.sort_components() however expects
- # a list of just components, but sort() is supposed to deal
- # with a list of (name, viewlet) tuples.
- # To handle this situation we first store the name part on the
- # viewlet, then use util.sort_components() and then "unpack"
- # the name from the viewlet and recreate the list of (name,
- # viewlet) tuples, now in the correct order.
- s_viewlets = []
- for name, viewlet in viewlets:
- # Stuff away viewlet name so we can later retrieve it.
- # XXX We loose name information in case the same viewlet
- # is in the viewlets list twice, but with a different
- # name. Most probably this situation doesn't occur.
- viewlet.__viewlet_name__ = name
- s_viewlets.append(viewlet)
- s_viewlets = util.sort_components(s_viewlets)
- return [(viewlet.__viewlet_name__, viewlet) for viewlet in s_viewlets]
-
- def default_namespace(self):
- namespace = {}
- namespace['context'] = self.context
- namespace['request'] = self.request
- namespace['static'] = self.static
- namespace['view'] = self.view
- namespace['viewletmanager'] = self
- return namespace
-
- def namespace(self):
- return {}
-
- def render(self):
- """See zope.contentprovider.interfaces.IContentProvider"""
- # Now render the view
- if self.template:
- return self.template.render(self)
- else:
- return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
-
-
-class Viewlet(ViewletBase):
- """Batteries included viewlet.
- """
-
- def __init__(self, context, request, view, manager):
- super(Viewlet, self).__init__(context, request, view, manager)
- self.context = context
- self.request = request
- self.view = view
- self.viewletmanager = manager
- self.__name__ = self.__view_name__
- self.static = component.queryAdapter(
- self.request,
- interface.Interface,
- name=self.module_info.package_dotted_name
- )
-
- def default_namespace(self):
- namespace = {}
- namespace['context'] = self.context
- namespace['request'] = self.request
- namespace['static'] = self.static
- namespace['view'] = self.view
- namespace['viewlet'] = self
- namespace['viewletmanager'] = self.manager
- return namespace
-
- def namespace(self):
- return {}
-
- def update(self):
- pass
-
- def render(self):
- return self.template.render(self)
Modified: grokcore.security/trunk/src/grokcore/security/directive.py
===================================================================
--- grokcore.security/trunk/src/grokcore/security/directive.py 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/directive.py 2008-07-28 20:46:10 UTC (rev 88900)
@@ -13,99 +13,14 @@
##############################################################################
"""Grok directives.
"""
-
import sys
-import grok
-from zope import interface
-from zope.interface.interfaces import IInterface
-from zope.publisher.interfaces.browser import IBrowserView
-
import martian
+import grokcore.component
from martian import util
from martian.error import GrokImportError, GrokError
from martian.directive import StoreMultipleTimes
-from grokcore.component.scan import UnambiguousComponentScope
-from grok import components
+from grokcore.security import components
-# Define grok directives
-class template(martian.Directive):
- scope = martian.CLASS
- store = martian.ONCE
- validate = martian.validateText
-
-class templatedir(martian.Directive):
- scope = martian.MODULE
- store = martian.ONCE
- validate = martian.validateText
-
-class local_utility(martian.Directive):
- scope = martian.CLASS
- store = martian.DICT
-
- def factory(self, factory, provides=None, name=u'',
- setup=None, public=False, name_in_container=None):
- if provides is not None and not IInterface.providedBy(provides):
- raise GrokImportError("You can only pass an interface to the "
- "provides argument of %s." % self.name)
-
- if provides is None:
- provides = grok.provides.bind().get(factory)
-
- if provides is None:
- if util.check_subclass(factory, grok.LocalUtility):
- baseInterfaces = interface.implementedBy(grok.LocalUtility)
- utilityInterfaces = interface.implementedBy(factory)
- provides = list(utilityInterfaces - baseInterfaces)
-
- if len(provides) == 0 and len(list(utilityInterfaces)) > 0:
- raise GrokImportError(
- "Cannot determine which interface to use "
- "for utility registration of %r. "
- "It implements an interface that is a specialization "
- "of an interface implemented by grok.LocalUtility. "
- "Specify the interface by either using grok.provides "
- "on the utility or passing 'provides' to "
- "grok.local_utility." % factory, factory)
- else:
- provides = list(interface.implementedBy(factory))
-
- util.check_implements_one_from_list(provides, factory)
- provides = provides[0]
-
- if (provides, name) in self.frame.f_locals.get(self.dotted_name(), {}):
- raise GrokImportError(
- "Conflicting local utility registration %r. "
- "Local utilities are registered multiple "
- "times for interface %r and name %r." %
- (factory, provides, name), factory)
-
- info = LocalUtilityInfo(factory, provides, name, setup, public,
- name_in_container)
- return (provides, name), info
-
-
-class LocalUtilityInfo(object):
-
- _order = 0
-
- def __init__(self, factory, provides, name=u'',
- setup=None, public=False, name_in_container=None):
- self.factory = factory
- self.provides = provides
- self.name = name
- self.setup = setup
- self.public = public
- self.name_in_container = name_in_container
-
- self.order = LocalUtilityInfo._order
- LocalUtilityInfo._order += 1
-
- def __cmp__(self, other):
- # LocalUtilityInfos have an inherit sort order by which the
- # registrations take place.
- return cmp(self.order, other.order)
-
-
class RequireDirectiveStore(StoreMultipleTimes):
def get(self, directive, component, default):
@@ -135,7 +50,7 @@
def factory(self, value):
if util.check_subclass(value, components.Permission):
- return grok.name.bind().get(value)
+ return grokcore.component.name.bind().get(value)
return value
def __call__(self, func):
@@ -147,51 +62,3 @@
permission = self.store.pop(frame.f_locals, self)
self.set(func, [permission])
return func
-
-class site(martian.Directive):
- scope = martian.CLASS
- store = martian.ONCE
- validate = martian.validateInterfaceOrClass
-
-class permissions(martian.Directive):
- scope = martian.CLASS
- store = martian.ONCE
- default = []
-
- def factory(*args):
- return args
-
-class OneInterfaceOrClassOnClassOrModule(martian.Directive):
- """Convenience base class. Not for public use."""
- scope = martian.CLASS_OR_MODULE
- store = martian.ONCE
- validate = martian.validateInterfaceOrClass
-
-class layer(OneInterfaceOrClassOnClassOrModule):
- pass
-
-class viewletmanager(OneInterfaceOrClassOnClassOrModule):
- scope = UnambiguousComponentScope('viewletmanager')
-
-class view(OneInterfaceOrClassOnClassOrModule):
- default = IBrowserView
-
-class traversable(martian.Directive):
- scope = martian.CLASS
- store = martian.DICT
-
- def factory(self, attr, name=None):
- if name is None:
- name = attr
- return (name, attr)
-
-class order(martian.Directive):
- scope = martian.CLASS
- store = martian.ONCE
- default = 0, 0
-
- _order = 0
-
- def factory(self, value=0):
- order._order += 1
- return value, order._order
Deleted: grokcore.security/trunk/src/grokcore/security/formlib.py
===================================================================
--- grokcore.security/trunk/src/grokcore/security/formlib.py 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/formlib.py 2008-07-28 20:46:10 UTC (rev 88900)
@@ -1,124 +0,0 @@
-import types
-from zope import interface, event, lifecycleevent
-from zope.interface.interfaces import IInterface
-from zope.formlib import form
-from zope.schema.interfaces import IField
-
-class action(form.action):
- """We override the action decorator we pass in our custom Action.
- """
- def __call__(self, success):
- action = Action(self.label, success=success, **self.options)
- self.actions.append(action)
- return action
-
-class Action(form.Action):
- def success(self, data):
- if self.success_handler is not None:
- return self.success_handler(self.form, **data)
-
-def Fields(*args, **kw):
- fields = []
- for key, value in kw.items():
- if IField.providedBy(value):
- value.__name__ = key
- fields.append(value)
- del kw[key]
- fields.sort(key=lambda field: field.order)
- return form.Fields(*(args + tuple(fields)), **kw)
-
-def get_auto_fields(context):
- """Get the form fields for context.
- """
- # for an interface context, we generate them from that interface
- if IInterface.providedBy(context):
- return form.Fields(context)
- # if we have a non-interface context, we're autogenerating them
- # from any schemas defined by the context
- fields = form.Fields(*most_specialized_interfaces(context))
- # we pull in this field by default, but we don't want it in our form
- fields = fields.omit('__name__')
- return fields
-
-AutoFields = get_auto_fields
-
-def most_specialized_interfaces(context):
- """Get interfaces for an object without any duplicates.
-
- Interfaces in a declaration for an object may already have been seen
- because it is also inherited by another interface. Don't return the
- interface twice, as that would result in duplicate names when creating
- the form.
- """
- declaration = interface.implementedBy(context)
- seen = []
- for iface in declaration.flattened():
- if interface_seen(seen, iface):
- continue
- seen.append(iface)
- return seen
-
-def interface_seen(seen, iface):
- """Return True if interface already is seen.
- """
- for seen_iface in seen:
- if seen_iface.extends(iface):
- return True
- return False
-
-def apply_data(context, form_fields, data, adapters=None, update=False):
- """Save form data (``data`` dict) on a ``context`` object.
-
- This is a beefed up version of zope.formlib.form.applyChanges().
- It allows you to specify whether values should be compared with
- the attributes on already existing objects or not, using the
- ``update`` parameter.
-
- Unlike zope.formlib.form.applyChanges(), it will return a
- dictionary of interfaces and their fields that were changed. This
- is necessary to appropriately send IObjectModifiedEvents.
- """
- if adapters is None:
- adapters = {}
-
- changes = {}
-
- for form_field in form_fields:
- field = form_field.field
- # Adapt context, if necessary
- interface = form_field.interface
- adapter = adapters.get(interface)
- if adapter is None:
- if interface is None:
- adapter = context
- else:
- adapter = interface(context)
- adapters[interface] = adapter
-
- name = form_field.__name__
- newvalue = data.get(name, form_field) # using form_field as marker
-
- if update:
- if ((newvalue is not form_field) and
- (field.get(adapter) != newvalue)):
- field.set(adapter, newvalue)
- changes.setdefault(interface, []).append(name)
- else:
- if newvalue is not form_field:
- field.set(adapter, newvalue)
- changes.setdefault(interface, []).append(name)
-
- return changes
-
-def apply_data_event(context, form_fields, data, adapters=None, update=False):
- """Like apply_data, but also sends an IObjectModifiedEvent.
- """
- changes = apply_data(context, form_fields, data, adapters, update)
-
- if changes:
- descriptions = []
- for interface, names in changes.items():
- descriptions.append(lifecycleevent.Attributes(interface, *names))
- event.notify(lifecycleevent.ObjectModifiedEvent(context, *descriptions))
-
- return changes
Deleted: grokcore.security/trunk/src/grokcore/security/index.py
===================================================================
--- grokcore.security/trunk/src/grokcore/security/index.py 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/index.py 2008-07-28 20:46:10 UTC (rev 88900)
@@ -1,60 +0,0 @@
-import sys
-
-from zope.interface import implements
-from zope.interface.interfaces import IMethod, IInterface
-
-from zope.app.catalog.field import FieldIndex
-from zope.app.catalog.text import TextIndex
-from zc.catalog.catalogindex import SetIndex
-
-from martian.error import GrokError, GrokImportError
-from martian.util import frame_is_class
-
-from grok.interfaces import IIndexDefinition
-
-class IndexDefinition(object):
- implements(IIndexDefinition)
-
- index_class = None
-
- def __init__(self, *args, **kw):
- frame = sys._getframe(1)
- if not frame_is_class(frame):
- raise GrokImportError(
- "%r can only be instantiated on class level." % self.__class__)
- # store any extra parameters to pass to index later
- self._args = args
- self._attribute = kw.pop('attribute', None)
- self._kw = kw
-
- def setup(self, catalog, name, context, module_info):
- if self._attribute is not None:
- field_name = self._attribute
- else:
- field_name = name
-
- if IInterface.providedBy(context):
- try:
- method = context[field_name]
- except KeyError:
- raise GrokError("grok.Indexes in %r refers to an attribute or "
- "method %r on interface %r, but this does not "
- "exist." % (module_info.getModule(),
- field_name, context), None)
- call = IMethod.providedBy(method)
- else:
- call = callable(getattr(context, field_name, None))
- context = None # no interface lookup
- catalog[name] = self.index_class(field_name=field_name,
- interface=context,
- field_callable=call,
- *self._args, **self._kw)
-
-class Field(IndexDefinition):
- index_class = FieldIndex
-
-class Text(IndexDefinition):
- index_class = TextIndex
-
-class Set(IndexDefinition):
- index_class = SetIndex
Modified: grokcore.security/trunk/src/grokcore/security/interfaces.py
===================================================================
--- grokcore.security/trunk/src/grokcore/security/interfaces.py 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/interfaces.py 2008-07-28 20:46:10 UTC (rev 88900)
@@ -13,94 +13,16 @@
##############################################################################
"""Grok interfaces
"""
-from zope import interface, schema
-from zope.publisher.interfaces.browser import IBrowserPage, IBrowserView
-from zope.formlib.interfaces import reConstraint
-from zope.interface.interfaces import IInterface
-from zope.viewlet.interfaces import IViewletManager as IViewletManagerBase
-from zope.app.container.interfaces import IContainer as IContainerBase
+from zope.interface import Interface, Attribute
-import grokcore.component.interfaces
+class IBaseClasses(Interface):
+ Permission = Attribute("Base class for permissions.")
-# Expose interfaces from grok.interfaces as well:
-from grokcore.component.interfaces import IContext
-from grokcore.component.interfaces import IGrokErrors
+class IDirectives(Interface):
-class IGrokBaseClasses(grokcore.component.interfaces.IBaseClasses):
- Model = interface.Attribute("Base class for persistent content objects "
- "(models).")
- Container = interface.Attribute("Base class for containers.")
- OrderedContainer = interface.Attribute("Base class for ordered containers.")
- Site = interface.Attribute("Mixin class for sites.")
- Application = interface.Attribute("Base class for applications.")
- Annotation = interface.Attribute("Base class for persistent annotations.")
- LocalUtility = interface.Attribute("Base class for local utilities.")
- View = interface.Attribute("Base class for browser views.")
- XMLRPC = interface.Attribute("Base class for XML-RPC methods.")
- JSON = interface.Attribute("Base class for JSON methods.")
- REST = interface.Attribute("Base class for REST views.")
- Traverser = interface.Attribute("Base class for custom traversers.")
- Form = interface.Attribute("Base class for forms.")
- AddForm = interface.Attribute("Base class for add forms.")
- EditForm = interface.Attribute("Base class for edit forms.")
- DisplayForm = interface.Attribute("Base class for display forms.")
- Indexes = interface.Attribute("Base class for catalog index definitions.")
- Layer = interface.Attribute("Base interface for layers.")
- Skin = interface.Attribute("Base class for skin.")
- ViewletManager = interface.Attribute("Base class for viewletmanager.")
- Viewlet = interface.Attribute("Base class for viewlet.")
- Permission = interface.Attribute("Base class for permissions.")
- Role = interface.Attribute("Base class for roles.")
- Public = interface.Attribute("Marker for explicitly not requiring a permission.")
-
-
-class IGrokDirectives(grokcore.component.interfaces.IDirectives):
-
- def layer(layer):
- """Declare the layer for the view.
-
- This directive acts as a contraint on the 'request' of
- grok.View. This directive can only be used on class level."""
-
- def skin(skin):
- """Declare this layer as a named skin.
-
- This directive can only be used on class level."""
-
- def template(template):
- """Declare the template name for a view.
-
- This directive can only be used on class level."""
-
- def templatedir(directory):
- """Declare a directory to be searched for templates.
-
- By default, grok will take the name of the module as the name
- of the directory. This can be overridden using
- ``templatedir``."""
-
- def local_utility(factory, provides=None, name=u'',
- setup=None, public=False, name_in_container=None):
- """Register a local utility.
-
- factory - the factory that creates the local utility
- provides - the interface the utility should be looked up with
- name - the name of the utility
- setup - a callable that receives the utility as its single argument,
- it is called after the utility has been created and stored
- public - if False, the utility will be stored below ++etc++site
- if True, the utility will be stored directly in the site.
- The site should in this case be a container.
- name_in_container - the name to use for storing the utility
- """
-
- def permissions(permissions):
- """Specify the permissions that comprise a role.
- """
-
def require(permission):
- """Protect a view class or an XMLRPC method with ``permision``.
+ """Protect a view class or an XMLRPC method with ``permission``.
``permission`` must already be defined, e.g. using
grok.Permission.
@@ -108,372 +30,6 @@
grok.require can be used as a class-level directive or as a
method decorator."""
- def site(class_or_interface):
- """Specifies the site that an indexes definition is for.
- It can only be used inside grok.Indexes subclasses.
- """
-
- def order(value=None):
- """Control the ordering of components.
-
- If the value is specified, the order will be determined by sorting on
- it.
- If no value is specified, the order will be determined by definition
- order within the module.
- If the directive is absent, the order will be determined by class name.
- (unfortunately our preferred default behavior on absence which would
- be like grok.order() without argument is hard to implement in Python)
-
- Inter-module order is by dotted name of the module the
- components are in; unless an explicit argument is specified to
- ``grok.order()``, components are grouped by module.
-
- The function grok.util.sort_components can be used to sort
- components according to these rules.
- """
-
-
-class IGrokDecorators(grokcore.component.interfaces.IDecorators):
-
- def action(label, **options):
- """Decorator that defines an action factory based on a form
- method. The method receives the form data as keyword
- parameters."""
-
-
-class IGrokEvents(interface.Interface):
-
- IObjectCreatedEvent = interface.Attribute("")
-
- ObjectCreatedEvent = interface.Attribute("")
-
- IObjectModifiedEvent = interface.Attribute("")
-
- ObjectModifiedEvent = interface.Attribute("")
-
- IObjectCopiedEvent = interface.Attribute("")
-
- ObjectCopiedEvent = interface.Attribute("")
-
- IObjectAddedEvent = interface.Attribute("")
-
- ObjectAddedEvent = interface.Attribute("")
-
- IObjectMovedEvent = interface.Attribute("")
-
- ObjectMovedEvent = interface.Attribute("")
-
- IObjectRemovedEvent = interface.Attribute("")
-
- ObjectRemovedEvent = interface.Attribute("")
-
- IContainerModifiedEvent = interface.Attribute("")
-
- ContainerModifiedEvent = interface.Attribute("")
-
-
-class IGrokAPI(IGrokBaseClasses, IGrokDirectives, IGrokDecorators,
- IGrokEvents, IGrokErrors):
-
- # BBB this is deprecated
- def grok(dotted_name):
- """Grok a module or package specified by ``dotted_name``.
-
- NOTE: This function will be removed from the public Grok
- public API. For tests and interpreter sessions, use
- grok.testing.grok().
- """
-
- # BBB this is deprecated
- def grok_component(name, component, context=None, module_info=None,
- templates=None):
- """Grok an arbitrary object. Can be useful during testing.
-
- name - the name of the component (class name, or global instance name
- as it would appear in a module).
- component - the object (class, etc) to grok.
- context - the context object (optional).
- module_info - the module being grokked (optional).
- templates - the templates registry (optional).
-
- Note that context, module_info and templates might be required
- for some grokkers which rely on them.
-
- NOTE: This function will be removed from the public Grok
- public API. For tests and interpreter sessions, use
- grok.testing.grok_component().
- """
-
- def url(request, obj, name=None, data=None):
- """Generate the URL to an object with optional name attached.
- An optional argument 'data' can be a dictionary that is converted
- into a query string appended to the URL.
- """
-
- def notify(event):
- """Send ``event`` to event subscribers."""
-
- def getSite():
- """Get the current site."""
-
- def PageTemplate(template):
- """Create a Grok PageTemplate object from ``template`` source
- text. This can be used for inline PageTemplates."""
-
- def PageTemplateFile(filename):
- """Create a Grok PageTemplate object from a file specified by
- ``filename``. It will be treated like an inline template
- created with ``PageTemplate``."""
-
- def Fields(*args, **kw):
- """Return a list of formlib fields based on interfaces and/or schema
- fields."""
-
- def AutoFields(context):
- """Return a list of fields for context autogenerated by grok.
- """
-
- def action(label, actions=None, **options):
- """grok-specific action decorator.
- """
-
- IRESTSkinType = interface.Attribute('The REST skin type')
-
-class IGrokView(IBrowserPage, IBrowserView):
- """Grok views all provide this interface."""
-
- context = interface.Attribute('context', "Object that the view presents.")
-
- request = interface.Attribute('request', "Request that the view was looked"
- "up with.")
-
- response = interface.Attribute('response', "Response object that is "
- "associated with the current request.")
-
- static = interface.Attribute('static', "Directory resource containing "
- "the static files of the view's package.")
-
- def redirect(url):
- """Redirect to given URL"""
-
- def url(obj=None, name=None, data=None):
- """Construct URL.
-
- If no arguments given, construct URL to view itself.
-
- If only obj argument is given, construct URL to obj.
-
- If only name is given as the first argument, construct URL
- to context/name.
-
- If both object and name arguments are supplied, construct
- URL to obj/name.
-
- Optionally pass a 'data' keyword argument which gets added to the URL
- as a cgi query string.
- """
-
- def default_namespace():
- """Returns a dictionary of namespaces that the template
- implementation expects to always be available.
-
- This method is *not* intended to be overridden by application
- developers.
- """
-
- def namespace():
- """Returns a dictionary that is injected in the template
- namespace in addition to the default namespace.
-
- This method *is* intended to be overridden by the application
- developer.
- """
-
- def update(**kw):
- """This method is meant to be implemented by grok.View
- subclasses. It will be called *before* the view's associated
- template is rendered and can be used to pre-compute values
- for the template.
-
- update() can take arbitrary keyword parameters which will be
- filled in from the request (in that case they *must* be
- present in the request)."""
-
- def render(**kw):
- """A view can either be rendered by an associated template, or
- it can implement this method to render itself from Python.
- This is useful if the view's output isn't XML/HTML but
- something computed in Python (plain text, PDF, etc.)
-
- render() can take arbitrary keyword parameters which will be
- filled in from the request (in that case they *must* be
- present in the request)."""
-
- def application_url(name=None):
- """Return the URL of the closest application object in the
- hierarchy or the URL of a named object (``name`` parameter)
- relative to the closest application object.
- """
-
- def flash(message, type='message'):
- """Send a short message to the user."""
-
-
-class IGrokForm(IGrokView):
- """Grok form API, inspired by zope.formlib's IFormBaseCustomization.
-
- We explicitly don't inherit from IFormBaseCustomization because
- that would imply ISubPage with another definition of update() and
- render() than IGrokView has.
- """
-
- prefix = schema.ASCII(
- constraint=reConstraint(
- '[a-zA-Z][a-zA-Z0-9_]*([.][a-zA-Z][a-zA-Z0-9_]*)*',
- "Must be a sequence of not-separated identifiers"),
- description=u"""Page-element prefix
-
- All named or identified page elements in a subpage should have
- names and identifiers that begin with a subpage prefix
- followed by a dot.
- """,
- readonly=True,
- )
-
- def setPrefix(prefix):
- """Update the subpage prefix
- """
-
- label = interface.Attribute("A label to display at the top of a form")
-
- status = interface.Attribute(
- """An update status message
-
- This is normally generated by success or failure handlers.
- """)
-
- errors = interface.Attribute(
- """Sequence of errors encountered during validation
- """)
-
- form_result = interface.Attribute(
- """Return from action result method
- """)
-
- form_reset = interface.Attribute(
- """Boolean indicating whether the form needs to be reset
- """)
-
- form_fields = interface.Attribute(
- """The form's form field definitions
-
- This attribute is used by many of the default methods.
- """)
-
- widgets = interface.Attribute(
- """The form's widgets
-
- - set by setUpWidgets
-
- - used by validate
- """)
-
- def setUpWidgets(ignore_request=False):
- """Set up the form's widgets.
-
- The default implementation uses the form definitions in the
- form_fields attribute and setUpInputWidgets.
-
- The function should set the widgets attribute.
- """
-
- def validate(action, data):
- """The default form validator
-
- If an action is submitted and the action doesn't have it's own
- validator then this function will be called.
- """
-
- template = interface.Attribute(
- """Template used to display the form
- """)
-
- def resetForm():
- """Reset any cached data because underlying content may have changed
- """
-
- def error_views():
- """Return views of any errors.
-
- The errors are returned as an iterable.
- """
-
- def applyData(obj, **data):
- """Save form data to an object.
-
- This returns a dictionary with interfaces as keys and lists of
- field names as values to indicate which fields in which
- schemas had to be changed in order to save the data. In case
- the method works in update mode (e.g. on EditForms) and
- doesn't have to update an object, the dictionary is empty.
- """
-
-class IREST(interface.Interface):
- context = interface.Attribute("Object that the REST handler presents.")
-
- request = interface.Attribute("Request that REST handler was looked"
- "up with.")
-
- body = interface.Attribute(
- """The text of the request body.""")
-
-class IApplication(interface.Interface):
- """Marker-interface for grok application factories.
-
- Used to register applications as utilities to look them up and
- provide a list of grokked applications.
- """
-
-class IIndexDefinition(interface.Interface):
- """Define an index for grok.Indexes.
- """
-
- def setup(catalog, name, context):
- """Set up index called name in given catalog.
-
- Use name for index name and attribute to index. Set up
- index for interface or class context.
- """
-
-class IRESTSkinType(IInterface):
- """Skin type for REST requests.
- """
-
-class ITemplateFileFactory(interface.Interface):
- """Utility that generates templates from files in template directories.
- """
-
- def __call__(filename, _prefix=None):
- """Creates an ITemplate from a file
-
- _prefix is the directory the file is located in
- """
-
-class ITemplate(interface.Interface):
- """Template objects
- """
-
- def _initFactory(factory):
- """Template language specific initializations on the view factory."""
-
- def render(view):
- """Renders the template"""
-
-class IContainer(IContext, IContainerBase):
- """A Grok container.
- """
-
-class IViewletManager(IViewletManagerBase):
- """The Grok viewlet manager.
- """
+class IGrokcoreSecurityAPI(IBaseClasses, IDirectives):
+ Public = Attribute("Permission identifier to denote public access.")
Modified: grokcore.security/trunk/src/grokcore/security/meta.py
===================================================================
--- grokcore.security/trunk/src/grokcore/security/meta.py 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/meta.py 2008-07-28 20:46:10 UTC (rev 88900)
@@ -11,454 +11,31 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Grokkers for the various components."""
+"""Grokkers for security-related components."""
-import os
-
-import zope.component.interface
-from zope import interface, component
-from zope.publisher.interfaces.browser import (IDefaultBrowserLayer,
- IBrowserRequest,
- IBrowserPublisher,
- IBrowserSkinType)
-from zope.publisher.interfaces.http import IHTTPRequest
-
-from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
-from zope.viewlet.interfaces import IViewletManager, IViewlet
-from zope.security.interfaces import IPermission
-from zope.securitypolicy.interfaces import IRole
-from zope.securitypolicy.rolepermission import rolePermissionManager
-
-from zope.annotation.interfaces import IAnnotations
-
-from zope.app.publisher.xmlrpc import MethodPublisher
-from zope.app.container.interfaces import IContainer
-from zope.app.container.interfaces import INameChooser
-from zope.app.container.contained import contained
-
-from zope.app.intid import IntIds
-from zope.app.intid.interfaces import IIntIds
-from zope.app.catalog.catalog import Catalog
-from zope.app.catalog.interfaces import ICatalog
-
-from zope.exceptions.interfaces import DuplicationError
-
import martian
+import grokcore.component
+import grokcore.security
+import zope.component
from martian.error import GrokError
-from martian import util
+from zope.security.interfaces import IPermission
-import grok
-from grok import components, formlib, templatereg
-from grok.util import make_checker
-from grok.interfaces import IRESTSkinType
-from grok.interfaces import IViewletManager as IGrokViewletManager
-
-from grokcore.component.scan import determine_module_component
-
-
-def default_view_name(factory, module=None, **data):
- return factory.__name__.lower()
-
def default_fallback_to_name(factory, module, name, **data):
return name
-def default_annotation_provides(factory, module, **data):
- base_interfaces = interface.implementedBy(grok.Annotation)
- factory_interfaces = interface.implementedBy(factory)
- real_interfaces = list(factory_interfaces - base_interfaces)
- util.check_implements_one_from_list(real_interfaces, factory)
- return real_interfaces[0]
-
-def default_annotation_name(factory, module, **data):
- return factory.__module__ + '.' + factory.__name__
-
-
-class ViewletManagerContextGrokker(martian.GlobalGrokker):
-
- martian.priority(1001)
-
- def grok(self, name, module, module_info, config, **kw):
- viewletmanager = determine_module_component(module_info,
- grok.viewletmanager,
- IGrokViewletManager)
- grok.viewletmanager.set(module, viewletmanager)
- return True
-
-
-class XMLRPCGrokker(martian.MethodGrokker):
- martian.component(grok.XMLRPC)
- martian.directive(grok.context)
- martian.directive(grok.require, name='permission')
-
- def execute(self, factory, method, config, context, permission, **kw):
- name = method.__name__
-
- # Make sure that the class inherits MethodPublisher, so that the
- # views have a location
- method_view = type(
- factory.__name__, (factory, MethodPublisher),
- {'__call__': method}
- )
-
- adapts = (context, IXMLRPCRequest)
- config.action(
- discriminator=('adapter', adapts, interface.Interface, name),
- callable=component.provideAdapter,
- args=(method_view, adapts, interface.Interface, name),
- )
- config.action(
- discriminator=('protectName', method_view, '__call__'),
- callable=make_checker,
- args=(factory, method_view, permission),
- )
- return True
-
-
-class RESTGrokker(martian.MethodGrokker):
- martian.component(grok.REST)
- martian.directive(grok.context)
- martian.directive(grok.layer, default=grok.IRESTLayer)
- martian.directive(grok.require, name='permission')
-
- def execute(self, factory, method, config, permission, context, layer, **kw):
- name = method.__name__
-
- method_view = type(
- factory.__name__, (factory,),
- {'__call__': method }
- )
-
- adapts = (context, layer)
- config.action(
- discriminator=('adapter', adapts, interface.Interface, name),
- callable=component.provideAdapter,
- args=(method_view, adapts, interface.Interface, name),
- )
- config.action(
- discriminator=('protectName', method_view, '__call__'),
- callable=make_checker,
- args=(factory, method_view, permission),
- )
- return True
-
-
-class ViewGrokker(martian.ClassGrokker):
- martian.component(grok.View)
- martian.directive(grok.context)
- martian.directive(grok.layer, default=IDefaultBrowserLayer)
- martian.directive(grok.name, get_default=default_view_name)
- martian.directive(grok.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(ViewGrokker, self).grok(name, factory, module_info, **kw)
-
- def execute(self, factory, config, context, layer, name, permission, **kw):
- if util.check_subclass(factory, components.GrokForm):
- # setup form_fields from context class if we've encountered a form
- if getattr(factory, 'form_fields', None) is None:
- factory.form_fields = formlib.get_auto_fields(context)
-
- if not getattr(factory.render, 'base_method', False):
- raise GrokError(
- "It is not allowed to specify a custom 'render' "
- "method for form %r. Forms either use the default "
- "template or a custom-supplied one." % factory,
- factory)
-
- # find templates
- templates = factory.module_info.getAnnotation('grok.templates', None)
- if templates is not None:
- config.action(
- discriminator=None,
- callable=self.checkTemplates,
- args=(templates, factory.module_info, factory)
- )
-
- # 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 grok.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, interface.Interface, name),
- callable=component.provideAdapter,
- args=(factory, adapts, interface.Interface, name),
- )
-
- config.action(
- discriminator=('protectName', factory, '__call__'),
- callable=make_checker,
- args=(factory, factory, permission),
- )
-
- return True
-
- def checkTemplates(self, templates, module_info, factory):
- def has_render(factory):
- return (getattr(factory, 'render', None) and
- not util.check_subclass(factory, grok.components.GrokForm))
- def has_no_render(factory):
- return not getattr(factory, 'render', None)
- templates.checkTemplates(module_info, factory, 'view',
- has_render, has_no_render)
-
-
-class JSONGrokker(martian.MethodGrokker):
- martian.component(grok.JSON)
- martian.directive(grok.context)
- martian.directive(grok.require, name='permission')
-
- # TODO: this grokker doesn't support layers yet
-
- def execute(self, factory, method, config, context, permission, **kw):
- # Create a new class with a __view_name__ attribute so the
- # JSON class knows what method to call.
- method_view = type(
- factory.__name__, (factory,),
- {'__view_name__': method.__name__}
- )
- adapts = (context, IDefaultBrowserLayer)
- name = method.__name__
-
- config.action(
- discriminator=('adapter', adapts, interface.Interface, name),
- callable=component.provideAdapter,
- args=(method_view, adapts, interface.Interface, name),
- )
- config.action(
- discriminator=('protectName', method_view, '__call__'),
- callable=make_checker,
- args=(factory, method_view, permission),
- )
- return True
-
-
-class TraverserGrokker(martian.ClassGrokker):
- martian.component(grok.Traverser)
- martian.directive(grok.context)
-
- def execute(self, factory, config, context, **kw):
- adapts = (context, IHTTPRequest)
- config.action(
- discriminator=('adapter', adapts, IBrowserPublisher, ''),
- callable=component.provideAdapter,
- args=(factory, adapts, IBrowserPublisher),
- )
- return True
-
-
-class TemplateGrokker(martian.GlobalGrokker):
- # this needs to happen before any other grokkers execute that use
- # the template registry
- martian.priority(1001)
-
- def grok(self, name, module, module_info, config, **kw):
- module.__grok_templates__ = templatereg.TemplateRegistry()
- return True
-
-
-class ModulePageTemplateGrokker(martian.InstanceGrokker):
- martian.component(grok.components.BaseTemplate)
- # this needs to happen before any other grokkers execute that actually
- # use the templates
- martian.priority(1000)
-
- def grok(self, name, instance, module_info, config, **kw):
- templates = module_info.getAnnotation('grok.templates', None)
- if templates is None:
- return False
- config.action(
- discriminator=None,
- callable=templates.register,
- args=(name, instance)
- )
- config.action(
- discriminator=None,
- callable=instance._annotateGrokInfo,
- args=(name, module_info.dotted_name)
- )
- return True
-
-
-class FilesystemPageTemplateGrokker(martian.GlobalGrokker):
- # do this early on, but after ModulePageTemplateGrokker, as
- # findFilesystem depends on module-level templates to be
- # already grokked for error reporting
- martian.priority(999)
-
- def grok(self, name, module, module_info, config, **kw):
- templates = module_info.getAnnotation('grok.templates', None)
- if templates is None:
- return False
- config.action(
- discriminator=None,
- callable=templates.findFilesystem,
- args=(module_info,)
- )
- return True
-
-
-class UnassociatedTemplatesGrokker(martian.GlobalGrokker):
- martian.priority(-1001)
-
- def grok(self, name, module, module_info, config, **kw):
- templates = module_info.getAnnotation('grok.templates', None)
- if templates is None:
- return False
-
- config.action(
- discriminator=None,
- callable=templates.checkUnassociated,
- args=(module_info,)
- )
- return True
-
-
-class StaticResourcesGrokker(martian.GlobalGrokker):
-
- def grok(self, name, module, module_info, config, **kw):
- # we're only interested in static resources if this module
- # happens to be a package
- if not module_info.isPackage():
- return False
-
- resource_path = module_info.getResourcePath('static')
- if os.path.isdir(resource_path):
- static_module = module_info.getSubModuleInfo('static')
- if static_module is not None:
- if static_module.isPackage():
- raise GrokError(
- "The 'static' resource directory must not "
- "be a python package.",
- module_info.getModule())
- else:
- raise GrokError(
- "A package can not contain both a 'static' "
- "resource directory and a module named "
- "'static.py'", module_info.getModule())
-
- resource_factory = components.DirectoryResourceFactory(
- resource_path, module_info.dotted_name)
- adapts = (IDefaultBrowserLayer,)
- provides = interface.Interface
- name = module_info.dotted_name
- config.action(
- discriminator=('adapter', adapts, provides, name),
- callable=component.provideAdapter,
- args=(resource_factory, adapts, provides, name),
- )
- return True
-
-
-class SiteGrokker(martian.ClassGrokker):
- martian.component(grok.Site)
- martian.priority(500)
- martian.directive(grok.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, grok.IObjectAddedEvent)
-
- config.action(
- discriminator=None,
- callable=component.provideHandler,
- args=(localUtilityRegistrationSubscriber, adapts),
- )
- return True
-
-
-def localUtilityRegistrationSubscriber(site, event):
- """A subscriber that fires to set up local utilities.
- """
- installed = getattr(site, '__grok_utilities_installed__', False)
- if installed:
- return
-
- for info in getattr(site.__class__, '__grok_utilities_to_install__', []):
- setupUtility(site, info.factory(), info.provides, name=info.name,
- name_in_container=info.name_in_container,
- public=info.public, setup=info.setup)
-
- # we are done. If this subscriber gets fired again, we therefore
- # do not register utilities anymore
- site.__grok_utilities_installed__ = True
-
-
-def setupUtility(site, utility, provides, name=u'',
- name_in_container=None, public=False, setup=None):
- """Set up a utility in a site.
-
- site - the site to set up the utility in
- utility - the utility to set up
- provides - the interface the utility should be registered with
- name - the name the utility should be registered under, default
- the empty string (no name)
- name_in_container - if given it will be used to add the utility
- object to its container. Otherwise a name will be made up
- public - if False, the utility will be stored in the site manager. If
- True, the utility will be storedin the site (it is assumed the
- site is a container)
- setup - if not None, it will be called with the utility as its first
- argument. This function can then be used to further set up the
- utility.
- """
- site_manager = site.getSiteManager()
-
- if not public:
- container = site_manager
- else:
- container = site
-
- if name_in_container is None:
- name_in_container = INameChooser(container).chooseName(
- utility.__class__.__name__, utility)
- container[name_in_container] = utility
-
- if setup is not None:
- setup(utility)
-
- site_manager.registerUtility(utility, provided=provides,
- name=name)
-
-
-class PermissionGrokker(martian.ClassGrokker):
- martian.component(grok.Permission)
+class PermissionGrokker(martian.ClassGrokcore.Securityker):
+ martian.component(grokcore.security.Permission)
martian.priority(1500)
- martian.directive(grok.name)
- martian.directive(grok.title, get_default=default_fallback_to_name)
- martian.directive(grok.description)
+ 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)
+ "grokcore.security.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),
@@ -466,293 +43,8 @@
config.action(
discriminator=('utility', IPermission, name),
- callable=component.provideUtility,
+ callable=zope.component.provideUtility,
args=(permission, IPermission, name),
order=-1 # need to do this early in the process
)
return True
-
-
-class RoleGrokker(martian.ClassGrokker):
- martian.component(grok.Role)
- martian.priority(martian.priority.bind().get(PermissionGrokker()) - 1)
- martian.directive(grok.name)
- martian.directive(grok.title, get_default=default_fallback_to_name)
- martian.directive(grok.description)
- martian.directive(grok.permissions)
-
- def execute(self, factory, config, name, title, description,
- permissions, **kw):
- if not name:
- raise GrokError(
- "A role 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 makes sure
- # it is either unicode already or ASCII.
- role = factory(unicode(name), unicode(title), unicode(description))
-
- config.action(
- discriminator=('utility', IRole, name),
- callable=component.provideUtility,
- args=(role, IRole, name),
- )
-
- for permission in permissions:
- config.action(
- discriminator=('grantPermissionToRole', permission, name),
- callable=rolePermissionManager.grantPermissionToRole,
- args=(permission, name),
- )
- return True
-
-
-class AnnotationGrokker(martian.ClassGrokker):
- martian.component(grok.Annotation)
- martian.directive(grok.context, name='adapter_context')
- martian.directive(grok.provides, get_default=default_annotation_provides)
- martian.directive(grok.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
-
- # Containment has to be set up late to allow containment
- # proxies to be applied, if needed. This does not trigger
- # an event and is idempotent if containment is set up
- # already.
- contained_result = contained(result, context, name)
- return contained_result
-
- config.action(
- discriminator=('adapter', adapter_context, provides, ''),
- callable=component.provideAdapter,
- args=(getAnnotation,),
- )
- return True
-
-
-class ApplicationGrokker(martian.ClassGrokker):
- martian.component(grok.Application)
- martian.priority(500)
-
- def grok(self, name, factory, module_info, config, **kw):
- # XXX fail loudly if the same application name is used twice.
- provides = grok.interfaces.IApplication
- name = '%s.%s' % (module_info.dotted_name, name)
- config.action(
- discriminator=('utility', provides, name),
- callable=component.provideUtility,
- args=(factory, provides, name),
- )
- return True
-
-
-class IndexesGrokker(martian.InstanceGrokker):
- martian.component(components.IndexesClass)
-
- def grok(self, name, factory, module_info, config, **kw):
- site = grok.site.bind().get(factory)
- context = grok.context.bind().get(factory, module_info.getModule())
- catalog_name = grok.name.bind().get(factory)
-
- if site is None:
- raise GrokError("No site specified for grok.Indexes "
- "subclass in module %r. "
- "Use grok.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, grok.IObjectAddedEvent)
- config.action(
- discriminator=None,
- callable=component.provideHandler,
- args=(subscriber, subscribed),
- )
- return True
-
-
-class IndexesSetupSubscriber(object):
-
- def __init__(self, catalog_name, indexes, context, module_info):
- self.catalog_name = catalog_name
- self.indexes = indexes
- self.context = context
- self.module_info = module_info
-
- def __call__(self, site, event):
- # make sure we have an intids
- self._createIntIds(site)
- # get the catalog
- catalog = self._createCatalog(site)
- # now install indexes
- for name, index in self.indexes.items():
- try:
- index.setup(catalog, name, self.context, self.module_info)
- except DuplicationError:
- raise GrokError(
- "grok.Indexes in module %r causes "
- "creation of catalog index %r in catalog %r, "
- "but an index with that name is already present." %
- (self.module_info.getModule(), name, self.catalog_name),
- None)
-
- def _createCatalog(self, site):
- """Create the catalog if needed and return it.
-
- If the catalog already exists, return that.
-
- """
- catalog = zope.component.queryUtility(
- ICatalog, name=self.catalog_name, context=site, default=None)
- if catalog is not None:
- return catalog
- catalog = Catalog()
- setupUtility(site, catalog, ICatalog, name=self.catalog_name)
- return catalog
-
- def _createIntIds(self, site):
- """Create intids if needed, and return it.
- """
- intids = zope.component.queryUtility(
- IIntIds, context=site, default=None)
- if intids is not None:
- return intids
- intids = IntIds()
- setupUtility(site, intids, IIntIds)
- return intids
-
-
-class SkinGrokker(martian.ClassGrokker):
- martian.component(grok.Skin)
- martian.directive(grok.layer, default=IBrowserRequest)
- martian.directive(grok.name, get_default=default_view_name)
-
- def execute(self, factory, config, name, layer, **kw):
- config.action(
- discriminator=('skin', name),
- callable=zope.component.interface.provideInterface,
- args=(name, layer, IBrowserSkinType)
- )
- return True
-
-class RESTProtocolGrokker(martian.ClassGrokker):
- martian.component(grok.RESTProtocol)
- martian.directive(grok.layer, default=IBrowserRequest)
- martian.directive(grok.name, get_default=default_view_name)
-
- def execute(self, factory, config, name, layer, **kw):
- config.action(
- discriminator=('restprotocol', name),
- callable=zope.component.interface.provideInterface,
- args=(name, layer, IRESTSkinType)
- )
- return True
-
-class ViewletManagerGrokker(martian.ClassGrokker):
- martian.component(grok.ViewletManager)
- martian.directive(grok.context)
- martian.directive(grok.layer, default=IDefaultBrowserLayer)
- martian.directive(grok.view)
- martian.directive(grok.name)
-
- 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(ViewletManagerGrokker, self).grok(
- name, factory, module_info, **kw)
-
- def execute(self, factory, config, context, layer, view, name, **kw):
- # This will be used to support __name__ on the viewlet manager
- factory.__view_name__ = name
-
- # find templates
- templates = factory.module_info.getAnnotation('grok.templates', None)
- if templates is not None:
- config.action(
- discriminator=None,
- callable=self.checkTemplates,
- args=(templates, factory.module_info, factory)
- )
-
- config.action(
- discriminator = ('viewletManager', context, layer, view, name),
- callable = component.provideAdapter,
- args = (factory, (context, layer, view), IViewletManager, name)
- )
- return True
-
- def checkTemplates(self, templates, module_info, factory):
- def has_render(factory):
- return factory.render != grok.components.ViewletManager.render
- def has_no_render(factory):
- # always has a render method
- return False
- templates.checkTemplates(module_info, factory, 'viewlet manager',
- has_render, has_no_render)
-
-class ViewletGrokker(martian.ClassGrokker):
- martian.component(grok.Viewlet)
- martian.directive(grok.context)
- martian.directive(grok.layer, default=IDefaultBrowserLayer)
- martian.directive(grok.view)
- martian.directive(grok.viewletmanager)
- martian.directive(grok.name, get_default=default_view_name)
- martian.directive(grok.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(ViewletGrokker, self).grok(
- name, factory, module_info, **kw)
-
- def execute(self, factory, config,
- context, layer, view, viewletmanager, name, permission, **kw):
- # This will be used to support __name__ on the viewlet
- factory.__view_name__ = name
-
- # find templates
- templates = factory.module_info.getAnnotation('grok.templates', None)
- if templates is not None:
- config.action(
- discriminator=None,
- callable=self.checkTemplates,
- args=(templates, factory.module_info, factory)
- )
-
- config.action(
- discriminator = ('viewlet', context, layer,
- view, viewletmanager, name),
- callable = component.provideAdapter,
- args = (factory, (context, layer, view, viewletmanager),
- IViewlet, name)
- )
-
- config.action(
- discriminator=('protectName', factory, '__call__'),
- callable=make_checker,
- args=(factory, factory, permission, ['update', 'render']),
- )
-
- return True
-
- def checkTemplates(self, templates, module_info, factory):
- def has_render(factory):
- return factory.render != grok.components.Viewlet.render
- def has_no_render(factory):
- return not has_render(factory)
- templates.checkTemplates(module_info, factory, 'viewlet',
- has_render, has_no_render)
Modified: grokcore.security/trunk/src/grokcore/security/meta.zcml
===================================================================
--- grokcore.security/trunk/src/grokcore/security/meta.zcml 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/meta.zcml 2008-07-28 20:46:10 UTC (rev 88900)
@@ -1,10 +1,7 @@
<configure
xmlns="http://namespaces.zope.org/zope"
- xmlns:meta="http://namespaces.zope.org/meta"
xmlns:grok="http://namespaces.zope.org/grok">
- <include package="z3c.autoinclude" file="meta.zcml" />
-
<!-- Load the grokkers -->
<include package="grokcore.component" file="meta.zcml" />
<grok:grok package=".meta" />
Deleted: grokcore.security/trunk/src/grokcore/security/publication.py
===================================================================
--- grokcore.security/trunk/src/grokcore/security/publication.py 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/publication.py 2008-07-28 20:46:10 UTC (rev 88900)
@@ -1,90 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Grok publication objects
-"""
-
-from grok.rest import GrokMethodNotAllowed
-
-from zope import component
-from zope.security.proxy import removeSecurityProxy
-from zope.security.checker import selectChecker
-from zope.publisher.publish import mapply
-
-from zope.app.publication.http import BaseHTTPPublication, HTTPPublication
-from zope.app.publication.browser import BrowserPublication
-from zope.app.publication.requestpublicationfactories import \
- BrowserFactory, XMLRPCFactory, HTTPFactory
-from zope.app.http.interfaces import IHTTPException
-
-class ZopePublicationSansProxy(object):
-
- def getApplication(self, request):
- result = super(ZopePublicationSansProxy, self).getApplication(request)
- return removeSecurityProxy(result)
-
- def traverseName(self, request, ob, name):
- result = super(ZopePublicationSansProxy, self).traverseName(
- request, ob, name)
- return removeSecurityProxy(result)
-
- def callObject(self, request, ob):
- checker = selectChecker(ob)
- if checker is not None:
- checker.check(ob, '__call__')
- return super(ZopePublicationSansProxy, self).callObject(request, ob)
-
-
-class GrokBrowserPublication(ZopePublicationSansProxy, BrowserPublication):
-
- def getDefaultTraversal(self, request, ob):
- obj, path = super(GrokBrowserPublication, self).getDefaultTraversal(
- request, ob)
- return removeSecurityProxy(obj), path
-
-
-class GrokBrowserFactory(BrowserFactory):
-
- def __call__(self):
- request, publication = super(GrokBrowserFactory, self).__call__()
- return request, GrokBrowserPublication
-
-
-class GrokXMLRPCPublication(ZopePublicationSansProxy, BaseHTTPPublication):
- pass
-
-class GrokXMLRPCFactory(XMLRPCFactory):
-
- def __call__(self):
- request, publication = super(GrokXMLRPCFactory, self).__call__()
- return request, GrokXMLRPCPublication
-
-
-class GrokHTTPPublication(ZopePublicationSansProxy, HTTPPublication):
- def callObject(self, request, ob):
- orig = ob
- if not IHTTPException.providedBy(ob):
- ob = component.queryMultiAdapter((ob, request),
- name=request.method)
- checker = selectChecker(ob)
- if checker is not None:
- checker.check(ob, '__call__')
- ob = getattr(ob, request.method, None)
- if ob is None:
- raise GrokMethodNotAllowed(orig, request)
- return mapply(ob, request.getPositionalArguments(), request)
-
-class GrokHTTPFactory(HTTPFactory):
- def __call__(self):
- request, publication = super(GrokHTTPFactory, self).__call__()
- return request, GrokHTTPPublication
Deleted: grokcore.security/trunk/src/grokcore/security/rest.py
===================================================================
--- grokcore.security/trunk/src/grokcore/security/rest.py 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/rest.py 2008-07-28 20:46:10 UTC (rev 88900)
@@ -1,86 +0,0 @@
-import grok
-
-from zope import component
-from zope.component.interfaces import ComponentLookupError
-
-from zope.traversing.interfaces import TraversalError
-from zope.traversing.namespace import view
-from zope.interface import Interface
-from zope.interface.interfaces import IInterface
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.publisher.interfaces.http import IHTTPRequest
-from zope.app.publication.http import MethodNotAllowed
-
-from grok.interfaces import IRESTSkinType
-from zope.publisher.browser import applySkin
-
-class GrokMethodNotAllowed(MethodNotAllowed):
- pass
-
-class MethodNotAllowedView(grok.MultiAdapter):
- grok.adapts(GrokMethodNotAllowed, IHTTPRequest)
- grok.name('index.html')
- grok.implements(Interface)
-
- def __init__(self, error, request):
- self.error = error
- self.request = request
- self.allow = self._getAllow()
-
- def _getAllow(self):
- allow = []
- for method in ['GET', 'PUT', 'POST', 'DELETE']:
- view = component.queryMultiAdapter(
- (self.error.object, self.error.request),
- name=method)
- if view is not None:
- is_not_allowed = getattr(view, 'is_not_allowed', False)
- if not is_not_allowed:
- allow.append(method)
- allow.sort()
- return allow
-
- def __call__(self):
- self.request.response.setHeader('Allow', ', '.join(self.allow))
- self.request.response.setStatus(405)
- return 'Method Not Allowed'
-
-class rest_skin(view):
- """A rest skin.
-
- This used to be supported by zope.traversing but the change was backed out.
- We need it for our REST support.
- """
- def traverse(self, name, ignored):
- self.request.shiftNameToApplication()
- try:
- skin = component.getUtility(IRESTSkinType, name)
- except ComponentLookupError:
- raise TraversalError("++rest++%s" % name)
- applySkin(self.request, skin)
- return self.context
-
-
-class NotAllowedREST(grok.REST):
- """These are registered for everything by default to cause the correct
- errors.
-
- Any more specific REST view overrides this.
- """
- grok.layer(grok.IRESTLayer)
- grok.context(Interface)
-
- is_not_allowed = True
-
- def GET(self):
- raise GrokMethodNotAllowed(self.context, self.request)
-
- def POST(self):
- raise GrokMethodNotAllowed(self.context, self.request)
-
- def PUT(self):
- raise GrokMethodNotAllowed(self.context, self.request)
-
- def DELETE(self):
- raise GrokMethodNotAllowed(self.context, self.request)
-
Deleted: grokcore.security/trunk/src/grokcore/security/templatereg.py
===================================================================
--- grokcore.security/trunk/src/grokcore/security/templatereg.py 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/templatereg.py 2008-07-28 20:46:10 UTC (rev 88900)
@@ -1,131 +0,0 @@
-from martian.error import GrokError
-from martian import util
-
-import os
-import zope.component
-import grok
-import warnings
-
-class TemplateRegistry(object):
-
- def __init__(self):
- self._reg = {}
-
- def register(self, name, template):
- self._reg[name] = dict(template=template, associated=False)
-
- def markAssociated(self, name):
- self._reg[name]['associated'] = True
-
- def get(self, name):
- entry = self._reg.get(name)
- if entry is None:
- return None
- return entry['template']
-
- def findFilesystem(self, module_info):
- template_dir_name = grok.templatedir.bind().get(
- module=module_info.getModule())
- if template_dir_name is None:
- template_dir_name = module_info.name + '_templates'
-
- template_dir = module_info.getResourcePath(template_dir_name)
-
- if not os.path.isdir(template_dir):
- return
-
- if module_info.isPackage():
- return
-
- for template_file in os.listdir(template_dir):
- if template_file.startswith('.') or template_file.endswith('~'):
- continue
-
- template_name, extension = os.path.splitext(template_file)
- extension = extension[1:] # Get rid of the leading dot.
- template_factory = zope.component.queryUtility(
- grok.interfaces.ITemplateFileFactory,
- name=extension)
-
- if template_factory is None:
- # Warning when importing files. This should be
- # allowed because people may be using editors that generate
- # '.bak' files and such.
- warnings.warn("File '%s' has an unrecognized extension in "
- "directory '%s'" %
- (template_file, template_dir), UserWarning, 2)
- continue
-
- inline_template = self.get(template_name)
- if inline_template:
- raise GrokError("Conflicting templates found for name '%s' "
- "in module %r, either inline and in template "
- "directory '%s', or two templates with the "
- "same name and different extensions."
- % (template_name, module_info.getModule(),
- template_dir), inline_template)
-
- template = template_factory(template_file, template_dir)
- template_path = os.path.join(template_dir, template_file)
- template._annotateGrokInfo(template_name, template_path)
-
- self.register(template_name, template)
-
- def listUnassociated(self):
- for name, entry in self._reg.iteritems():
- if not entry['associated']:
- yield name
-
- def checkUnassociated(self, module_info):
- unassociated = list(self.listUnassociated())
- if unassociated:
- msg = (
- "Found the following unassociated template(s) when "
- "grokking %r: %s. Define view classes inheriting "
- "from grok.View to enable the template(s)." % (
- module_info.dotted_name, ', '.join(unassociated)))
- warnings.warn(msg, UserWarning, 1)
-
- def checkTemplates(self, module_info, factory, component_name,
- has_render, has_no_render):
- factory_name = factory.__name__.lower()
- template_name = grok.template.bind().get(factory)
- if template_name is None:
- template_name = factory_name
-
- if factory_name != template_name:
- # grok.template is being used
-
- if self.get(factory_name):
- raise GrokError("Multiple possible templates for %s %r. It "
- "uses grok.template('%s'), but there is also "
- "a template called '%s'."
- % (component_name, factory, template_name,
- factory_name), factory)
- template = self.get(template_name)
- if template is not None:
- if has_render(factory):
- # we do not accept render and template both for a view
- # (unless it's a form, they happen to have render.
- raise GrokError(
- "Multiple possible ways to render %s %r. "
- "It has both a 'render' method as well as "
- "an associated template." %
- (component_name, factory), factory)
- self.markAssociated(template_name)
- factory.template = template
- template._initFactory(factory)
- else:
- if has_no_render(factory):
- # we do not accept a view without any way to render it
- raise GrokError("%s %r has no associated template or "
- "'render' method." %
- (component_name.title(), factory), factory)
-
-class PageTemplateFileFactory(grok.GlobalUtility):
-
- grok.implements(grok.interfaces.ITemplateFileFactory)
- grok.name('pt')
-
- def __call__(self, filename, _prefix=None):
- return grok.components.PageTemplate(filename=filename, _prefix=_prefix)
Modified: grokcore.security/trunk/src/grokcore/security/testing.py
===================================================================
--- grokcore.security/trunk/src/grokcore/security/testing.py 2008-07-28 20:29:08 UTC (rev 88899)
+++ grokcore.security/trunk/src/grokcore/security/testing.py 2008-07-28 20:46:10 UTC (rev 88900)
@@ -13,66 +13,12 @@
##############################################################################
"""Grok test helpers
"""
-import sys
-import os.path
-import z3c.testsetup
from zope.configuration.config import ConfigurationMachine
from grokcore.component import zcml
-# Provide this import here for BBB reasons:
-from grokcore.component.testing import grok_component
-class GrokTestCollector(z3c.testsetup.TestCollector):
-
- def initialize(self):
- # inject the grok ftesting ZCML as fallback...
- if 'zcml_config' in self.settings.keys():
- return
- pkg_path = os.path.dirname(self.package.__file__)
- if os.path.isfile(os.path.join(pkg_path, 'ftesting.zcml')):
- return
- self.settings['zcml_config'] = os.path.join(
- os.path.dirname(__file__), 'ftesting.zcml')
- if 'layer_name' in self.settings.keys():
- return
- self.settings['layer_name'] = 'GrokFunctionalLayer'
-
-def register_all_tests(pkg, *args, **kw):
- return GrokTestCollector(pkg, *args, **kw)
-
def grok(module_name):
config = ConfigurationMachine()
zcml.do_grok('grokcore.component.meta', config)
- zcml.do_grok('grok.meta', config)
- zcml.do_grok('grok.templatereg', config)
+ zcml.do_grok('grokcore.security.meta', config)
zcml.do_grok(module_name, config)
config.execute_actions()
-
-def warn(message, category=None, stacklevel=1):
- """Intended to replace warnings.warn in tests.
-
- Modified copy from zope.deprecation.tests to:
-
- * make the signature identical to warnings.warn
- * to check for *.pyc and *.pyo files.
-
- When zope.deprecation is fixed, this warn function can be removed again.
- """
- print "From grok.testing's warn():"
-
- frame = sys._getframe(stacklevel)
- path = frame.f_globals['__file__']
- if path.endswith('.pyc') or path.endswith('.pyo'):
- path = path[:-1]
-
- file = open(path)
- lineno = frame.f_lineno
- for i in range(lineno):
- line = file.readline()
-
- print "%s:%s: %s: %s\n %s" % (
- path,
- frame.f_lineno,
- category.__name__,
- message,
- line.strip(),
- )
More information about the Checkins
mailing list