[Zope-Checkins]
SVN: Zope/branches/easter-sprint_traversal-refactor/lib/python/ZPublisher/BaseRequest.py
Step 1: Refactoring the traversl into something less monolithic.
Lennart Regebro
regebro at gmail.com
Tue Apr 18 13:55:24 EDT 2006
Log message for revision 67081:
Step 1: Refactoring the traversl into something less monolithic.
Changed:
U Zope/branches/easter-sprint_traversal-refactor/lib/python/ZPublisher/BaseRequest.py
-=-
Modified: Zope/branches/easter-sprint_traversal-refactor/lib/python/ZPublisher/BaseRequest.py
===================================================================
--- Zope/branches/easter-sprint_traversal-refactor/lib/python/ZPublisher/BaseRequest.py 2006-04-18 16:48:55 UTC (rev 67080)
+++ Zope/branches/easter-sprint_traversal-refactor/lib/python/ZPublisher/BaseRequest.py 2006-04-18 17:55:23 UTC (rev 67081)
@@ -16,7 +16,7 @@
"""
from urllib import quote
import xmlrpc
-from zExceptions import Forbidden
+from zExceptions import Forbidden, Unauthorized
from zope.event import notify
from zope.app.publication.interfaces import EndRequestEvent
@@ -184,6 +184,56 @@
__repr__=__str__
+ def traverseName(self, object, entry_name):
+ got = 0
+ URL=self['URL']
+ if entry_name[:1]=='_':
+ raise Forbidden("Object name begins with an underscore at: %s" % URL)
+
+ if hasattr(object,'__bobo_traverse__'):
+ subobject=object.__bobo_traverse__(self,entry_name)
+ if type(subobject) is type(()) and len(subobject) > 1:
+ # Add additional parents into the path
+ parents[-1:] = list(subobject[:-1])
+ object, subobject = subobject[-2:]
+ else:
+ try:
+ subobject=getattr(object, entry_name)
+ except AttributeError:
+ got=1
+ subobject=object[entry_name]
+
+ # Ensure that the object has a docstring, or that the parent
+ # object has a pseudo-docstring for the object. Objects that
+ # have an empty or missing docstring are not published.
+ doc = getattr(subobject, '__doc__', None)
+ if doc is None:
+ doc = getattr(object, '%s__doc__' % entry_name, None)
+ if not doc:
+ raise Forbidden(
+ "The object at %s has an empty or missing " \
+ "docstring. Objects must have a docstring to be " \
+ "published." % URL
+ )
+
+ # Hack for security: in Python 2.2.2, most built-in types
+ # gained docstrings that they didn't have before. That caused
+ # certain mutable types (dicts, lists) to become publishable
+ # when they shouldn't be. The following check makes sure that
+ # the right thing happens in both 2.2.2+ and earlier versions.
+
+ if not typeCheck(subobject):
+ raise Forbidden(
+ "The object at %s is not publishable." % URL
+ )
+
+ self.roles = getRoles(
+ object, (not got) and entry_name or None, subobject,
+ self.roles)
+ print self.roles
+ return subobject
+
+
def traverse(self, path, response=None, validated_hook=None):
"""Traverse the object space
@@ -193,7 +243,6 @@
request=self
request_get=request.get
if response is None: response=self.response
- debug_mode=response.debug_mode
# remember path for later use
browser_path = path
@@ -235,14 +284,14 @@
object=parents[-1]
del parents[:]
- roles = getRoles(None, None, object, UNSPECIFIED_ROLES)
+ self.roles = getRoles(None, None, object, UNSPECIFIED_ROLES)
# if the top object has a __bobo_traverse__ method, then use it
# to possibly traverse to an alternate top-level object.
if hasattr(object,'__bobo_traverse__'):
try:
object=object.__bobo_traverse__(request)
- roles = getRoles(None, None, object, UNSPECIFIED_ROLES)
+ self.roles = getRoles(None, None, object, UNSPECIFIED_ROLES)
except: pass
if not path and not method:
@@ -302,8 +351,8 @@
method = 'index_html'
else:
if (hasattr(object, '__call__')):
- roles = getRoles(object, '__call__', object.__call__,
- roles)
+ self.roles = getRoles(object, '__call__', object.__call__,
+ self.roles)
if request._hacked_path:
i=URL.rfind('/')
if i > 0: response.setBase(URL[:i])
@@ -311,91 +360,45 @@
step = quote(entry_name)
_steps.append(step)
request['URL'] = URL = '%s/%s' % (request['URL'], step)
- got = 0
- if entry_name[:1]=='_':
- if debug_mode:
+
+ try:
+ object = self.traverseName(object, entry_name)
+ except (KeyError, AttributeError):
+ if response.debug_mode:
return response.debugError(
- "Object name begins with an underscore at: %s" % URL)
- else: return response.forbiddenError(entry_name)
+ "Cannot locate object at: %s" % URL)
+ else:
+ return response.notFoundError(URL)
+ except Forbidden, e:
+ if self.response.debug_mode:
+ return response.debugError(e.args)
+ else:
+ return response.forbiddenError(entry_name)
+
- if hasattr(object,'__bobo_traverse__'):
- try:
- subobject=object.__bobo_traverse__(request,entry_name)
- if type(subobject) is type(()) and len(subobject) > 1:
- # Add additional parents into the path
- parents[-1:] = list(subobject[:-1])
- object, subobject = subobject[-2:]
- except (AttributeError, KeyError):
- if debug_mode:
- return response.debugError(
- "Cannot locate object at: %s" % URL)
- else:
- return response.notFoundError(URL)
- else:
- try:
- # Note - no_acquire_flag is necessary to support
- # things like DAV. We have to make sure
- # that the target object is not acquired
- # if the request_method is other than GET
- # or POST. Otherwise, you could never use
- # PUT to add a new object named 'test' if
- # an object 'test' existed above it in the
- # heirarchy -- you'd always get the
- # existing object :(
-
- if (no_acquire_flag and len(path) == 0 and
- hasattr(object, 'aq_base')):
- if hasattr(object.aq_base, entry_name):
- subobject=getattr(object, entry_name)
- else: raise AttributeError, entry_name
- else: subobject=getattr(object, entry_name)
- except AttributeError:
- got=1
- try: subobject=object[entry_name]
- except (KeyError, IndexError,
- TypeError, AttributeError):
- if debug_mode:
- return response.debugError(
- "Cannot locate object at: %s" % URL)
- else:
- return response.notFoundError(URL)
-
- # Ensure that the object has a docstring, or that the parent
- # object has a pseudo-docstring for the object. Objects that
- # have an empty or missing docstring are not published.
- doc = getattr(subobject, '__doc__', None)
- if doc is None:
- doc = getattr(object, '%s__doc__' % entry_name, None)
- if not doc:
- return response.debugError(
- "The object at %s has an empty or missing " \
- "docstring. Objects must have a docstring to be " \
- "published." % URL
- )
-
- # Hack for security: in Python 2.2.2, most built-in types
- # gained docstrings that they didn't have before. That caused
- # certain mutable types (dicts, lists) to become publishable
- # when they shouldn't be. The following check makes sure that
- # the right thing happens in both 2.2.2+ and earlier versions.
-
- if not typeCheck(subobject):
- return response.debugError(
- "The object at %s is not publishable." % URL
- )
-
- roles = getRoles(
- object, (not got) and entry_name or None, subobject,
- roles)
-
- # Promote subobject to object
- object=subobject
parents.append(object)
steps.append(entry_name)
finally:
parents.reverse()
-
+
+ # Note - no_acquire_flag is necessary to support
+ # things like DAV. We have to make sure
+ # that the target object is not acquired
+ # if the request_method is other than GET
+ # or POST. Otherwise, you could never use
+ # PUT to add a new object named 'test' if
+ # an object 'test' existed above it in the
+ # heirarchy -- you'd always get the
+ # existing object :(
+
+ if (no_acquire_flag and
+ hasattr(parent[1], 'aq_base') and
+ not hasattr(parent[1],'__bobo_traverse__')):
+ if not (hasattr(parent[1].aq_base, entry_name) or
+ parent[1].aq_base.has_key(entry_name)):
+ raise AttributeError, entry_name
+
# After traversal post traversal hooks aren't available anymore
del self._post_traverse
@@ -427,25 +430,25 @@
auth=request._auth
- if v is old_validation and roles is UNSPECIFIED_ROLES:
+ if v is old_validation and self.roles is UNSPECIFIED_ROLES:
# No roles, so if we have a named group, get roles from
# group keys
- if hasattr(groups,'keys'): roles=groups.keys()
+ if hasattr(groups,'keys'): self.roles=groups.keys()
else:
try: groups=groups()
except: pass
- try: roles=groups.keys()
+ try: self.roles=groups.keys()
except: pass
if groups is None:
# Public group, hack structures to get it to validate
- roles=None
+ self.roles=None
auth=''
if v is old_validation:
- user=old_validation(groups, request, auth, roles)
- elif roles is UNSPECIFIED_ROLES: user=v(request, auth)
- else: user=v(request, auth, roles)
+ user=old_validation(groups, request, auth, self.roles)
+ elif self.roles is UNSPECIFIED_ROLES: user=v(request, auth)
+ else: user=v(request, auth, self.roles)
while user is None and i < last_parent_index:
parent=parents[i]
@@ -456,11 +459,11 @@
if hasattr(groups,'validate'): v=groups.validate
else: v=old_validation
if v is old_validation:
- user=old_validation(groups, request, auth, roles)
- elif roles is UNSPECIFIED_ROLES: user=v(request, auth)
- else: user=v(request, auth, roles)
+ user=old_validation(groups, request, auth, self.roles)
+ elif self.roles is UNSPECIFIED_ROLES: user=v(request, auth)
+ else: user=v(request, auth, self.roles)
- if user is None and roles != UNSPECIFIED_ROLES:
+ if user is None and self.roles != UNSPECIFIED_ROLES:
response.unauthorized()
if user is not None:
More information about the Zope-Checkins
mailing list