def traverseName(self, request, ob, name): nm = name # the name to look up the object with if name and name[:1] in '@+': # Process URI segment parameters. ns, nm = nsParse(name) if ns: try: ob2 = namespaceLookup(ns, nm, ob, request) except TraversalError: raise NotFound(ob, name) return self.proxy(ob2) if nm == '.': return ob if IPublishTraverse.providedBy(ob): ob2 = ob.publishTraverse(request, nm) else: # self is marker adapter = queryMultiAdapter((ob, request), IPublishTraverse, default=self) if adapter is not self: ob2 = adapter.publishTraverse(request, nm) else: raise NotFound(ob, name, request) return self.proxy(ob2)
def traverseName(self, ob, name): if name and name[:1] in '@+': # Process URI segment parameters. ns, nm = nsParse(name) if ns: try: ob2 = namespaceLookup(ns, nm, ob, self) except LocationError: raise ztkNotFound(ob, name) if IAcquirer.providedBy(ob2): ob2 = ob2.__of__(ob) return ob2 if name == '.': return ob if IPublishTraverse.providedBy(ob): ob2 = ob.publishTraverse(self, name) else: adapter = queryMultiAdapter((ob, self), IPublishTraverse) if adapter is None: # Zope2 doesn't set up its own adapters in a lot of cases # so we will just use a default adapter. adapter = DefaultPublishTraverse(ob, self) ob2 = adapter.publishTraverse(self, name) return ob2
def traverseName(self, ob, name): if name and name[:1] in '@+': # Process URI segment parameters. ns, nm = nsParse(name) if ns: try: ob2 = namespaceLookup(ns, nm, ob, self) except LocationError: raise ztkNotFound(ob, name) if IAcquirer.providedBy(ob2): ob2 = ob2.__of__(ob) return ob2 if name == '.': return ob if IPublishTraverse.providedBy(ob): ob2 = ob.publishTraverse(self, name) else: adapter = queryMultiAdapter((ob, self), IPublishTraverse) if adapter is None: ## Zope2 doesn't set up its own adapters in a lot of cases ## so we will just use a default adapter. adapter = DefaultPublishTraverse(ob, self) ob2 = adapter.publishTraverse(self, name) return ob2
def traversePathElement(obj, name, further_path, default=_marker, traversable=None, request=None): """ Traverse a single step *name* relative to the given object. This is used to implement :meth:`zope.traversing.interfaces.ITraversalAPI.traverseName`. :param str name: must be a string. '.' and '..' are treated specially, as well as names starting with '@' or '+'. Otherwise *name* will be treated as a single path segment. :param list further_path: a list of names still to be traversed. This method is allowed to change the contents of *further_path*. :keyword ITraversable traversable: You can explicitly pass in an `~zope.traversing.interfaces.ITraversable` as the *traversable* argument. If you do not, the given object will be adapted to ``ITraversable``. :keyword request: assed in when traversing from presentation code. This allows paths like ``@@foo`` to work. :raises zope.location.interfaces.LocationError: if *path* cannot be found and '*default* was not provided. """ __traceback_info__ = (obj, name) if name == '.': return obj if name == '..': return obj.__parent__ if name and name[:1] in '@+': ns, nm = nsParse(name) if ns: return namespaceLookup(ns, nm, obj, request) else: nm = name if traversable is None: traversable = ITraversable(obj, None) if traversable is None: raise LocationError('No traversable adapter found', obj) try: return traversable.traverse(nm, further_path) except UnicodeEncodeError: # If we're on Python 2, and nm was a unicode string, and the traversable # tried to do an attribute lookup, the nm would have been encoded using the # system encoding (usually ascii). Failure to encode means invalid attribute # name. if default is not _marker: return default raise LocationError(obj, name) except LocationError: if default is not _marker: return default raise
def traversePathElement(obj, name, further_path, default=_marker, traversable=None, request=None): """Traverse a single step 'name' relative to the given object. 'name' must be a string. '.' and '..' are treated specially, as well as names starting with '@' or '+'. Otherwise 'name' will be treated as a single path segment. 'further_path' is a list of names still to be traversed. This method is allowed to change the contents of 'further_path'. You can explicitly pass in an ITraversable as the 'traversable' argument. If you do not, the given object will be adapted to ITraversable. 'request' is passed in when traversing from presentation code. This allows paths like @@foo to work. Raises LocationError if path cannot be found and 'default' was not provided. """ __traceback_info__ = (obj, name) if name == '.': return obj if name == '..': return obj.__parent__ if name and name[:1] in '@+': ns, nm = nsParse(name) if ns: return namespaceLookup(ns, nm, obj, request) else: nm = name if traversable is None: traversable = ITraversable(obj, None) if traversable is None: raise LocationError('No traversable adapter found', obj) try: return traversable.traverse(nm, further_path) except UnicodeEncodeError: # If we're on Python 2, and nm was a unicode string, and the traversable # tried to do an attribute lookup, the nm would have been encoded using the # system encoding (usually ascii). Failure to encode means invalid attribute # name. if default is not _marker: return default raise LocationError(obj, name) except LocationError: if default is not _marker: return default raise
def testTraverseNameSpace( self ): """ Test unrestrictedTraverse to a path that contains a namespace adapter. """ from OFS.SimpleItem import SimpleItem from Testing.makerequest import makerequest from zope import component from zope import interface from zope.publisher.interfaces.browser import IBrowserRequest from zope.traversing.interfaces import ITraversable from zope.traversing.namespace import namespaceLookup from OFS.Traversable import Traversable # First we create a dummy content type and its interface, against # which the namespace adapter will be registered class I(interface.Interface): """Test interface""" @interface.implementer(I) class C(Traversable): """ """ class NameSpaceAdapter(object): def __init__(self, context, request=None): self.context = context def traverse(self, name, remaining): return '42' # Now we register the namespace adapter twice. Once without expecting a # request object (i.e. providing IBrowserRequest) and once expecting # it. component.provideAdapter( NameSpaceAdapter, (I,), ITraversable, 'norequest') component.provideAdapter( NameSpaceAdapter, (I, IBrowserRequest), ITraversable, 'withrequest') # Lets instantiate our object, give it a REQUEST attr and see if # unrestrictedTraverse will call the NameSpaceAdapter with name # 'withrequest'. obj = C() request = makerequest(self.app).REQUEST obj.REQUEST = request self.assertEquals( obj.unrestrictedTraverse('++withrequest++number'), '42') # Now we remove the REQUEST attr. unrestrictedTraverse must now # return the NameSpaceAdapter with name 'norequest'. del obj.REQUEST self.assertEquals( namespaceLookup('norequest', 'number', obj), '42') self.assertEquals( obj.unrestrictedTraverse('++norequest++number'), '42')
def patchedTraverseName(self, request, ob, name): nm = name # the name to look up the object with if name and name[:1] in '@+': # Process URI segment parameters. ns, nm = nsParse(name) if ns: try: ob2 = namespaceLookup(ns, nm, ob, request) except (TraversalError, ValueError), e: raise NotFound(ob, name) return ProxyFactory(ob2)
def traversePathElement(obj, name, further_path, default=_marker, traversable=None, request=None): """Traverse a single step 'name' relative to the given object. 'name' must be a string. '.' and '..' are treated specially, as well as names starting with '@' or '+'. Otherwise 'name' will be treated as a single path segment. 'further_path' is a list of names still to be traversed. This method is allowed to change the contents of 'further_path'. You can explicitly pass in an ITraversable as the 'traversable' argument. If you do not, the given object will be adapted to ITraversable. 'request' is passed in when traversing from presentation code. This allows paths like @@foo to work. Raises LocationError if path cannot be found and 'default' was not provided. """ __traceback_info__ = (obj, name) if name == '.': return obj if name == '..': return obj.__parent__ if name and name[:1] in '@+': ns, nm = nsParse(name) if ns: return namespaceLookup(ns, nm, obj, request) else: nm = name if traversable is None: traversable = ITraversable(obj, None) if traversable is None: raise LocationError('No traversable adapter found', obj) try: return traversable.traverse(nm, further_path) except LocationError: if default is not _marker: return default else: raise return obj
def traverseName(self, request, ob, name): bpth = getattr(object, '__before_publishing_traverse__', None) if bpth is not None: bpth(object, self) # mostly lifted from zope.app.publication.publicationtraverse lookup_name = name if name and name[:1] in '@+': # Process URI segment parameters. ns, lookup_name = nsParse(name) if ns: try: subobject = namespaceLookup(ns, lookup_name, ob, request) except TraversalError: raise NotFound(ob, name) return subobject if lookup_name == '.': return ob if IPublishTraverse.providedBy(ob): subobject = ob.publishTraverse(request, lookup_name) else: # self is marker adapter = queryMultiAdapter((ob, request), IPublishTraverse, default=self) if adapter is not self: subobject = adapter.publishTraverse(request, lookup_name) else: raise NotFound(ob, name, request) request['PARENTS'].append(subobject) return subobject
def unrestrictedTraverse(self, path, default=_marker, restricted=False): """Lookup an object by path. path -- The path to the object. May be a sequence of strings or a slash separated string. If the path begins with an empty path element (i.e., an empty string or a slash) then the lookup is performed from the application root. Otherwise, the lookup is relative to self. Two dots (..) as a path element indicates an upward traversal to the acquisition parent. default -- If provided, this is the value returned if the path cannot be traversed for any reason (i.e., no object exists at that path or the object is inaccessible). restricted -- If false (default) then no security checking is performed. If true, then all of the objects along the path are validated with the security machinery. Usually invoked using restrictedTraverse(). """ if not path: return self if isinstance(path, str): # Unicode paths are not allowed path = path.split('/') else: path = list(path) REQUEST = {'TraversalRequestNameStack': path} path.reverse() path_pop = path.pop if len(path) > 1 and not path[0]: # Remove trailing slash path_pop(0) if restricted: validate = getSecurityManager().validate if not path[-1]: # If the path starts with an empty string, go to the root first. path_pop() obj = self.getPhysicalRoot() if restricted: validate(None, None, None, obj) # may raise Unauthorized else: obj = self # import time ordering problem from webdav.NullResource import NullResource resource = _marker try: while path: name = path_pop() __traceback_info__ = path, name if name[0] == '_': # Never allowed in a URL. raise NotFound, name if name == '..': next = aq_parent(obj) if next is not None: if restricted and not validate(obj, obj, name, next): raise Unauthorized(name) obj = next continue bobo_traverse = getattr(obj, '__bobo_traverse__', None) try: if name and name[:1] in '@+' and name != '+' and nsParse(name)[1]: # Process URI segment parameters. ns, nm = nsParse(name) try: next = namespaceLookup( ns, nm, obj, aq_acquire(self, 'REQUEST')) if IAcquirer.providedBy(next): next = next.__of__(obj) if restricted and not validate( obj, obj, name, next): raise Unauthorized(name) except LocationError: raise AttributeError(name) else: next = UseTraversalDefault # indicator try: if bobo_traverse is not None: next = bobo_traverse(REQUEST, name) if restricted: if aq_base(next) is not next: # The object is wrapped, so the acquisition # context is the container. container = aq_parent(aq_inner(next)) elif getattr(next, 'im_self', None) is not None: # Bound method, the bound instance # is the container container = next.im_self elif getattr(aq_base(obj), name, _marker) is next: # Unwrapped direct attribute of the object so # object is the container container = obj else: # Can't determine container container = None # If next is a simple unwrapped property, its # parentage is indeterminate, but it may have # been acquired safely. In this case validate # will raise an error, and we can explicitly # check that our value was acquired safely. try: ok = validate(obj, container, name, next) except Unauthorized: ok = False if not ok: if (container is not None or guarded_getattr(obj, name, _marker) is not next): raise Unauthorized(name) except UseTraversalDefault: # behave as if there had been no '__bobo_traverse__' bobo_traverse = None if next is UseTraversalDefault: if getattr(aq_base(obj), name, _marker) is not _marker: if restricted: next = guarded_getattr(obj, name) else: next = getattr(obj, name) else: try: next = obj[name] # The item lookup may return a NullResource, # if this is the case we save it and return it # if all other lookups fail. if isinstance(next, NullResource): resource = next raise KeyError(name) except AttributeError: # Raise NotFound for easier debugging # instead of AttributeError: __getitem__ raise NotFound(name) if restricted and not validate( obj, obj, None, next): raise Unauthorized(name) except (AttributeError, NotFound, KeyError), e: # Try to look for a view next = queryMultiAdapter((obj, aq_acquire(self, 'REQUEST')), Interface, name) if next is not None: if IAcquirer.providedBy(next): next = next.__of__(obj) if restricted and not validate(obj, obj, name, next): raise Unauthorized(name) elif bobo_traverse is not None: # Attribute lookup should not be done after # __bobo_traverse__: raise e else: # No view, try acquired attributes try: if restricted: next = guarded_getattr(obj, name, _marker) else: next = getattr(obj, name, _marker) except AttributeError: raise e if next is _marker: # If we have a NullResource from earlier use it. next = resource if next is _marker: # Nothing found re-raise error raise e obj = next return obj
def unrestrictedTraverse(self, path, default=_marker, restricted=False): """Lookup an object by path. path -- The path to the object. May be a sequence of strings or a slash separated string. If the path begins with an empty path element (i.e., an empty string or a slash) then the lookup is performed from the application root. Otherwise, the lookup is relative to self. Two dots (..) as a path element indicates an upward traversal to the acquisition parent. default -- If provided, this is the value returned if the path cannot be traversed for any reason (i.e., no object exists at that path or the object is inaccessible). restricted -- If false (default) then no security checking is performed. If true, then all of the objects along the path are validated with the security machinery. Usually invoked using restrictedTraverse(). """ if not path: return self if isinstance(path, str): # Unicode paths are not allowed path = path.split('/') else: path = list(path) REQUEST = {'TraversalRequestNameStack': path} path.reverse() path_pop = path.pop if len(path) > 1 and not path[0]: # Remove trailing slash path_pop(0) if restricted: validate = getSecurityManager().validate if not path[-1]: # If the path starts with an empty string, go to the root first. path_pop() obj = self.getPhysicalRoot() if restricted: validate(None, None, None, obj) # may raise Unauthorized else: obj = self # import time ordering problem from webdav.NullResource import NullResource resource = _marker try: while path: name = path_pop() __traceback_info__ = path, name if name[0] == '_': # Never allowed in a URL. raise NotFound, name if name == '..': next = aq_parent(obj) if next is not None: if restricted and not validate(obj, obj, name, next): raise Unauthorized(name) obj = next continue bobo_traverse = getattr(obj, '__bobo_traverse__', None) try: if name and name[:1] in '@+' and name != '+' and nsParse( name)[1]: # Process URI segment parameters. ns, nm = nsParse(name) try: next = namespaceLookup(ns, nm, obj, aq_acquire(self, 'REQUEST')) if IAcquirer.providedBy(next): next = next.__of__(obj) if restricted and not validate( obj, obj, name, next): raise Unauthorized(name) except LocationError: raise AttributeError(name) else: next = UseTraversalDefault # indicator try: if bobo_traverse is not None: next = bobo_traverse(REQUEST, name) if restricted: if aq_base(next) is not next: # The object is wrapped, so the acquisition # context is the container. container = aq_parent(aq_inner(next)) elif getattr(next, 'im_self', None) is not None: # Bound method, the bound instance # is the container container = next.im_self elif getattr(aq_base(obj), name, _marker) is next: # Unwrapped direct attribute of the object so # object is the container container = obj else: # Can't determine container container = None # If next is a simple unwrapped property, its # parentage is indeterminate, but it may have # been acquired safely. In this case validate # will raise an error, and we can explicitly # check that our value was acquired safely. try: ok = validate(obj, container, name, next) except Unauthorized: ok = False if not ok: if (container is not None or guarded_getattr( obj, name, _marker) is not next): raise Unauthorized(name) except UseTraversalDefault: # behave as if there had been no '__bobo_traverse__' bobo_traverse = None if next is UseTraversalDefault: if getattr(aq_base(obj), name, _marker) is not _marker: if restricted: next = guarded_getattr(obj, name) else: next = getattr(obj, name) else: try: next = obj[name] # The item lookup may return a NullResource, # if this is the case we save it and return it # if all other lookups fail. if isinstance(next, NullResource): resource = next raise KeyError(name) except (AttributeError, TypeError): # Raise NotFound for easier debugging # instead of AttributeError: __getitem__ # or TypeError: not subscriptable raise NotFound(name) if restricted and not validate( obj, obj, None, next): raise Unauthorized(name) except (AttributeError, NotFound, KeyError), e: # Try to look for a view next = queryMultiAdapter( (obj, aq_acquire(self, 'REQUEST')), Interface, name) if next is not None: if IAcquirer.providedBy(next): next = next.__of__(obj) if restricted and not validate(obj, obj, name, next): raise Unauthorized(name) elif bobo_traverse is not None: # Attribute lookup should not be done after # __bobo_traverse__: raise e else: # No view, try acquired attributes try: if restricted: next = guarded_getattr(obj, name, _marker) else: next = getattr(obj, name, _marker) except AttributeError: raise e if next is _marker: # If we have a NullResource from earlier use it. next = resource if next is _marker: # Nothing found re-raise error raise e obj = next return obj
def getAllowedViews(self): """ This method will return a dict containing the view name as keys and filesystem full path to both page template files and python files, according if it is a BrowserView or a FSPageTemplate """ pt = getToolByName(self.context, 'portal_types') portal_type = self.context.portal_type dvt = pt[portal_type] result = {} # The following was taken from traverseName function from # ZPublisher/BaseRequest.py for view in dvt.view_methods: if view[:1] in '@+': # Process URI segment parameters. ns, nm = nsParse(view) if ns: try: ob = namespaceLookup(ns, nm, self.context, self.request) except TraversalError: result[view] = {} continue if IAcquirer.providedBy(ob): ob = ob.__of__(self.context) else: if IPublishTraverse.providedBy(self.context): ob = self.context.publishTraverse(self.request, view) else: adapter = queryMultiAdapter((self.context, self.request), IPublishTraverse) if adapter is None: ## Zope2 doesn't set up its own adapters in a lot of cases ## so we will just use a default adapter. adapter = DefaultPublishTraverse(self.context, self.request) ob = adapter.publishTraverse(self.request, view) if isinstance(ob, BrowserView): # Taken from five.customerize.browser klass = ob.__class__ base = klass.__bases__[0] if base is BrowserView or base is object: py_file = inspect.getsourcefile(klass) else: py_file = inspect.getsourcefile(base) pt_file = ob.index.filename result[view] = {'py':py_file, 'pt':pt_file} elif isinstance(ob, FSPageTemplate): result[view] = {'pt':ob.getObjectFSPath()} else: result[view] = {} return result
def trustedTraverse( ob, path, ignored, ): if not path: return self get = getattr has = hasattr N = None M = rebindFunction # artifical marker if isinstance(path, str): path = path.split('/') else: path = list(path) REQUEST = get(ob, 'REQUEST', None) if REQUEST is None: REQUEST = FakeRequest() setDefaultSkin(REQUEST) REQUEST['TraversalRequestNameStack'] = path path.reverse() pop = path.pop if len(path) > 1 and not path[0]: # Remove trailing slash path.pop(0) if not path[-1]: # If the path starts with an empty string, go to the root first. pop() self = ob.getPhysicalRoot() object = ob while path: name = pop() __traceback_info__ = path, name if name == '..': o = getattr(object, 'aq_parent', M) if o is not M: object = o continue if name and name[:1] in '@+': # Process URI segment parameters. ns, nm = nsParse(name) if ns: try: o = namespaceLookup(ns, nm, object, REQUEST).__of__(object) except TraversalError: raise KeyError(name) object = o continue t = get(object, '__bobo_traverse__', M) if t is not M: o = t(REQUEST, name) else: o = get(object, name, M) if o is M: try: o = object[name] except (AttributeError, TypeError): # better exception o = queryMultiAdapter((object, REQUEST), Interface, name) if o is not None: o = o.__of__(object) else: raise AttributeError(name) object = o return object