def traverseRelativeURL(self, request, ob, path): ob = self.traversePath(request, ob, path) while True: adapter = IBrowserPublisher(ob, None) if adapter is None: return ob ob, path = adapter.browserDefault(request) ob = ProxyFactory(ob) if not path: return ob ob = self.traversePath(request, ob, path)
def traverseRelativeURL(self, request, ob, path): """Path traversal that includes browserDefault paths""" ob = self.traversePath(request, ob, path) while True: adapter = IBrowserPublisher(ob, None) if adapter is None: return ob ob, path = adapter.browserDefault(request) ob = self.proxy(ob) if not path: return ob ob = self.traversePath(request, ob, path)
def add_src_from_id(self, items): results = [] develmode = self.getDevelMode() portal = self.portal_state.portal() for info in items: item = copy(info) itemid = item["id"] if itemid.startswith('http'): info['src'] = itemid results.append(info) else: if '.min.' in itemid and develmode: try: id = itemid.replace(".min.", ".") content = portal.restrictedTraverse(id) itemid = id except KeyError: content = portal.restrictedTraverse(itemid) else: content = portal.restrictedTraverse(itemid) if content and IBrowserPublisher.providedBy(content): path = content.context.path time = str(os.path.getmtime(path)) info["src"] = "%s/%s?time%s" % (self.site_url, itemid, time) results.append(info) elif content: info["src"] = "%s/%s" % (self.site_url, info["id"]) results.append(info) return results
def publish(self, origin): path = self.path request = origin.request del request.PARENTS[-1] # Remove the current item and traverse if self.clear: request.form.clear() component = lookupREST(origin.context, request, path.pop()) while path: while path: part = path.pop() component = request.traverseName(component, part) adapter = None if IBrowserPublisher.providedBy(component): adapter = component else: adapter = queryMultiAdapter( (component, request), IBrowserPublisher) if adapter is not None: component, default_path = adapter.browserDefault(request) if default_path: path.extend(reversed(default_path)) return component()
def getDefaultTraversal(self, request, obj): if IBrowserPublisher.providedBy(obj): return obj.browserDefault(request) adapter = zope.component.queryMultiAdapter((obj, request), IBrowserPublisher) if adapter is not None: return adapter.browserDefault(request) return obj, None
def getDefaultTraversal(self, request, ob): if IBrowserPublisher.providedBy(ob): return ob.browserDefault(request) else: adapter = queryMultiAdapter((ob, request), IBrowserPublisher) if adapter is not None: ob, path = adapter.browserDefault(request) return ob, path else: return ob, None
def _generateIncludes(self, libraries): # generate the HTML that will be included in the response site = zope.component.hooks.getSite() if site is None: return resources = queryMultiAdapter((site, self._request), interface.Interface, name='') if not IBrowserPublisher.providedBy(resources): # a setup with no resources factory is supported; in this # case, we manually craft a URL to the resource publisher # (see ``zope.browserresource.resource``). resources = None base = queryMultiAdapter((site, self._request), IAbsoluteURL, name="resource") if base is None: baseURL = str( getMultiAdapter((site, self._request), IAbsoluteURL)) else: baseURL = str(base) html = [] for lib in libraries: if resources is not None: library_resources = resources[lib] included = zc.resourcelibrary.getIncluded(lib) for file_name in included: if resources is not None: url = library_resources[file_name]() else: url = "%s/@@/%s/%s" % (baseURL, lib, file_name) if file_name.endswith('.js'): html.append('<script src="%s" ' % url) html.append(' type="text/javascript">') html.append('</script>') elif file_name.endswith('.css'): html.append('<style type="text/css" media="all">') html.append(' <!--') html.append(' @import url("%s");' % url) html.append(' -->') html.append('</style>') elif file_name.endswith('.kss'): html.append( '<link type="text/kss" href="%s" rel="kinetic-stylesheet" />' % url) else: # shouldn't get here; zcml.py is supposed to check includes raise RuntimeError('Resource library doesn\'t know how to ' 'include this file: "%s"' % file_name) return '\n '.join(html)
def getDefaultTraversal(self, request, ob): if IBrowserPublisher.providedBy(ob): # ob is already proxied, so the result of calling a method will be return ob.browserDefault(request) else: adapter = zapi.queryMultiAdapter((ob, request), IBrowserPublisher) if adapter is not None: ob, path = adapter.browserDefault(request) ob = ProxyFactory(ob) return ob, path else: # ob is already proxied return ob, None
def getDefaultTraversal(self, request, ob): if IBrowserPublisher.providedBy(ob): # ob is already proxied, so the result of calling a method will be return ob.browserDefault(request) else: adapter = queryMultiAdapter((ob, request), IBrowserPublisher) if adapter is not None: ob, path = adapter.browserDefault(request) ob = ProxyFactory(ob) return ob, path else: # ob is already proxied return ob, None
def _generateIncludes(self, libraries): # generate the HTML that will be included in the response site = zope.component.hooks.getSite() if site is None: return resources = queryMultiAdapter( (site, self._request), interface.Interface, name='') if not IBrowserPublisher.providedBy(resources): # a setup with no resources factory is supported; in this # case, we manually craft a URL to the resource publisher # (see ``zope.browserresource.resource``). resources = None base = queryMultiAdapter( (site, self._request), IAbsoluteURL, name="resource") if base is None: baseURL = str(getMultiAdapter( (site, self._request), IAbsoluteURL)) else: baseURL = str(base) html = [] for lib in libraries: if resources is not None: library_resources = resources[lib] included = zc.resourcelibrary.getIncluded(lib) for file_name in included: if resources is not None: url = library_resources[file_name]() else: url = "%s/@@/%s/%s" % (baseURL, lib, file_name) if file_name.endswith('.js'): html.append('<script src="%s" ' % url) html.append(' type="text/javascript">') html.append('</script>') elif file_name.endswith('.css'): html.append('<style type="text/css" media="all">') html.append(' <!--') html.append(' @import url("%s");' % url) html.append(' -->') html.append('</style>') elif file_name.endswith('.kss'): html.append('<link type="text/kss" href="%s" rel="kinetic-stylesheet" />' % url) else: # shouldn't get here; zcml.py is supposed to check includes raise RuntimeError('Resource library doesn\'t know how to ' 'include this file: "%s"' % file_name) return '\n '.join(html)
def __call__(self): """Return the JSON cache.""" if IBrowserPublisher.providedBy(self.context): view = self.context else: defaultviewname = getDefaultViewName(self.context, self.request) view = getMultiAdapter((self.context, self.request), name=defaultviewname) if view is None: return naked_view = removeSecurityProxy(view) naked_view.initialize() cache = naked_view.getCacheJSON() self.request.response.setHeader('content-type', 'application/json') return cache
def test_class_w_implements(self): xmlconfig( StringIO(template % ''' <browser:page name="test" class=" zope.app.publisher.browser.tests.test_directives.C_w_implements" for="zope.app.component.tests.views.IC" attribute="index" permission="zope.Public" /> ''')) v = component.getMultiAdapter((ob, request), name='test') self.assertEqual(v.index(), v) self.assert_(IBrowserPublisher.providedBy(v))
def __call__(self): """Return the JSON cache.""" if IBrowserPublisher.providedBy(self.context): view = self.context else: defaultviewname = getDefaultViewName( self.context, self.request) view = getMultiAdapter( (self.context, self.request), name=defaultviewname) if view is None: return naked_view = removeSecurityProxy(view) naked_view.initialize() cache = naked_view.getCacheJSON() self.request.response.setHeader('content-type', 'application/json') return cache
def test_class_w_implements(self): xmlconfig( StringIO(template % u''' <browser:page name="test" class=" zope.browserpage.tests.test_page.C_w_implements" for="zope.browserpage.tests.test_page.IC" attribute="index" permission="zope.Public" /> ''')) v = component.getMultiAdapter((ob, self.request), name='test') self.assertEqual(v.index(), v) self.assertTrue(IBrowserPublisher.providedBy(v))
def test_class_w_implements(self): xmlconfig(StringIO(template % ''' <browser:page name="test" class=" zope.app.publisher.browser.tests.test_directives.C_w_implements" for="zope.app.component.tests.views.IC" attribute="index" permission="zope.Public" /> ''' )) v = zapi.getMultiAdapter((ob, request), name='test') self.assertEqual(v.index(), v) self.assert_(IBrowserPublisher.providedBy(v))
def test_class_w_implements(self): xmlconfig(StringIO( template % u''' <browser:page name="test" class=" zope.browserpage.tests.test_page.C_w_implements" for="zope.browserpage.tests.test_page.IC" attribute="index" permission="zope.Public" /> ''' )) v = component.getMultiAdapter((ob, self.request), name='test') self.assertEqual(v.index(), v) self.assertTrue(IBrowserPublisher.providedBy(v))
def render_error(self, error, last_known_obj): """Render and log an error. """ if IBrowserPage.providedBy(last_known_obj): #of the last obj is a view, use it's context (which should be # an IAcquirer) last_known_obj = last_known_obj.context if not IAcquirer.providedBy(last_known_obj): last_known_site = getSite() if last_known_site is not None: last_known_obj = last_known_site context = DefaultError(error) if IAcquirer.providedBy(last_known_obj): context = context.__of__(last_known_obj) error_view = queryMultiAdapter( (context, self.request), name='error.html') if IBrowserPublisher.providedBy(error_view): error_view, error_path = error_view.browserDefault(self.request) if error_path: raise NotImplementedError( u'Error browserDefault retuned an path. ' u'This is not implemented.') if error_view is not None: notify(interfaces.PublicationBeforeError( self.request, last_known_obj)) try: error_result = error_view() if error_result is not None: self.response.setBody(error_result) notify(interfaces.PublicationAfterRender( self.request, error_view)) except Exception: log_last_error( self.request, self.response, obj=last_known_obj, extra=u"Error while rendering error message") self.response.setStatus(500) self.response.setBody(ERROR_WHILE_RENDERING_ERROR_TEMPLATE) else: logger.error('No action defined for last exception') self.response.setStatus(500) self.response.setBody(DEFAULT_ERROR_TEMPLATE)
def get(self, name, default=_marker): value = super(SkinDirectory, self).get(name, None) if value is not None: return value wrapper = RequestWrapper(self.request) # lookup through the layer stack to find other directory # resources that might contain the requested resource. for layer in self.layers: interface.directlyProvides(wrapper, layer) resource_dir = component.queryAdapter(wrapper, name=self.__name__) if not ( IResource.providedBy( resource_dir ) \ and IBrowserPublisher.providedBy( resource_dir ) ): continue resource = resource_dir.get(name) if resource is not None: return resource raise NotFound(name)
def register_help_folder(context, folder, name): """Create a help folder subclass and register it with the ZCA.""" help_folder = type( str('%s for %s' % (name, folder)), (HelpFolder, ), {'folder': folder, '__name__': name}) defineChecker( help_folder, NamesChecker(list(IBrowserPublisher.names(True)) + ['__call__'])) context.action( discriminator=( 'view', (ILaunchpadApplication, IBrowserRequest), name), callable=handler, args=('registerAdapter', help_folder, (ILaunchpadApplication, IBrowserRequest), Interface, name, context.info), )
def register_help_folder(context, folder, name): """Create a help folder subclass and register it with the ZCA.""" help_folder = type(str('%s for %s' % (name, folder)), (HelpFolder, ), { 'folder': folder, '__name__': name }) defineChecker( help_folder, NamesChecker(list(IBrowserPublisher.names(True)) + ['__call__'])) context.action( discriminator=('view', (ILaunchpadApplication, IBrowserRequest), name), callable=handler, args=('registerAdapter', help_folder, (ILaunchpadApplication, IBrowserRequest), Interface, name, context.info), )
def get(self, name, default=_marker): value = super( SkinDirectory, self ).get( name, None) if value is not None: return value wrapper = RequestWrapper( self.request ) # lookup through the layer stack to find other directory # resources that might contain the requested resource. for layer in self.layers: interface.directlyProvides( wrapper, layer ) resource_dir = component.queryAdapter(wrapper, name=self.__name__) if not ( IResource.providedBy( resource_dir ) \ and IBrowserPublisher.providedBy( resource_dir ) ): continue resource = resource_dir.get( name ) if resource is not None: return resource raise NotFound( name )
def get_default_traversal(self, request, ob): """Get the default traversal steps for an object. Returns (next_object, steps). """ if request.form_action: # Do not follow default traversal when a form action was # provided. return ob, None if IBrowserPublisher.providedBy(ob): # ob is already proxied, so the result of calling a method # will be too. return ob.browserDefault(request) adapter = queryMultiAdapter((ob, request), IBrowserPublisher) if adapter is not None: ob, path = adapter.browserDefault(request) ob = self.proxy_factory(ob) return ob, path # ob is already proxied return ob, None
def traverse(self, path, response=None, validated_hook=None): """Traverse the object space The REQUEST must already have a PARENTS item with at least one object in it. This is typically the root object. """ request=self request_get=request.get if response is None: response=self.response # remember path for later use browser_path = path # Cleanup the path list if path[:1]=='/': path=path[1:] if path[-1:]=='/': path=path[:-1] clean=[] for item in path.split('/'): # Make sure that certain things that dont make sense # cannot be traversed. if item in ('REQUEST', 'aq_self', 'aq_base'): return response.notFoundError(path) if not item or item=='.': continue elif item == '..': del clean[-1] else: clean.append(item) path=clean # How did this request come in? (HTTP GET, PUT, POST, etc.) method = request_get('REQUEST_METHOD', 'GET').upper() if method=='GET' or method=='POST' and not isinstance(response, xmlrpc.Response): # Probably a browser no_acquire_flag=0 # index_html is still the default method, only any object can # override it by implementing its own __browser_default__ method method = 'index_html' elif self.maybe_webdav_client: # Probably a WebDAV client. no_acquire_flag=1 else: no_acquire_flag=0 URL=request['URL'] parents=request['PARENTS'] object=parents[-1] del parents[:] 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) self.roles = getRoles(None, None, object, UNSPECIFIED_ROLES) except: pass if not path and not method: return response.forbiddenError(self['URL']) # Traverse the URL to find the object: if hasattr(object, '__of__'): # Try to bind the top-level object to the request # This is how you get 'self.REQUEST' object=object.__of__(RequestContainer(REQUEST=request)) parents.append(object) steps=self.steps self._steps = _steps = map(quote, steps) path.reverse() request['TraversalRequestNameStack'] = request.path = path request['ACTUAL_URL'] = request['URL'] + quote(browser_path) # Set the posttraverse for duration of the traversal here self._post_traverse = post_traverse = [] entry_name = '' try: # We build parents in the wrong order, so we # need to make sure we reverse it when we're done. while 1: bpth = getattr(object, '__before_publishing_traverse__', None) if bpth is not None: bpth(object, self) path = request.path = request['TraversalRequestNameStack'] # Check for method: if path: entry_name = path.pop() else: # If we have reached the end of the path, we look to see # if we can find IBrowserPublisher.browserDefault. If so, # we call it to let the object tell us how to publish it. # BrowserDefault returns the object to be published # (usually self) and a sequence of names to traverse to # find the method to be published. # This is webdav support. The last object in the path # should not be acquired. Instead, a NullResource should # be given if it doesn't exist: if (no_acquire_flag and hasattr(object, 'aq_base') and not hasattr(object,'__bobo_traverse__')): if object.aq_parent is not object.aq_inner.aq_parent: from webdav.NullResource import NullResource object = NullResource(parents[-2], object.getId(), self).__of__(parents[-2]) if IBrowserPublisher.providedBy(object): adapter = object else: adapter = queryMultiAdapter((object, self), IBrowserPublisher) 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(object, self) object, default_path = adapter.browserDefault(self) if default_path: request._hacked_path=1 if len(default_path) > 1: path = list(default_path) method = path.pop() request['TraversalRequestNameStack'] = path continue else: entry_name = default_path[0] elif (method and hasattr(object,method) and entry_name != method and getattr(object, method) is not None): request._hacked_path=1 entry_name = method method = 'index_html' else: if hasattr(object, '__call__'): self.roles = getRoles(object, '__call__', object.__call__, self.roles) if request._hacked_path: i=URL.rfind('/') if i > 0: response.setBase(URL[:i]) break step = quote(entry_name) _steps.append(step) request['URL'] = URL = '%s/%s' % (request['URL'], step) try: subobject = self.traverseName(object, entry_name) if (hasattr(object,'__bobo_traverse__') or hasattr(object, entry_name)): check_name = entry_name else: check_name = None self.roles = getRoles( object, check_name, subobject, self.roles) object = subobject # traverseName() might raise ZTK's NotFound except (KeyError, AttributeError, ztkNotFound): if response.debug_mode: return response.debugError( "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) 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(parents[1], 'aq_base') and not hasattr(parents[1],'__bobo_traverse__')): if not (hasattr(parents[1].aq_base, entry_name) or parents[1].aq_base.has_key(entry_name)): raise AttributeError, entry_name # After traversal post traversal hooks aren't available anymore del self._post_traverse request['PUBLISHED'] = parents.pop(0) # Do authorization checks user=groups=None i=0 if 1: # Always perform authentication. last_parent_index=len(parents) if hasattr(object, '__allow_groups__'): groups=object.__allow_groups__ inext=0 else: inext=None for i in range(last_parent_index): if hasattr(parents[i],'__allow_groups__'): groups=parents[i].__allow_groups__ inext=i+1 break if inext is not None: i=inext if hasattr(groups, 'validate'): v=groups.validate else: v=old_validation auth=request._auth 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'): self.roles=groups.keys() else: try: groups=groups() except: pass try: self.roles=groups.keys() except: pass if groups is None: # Public group, hack structures to get it to validate self.roles=None auth='' if v is old_validation: 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] i=i+1 if hasattr(parent, '__allow_groups__'): groups=parent.__allow_groups__ else: continue if hasattr(groups,'validate'): v=groups.validate else: v=old_validation if v is old_validation: 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 self.roles != UNSPECIFIED_ROLES: response.unauthorized() if user is not None: if validated_hook is not None: validated_hook(self, user) request['AUTHENTICATED_USER']=user request['AUTHENTICATION_PATH']='/'.join(steps[:-i]) # Remove http request method from the URL. request['URL']=URL # Run post traversal hooks if post_traverse: result = exec_callables(post_traverse) if result is not None: object = result return object
def test_view(self): view = Manage(self.site, TestRequest()) self.assertTrue(IBrowserPublisher.providedBy(view))
def test_view(self): view = ContentsView(self.folder, TestRequest()) self.failUnless(IBrowserPublisher.providedBy(view))
def test_view(self): view = ContentsView(self.folder, TestRequest()) self.assertTrue(IBrowserPublisher.providedBy(view))
def traverse(self, path, response=None, validated_hook=None): """Traverse the object space The REQUEST must already have a PARENTS item with at least one object in it. This is typically the root object. """ request = self request_get = request.get if response is None: response = self.response # remember path for later use browser_path = path # Cleanup the path list if path[:1] == '/': path = path[1:] if path[-1:] == '/': path = path[:-1] clean = [] for item in path.split('/'): # Make sure that certain things that dont make sense # cannot be traversed. if item in ('REQUEST', 'aq_self', 'aq_base'): return response.notFoundError(path) if not item or item == '.': continue elif item == '..': del clean[-1] else: clean.append(item) path = clean # How did this request come in? (HTTP GET, PUT, POST, etc.) method = request_get('REQUEST_METHOD', 'GET').upper() # Probably a browser no_acquire_flag = 0 if (method in ('GET', 'POST', 'PURGE') and not is_xmlrpc_response(response)): # index_html is still the default method, only any object can # override it by implementing its own __browser_default__ method method = 'index_html' elif self.maybe_webdav_client: # Probably a WebDAV client. no_acquire_flag = 1 URL = request['URL'] parents = request['PARENTS'] object = parents[-1] del parents[:] 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: new_object = object.__bobo_traverse__(request) if new_object is not None: object = new_object self.roles = getRoles(None, None, object, UNSPECIFIED_ROLES) except Exception: pass if not path and not method: return response.forbiddenError(self['URL']) # Traverse the URL to find the object: if hasattr(object, '__of__'): # Try to bind the top-level object to the request # This is how you get 'self.REQUEST' object = object.__of__(RequestContainer(REQUEST=request)) parents.append(object) steps = self.steps self._steps = _steps = list(map(quote, steps)) path.reverse() request['TraversalRequestNameStack'] = request.path = path request['ACTUAL_URL'] = request['URL'] + quote(browser_path) # Set the posttraverse for duration of the traversal here self._post_traverse = post_traverse = [] # import time ordering problem if HAS_ZSERVER: from webdav.NullResource import NullResource else: NullResource = None entry_name = '' try: # We build parents in the wrong order, so we # need to make sure we reverse it when we're done. while 1: bpth = getattr(object, '__before_publishing_traverse__', None) if bpth is not None: bpth(object, self) path = request.path = request['TraversalRequestNameStack'] # Check for method: if path: entry_name = path.pop() else: # If we have reached the end of the path, we look to see # if we can find IBrowserPublisher.browserDefault. If so, # we call it to let the object tell us how to publish it. # BrowserDefault returns the object to be published # (usually self) and a sequence of names to traverse to # find the method to be published. # This is webdav support. The last object in the path # should not be acquired. Instead, a NullResource should # be given if it doesn't exist: if (NullResource is not None and no_acquire_flag and hasattr(object, 'aq_base') and not hasattr(object, '__bobo_traverse__')): if (object.__parent__ is not aq_inner(object).__parent__): object = NullResource(parents[-2], object.getId(), self).__of__(parents[-2]) if IBrowserPublisher.providedBy(object): adapter = object else: adapter = queryMultiAdapter((object, self), IBrowserPublisher) 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(object, self) object, default_path = adapter.browserDefault(self) if default_path: request._hacked_path = 1 if len(default_path) > 1: path = list(default_path) method = path.pop() request['TraversalRequestNameStack'] = path continue else: entry_name = default_path[0] elif (method and hasattr(object, method) and entry_name != method and getattr(object, method) is not None): request._hacked_path = 1 entry_name = method method = 'index_html' else: if hasattr(object, '__call__'): self.roles = getRoles(object, '__call__', object.__call__, self.roles) if request._hacked_path: i = URL.rfind('/') if i > 0: response.setBase(URL[:i]) break step = quote(entry_name) _steps.append(step) request['URL'] = URL = '%s/%s' % (request['URL'], step) try: subobject = self.traverseName(object, entry_name) if (hasattr(object, '__bobo_traverse__') or hasattr(object, entry_name)): check_name = entry_name else: check_name = None self.roles = getRoles(object, check_name, subobject, self.roles) object = subobject # traverseName() might raise ZTK's NotFound except (KeyError, AttributeError, ztkNotFound): if response.debug_mode: return response.debugError( "Cannot locate object at: %s" % URL) else: return response.notFoundError(URL) except Forbidden as e: if self.response.debug_mode: return response.debugError(e.args) else: return response.forbiddenError(entry_name) 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(parents[1], 'aq_base') and not hasattr(parents[1], '__bobo_traverse__')): base = aq_base(parents[1]) if not hasattr(base, entry_name): try: if entry_name not in base: raise AttributeError(entry_name) except TypeError: raise AttributeError(entry_name) # After traversal post traversal hooks aren't available anymore del self._post_traverse request['PUBLISHED'] = parents.pop(0) # Do authorization checks user = groups = None i = 0 if 1: # Always perform authentication. last_parent_index = len(parents) if hasattr(object, '__allow_groups__'): groups = object.__allow_groups__ inext = 0 else: inext = None for i in range(last_parent_index): if hasattr(parents[i], '__allow_groups__'): groups = parents[i].__allow_groups__ inext = i + 1 break if inext is not None: i = inext if hasattr(groups, 'validate'): v = groups.validate else: v = old_validation auth = request._auth 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'): self.roles = list(groups.keys()) else: try: groups = groups() except Exception: pass try: self.roles = list(groups.keys()) except Exception: pass if groups is None: # Public group, hack structures to get it to validate self.roles = None auth = '' if v is old_validation: 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] i = i + 1 if hasattr(parent, '__allow_groups__'): groups = parent.__allow_groups__ else: continue if hasattr(groups, 'validate'): v = groups.validate else: v = old_validation if v is old_validation: 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 self.roles != UNSPECIFIED_ROLES: response.unauthorized() if user is not None: if validated_hook is not None: validated_hook(self, user) request['AUTHENTICATED_USER'] = user request['AUTHENTICATION_PATH'] = '/'.join(steps[:-i]) # Remove http request method from the URL. request['URL'] = URL # Run post traversal hooks if post_traverse: result = exec_callables(post_traverse) if result is not None: object = result return object