[Checkins] SVN: grok/trunk/src/grok/publication.py Added module and class docstrings to publication.py.
Brandon Rhodes
brandon at rhodesmill.org
Sat Dec 13 08:33:28 EST 2008
Log message for revision 94015:
Added module and class docstrings to publication.py.
Changed:
U grok/trunk/src/grok/publication.py
-=-
Modified: grok/trunk/src/grok/publication.py
===================================================================
--- grok/trunk/src/grok/publication.py 2008-12-13 11:13:37 UTC (rev 94014)
+++ grok/trunk/src/grok/publication.py 2008-12-13 13:33:27 UTC (rev 94015)
@@ -11,9 +11,18 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Grok publication objects
+"""Grok publication factories and classes.
+
+These factories, and the publication classes they return, make Grok
+security different from the way that security normal operates during
+Zope publication. Instead of security proxies being wrapped around
+every object generated during traversal, and then wrapped around the
+final object before it is viewed, only a single security check is done
+when Grok is in charge: a check to see whether the view selected at the
+end of the traversal process is, in fact, permitted to display the
+object.
+
"""
-
from grok.rest import GrokMethodNotAllowed
from zope import component
@@ -33,7 +42,27 @@
from grok.components import JSON
class ZopePublicationSansProxy(object):
+ """Grok mixin that makes a publisher remove security proxies.
+ This mixin overrides three methods from the `IPublication` interface
+ (defined in `zope.publisher.interfaces`) to alter their security
+ behavior. The normal Zope machinery wraps a security proxy around
+ the application object returned by `getApplication()`, and around
+ each of the objects returned as `traverseName()` is then called for
+ each URL component. The versions here strip the security proxy off
+ instead, returning the bare object (unless the object is a non-Grok
+ view, in which case we leave the proxy installed for important
+ security reasons). Finally, when `callObject()` is asked to render
+ the view, we quickly re-install a security proxy on the object, make
+ sure that the current user is indeed allowed to invoke `__call__()`,
+ then pass the bare object to the rendering machinery.
+
+ The result is that, in place of the elaborate series of security
+ checks made during the processing of a normal Zope request, Grok
+ makes only a single security check: to see if the view can be
+ permissibly rendered or not.
+
+ """
def getApplication(self, request):
result = super(ZopePublicationSansProxy, self).getApplication(request)
return removeSecurityProxy(result)
@@ -58,45 +87,89 @@
class GrokBrowserPublication(ZopePublicationSansProxy, BrowserPublication):
+ """Combines `BrowserPublication` with the Grok sans-proxy mixin.
+ In addition to the three methods that are overridden by the
+ `ZopePublicationSansProxy`, this class overrides a fourth: the
+ `getDefaultTraversal()` method, which strips the security proxy from
+ the object being returned by the normal method.
+
+ """
def getDefaultTraversal(self, request, ob):
obj, path = super(GrokBrowserPublication, self).getDefaultTraversal(
request, ob)
return removeSecurityProxy(obj), path
-
class GrokBrowserFactory(BrowserFactory):
+ """Returns the classes Grok uses for browser requests and publication.
+ When an instance of this class is called, it returns a 2-element
+ tuple containing:
+
+ - The request class that Grok uses for browser requests.
+ - The publication class that Grok uses to publish to a browser.
+
+ """
def __call__(self):
request, publication = super(GrokBrowserFactory, self).__call__()
return request, GrokBrowserPublication
class GrokXMLRPCPublication(ZopePublicationSansProxy, BaseHTTPPublication):
- pass
+ """Combines `BaseHTTPPublication` with the Grok sans-proxy mixin."""
class GrokXMLRPCFactory(XMLRPCFactory):
+ """Returns the classes Grok uses for browser requests and publication.
+ When an instance of this class is called, it returns a 2-element
+ tuple containing:
+
+ - The request class that Grok uses for XML-RPC requests.
+ - The publication class that Grok uses to publish to a XML-RPC.
+
+ """
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),
+ """Combines `HTTPPublication` with the Grok sans-proxy mixin.
+
+ Because `HTTPPublication` provides its own, special `callObject()`
+ implementation, this subclass does the same, providing what is
+ basically the same call (you can verify, in fact, that most of its
+ lines were copied directly from the superclass's version) but with a
+ few extra lines added so that - as with the simpler `callObject()`
+ method in `ZopePublicationSansProxy` - it quickly places a security
+ proxy around the object, makes sure that this HTTP method is
+ permitted, and finally passes the bare object to the view that will
+ render it.
+
+ """
+ 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)
+ 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):
+ """Returns the classes Grok uses for HTTP requests and publication.
+
+ When an instance of this class is called, it returns a 2-element
+ tuple containing:
+
+ - The request class that Grok uses for HTTP requests.
+ - The publication class that Grok uses to publish to HTTP.
+
+ """
def __call__(self):
request, publication = super(GrokHTTPFactory, self).__call__()
return request, GrokHTTPPublication
More information about the Checkins
mailing list