def __bobo_traverse__(self, REQUEST, name=None): if name is None: # Make this more explicit, otherwise getattr(self, name) # would raise a TypeError getattr(): attribute name must be string return None if name == 'Control_Panel': return APP_MANAGER.__of__(self) try: return getattr(self, name) except AttributeError: pass try: return self[name] except KeyError: pass method = REQUEST.get('REQUEST_METHOD', 'GET') if NullResource is not None and method not in ('GET', 'POST'): return NullResource(self, name, REQUEST).__of__(self) if method not in ('GET', 'POST'): return NullResource(self, name, REQUEST).__of__(self) # Waaa. unrestrictedTraverse calls us with a fake REQUEST. # There is probably a better fix for this. try: REQUEST.RESPONSE.notFoundError("%s\n%s" % (name, method)) except AttributeError: raise KeyError(name)
def index_html(self): """ Allow creation of . """ if 'index_html' in self: return self._getOb('index_html') request = getattr(self, 'REQUEST', None) if request and 'REQUEST_METHOD' in request: if (request.maybe_webdav_client and request['REQUEST_METHOD'] in ['PUT']): # Very likely a WebDAV client trying to create something nr = NullResource(self, 'index_html') nr.__replaceable__ = REPLACEABLE return nr return None
def publishTraverse(self, request, name): context = aq_inner(self.context) # If we are trying to traverse to the folder "body" pseudo-object # returned by listDAVObjects(), return that immediately if getattr(request, 'maybe_webdav_client', False) \ and name == DAV_FOLDER_DATA_ID: return FolderDataResource(DAV_FOLDER_DATA_ID, context).__of__(context) defaultTraversal = super(DexterityPublishTraverse, self).publishTraverse(request, name) # If this is a WebDAV PUT/PROPFIND/PROPPATCH request, don't acquire # things. If we did, we couldn't create a new object with PUT, for # example, because the acquired object would shadow the NullResource if getattr(request, 'maybe_webdav_client', False) \ and request.get('REQUEST_METHOD', 'GET') not in ('GET', 'POST',) \ and IAcquirer.providedBy(defaultTraversal): parent = aq_parent(aq_inner(defaultTraversal)) if parent is not None and parent is not context: return NullResource(self.context, name, request).__of__(self.context) return defaultTraversal
def __bobo_traverse__(self, request, name): """ If no subobject is found through Folder API then try to lookup the object by invoking _getExtensibleContent """ # Normal traversal try: return getattr(self, name) except AttributeError: pass try: return self[name] except KeyError: pass document = self.getExtensibleContent(request, name) if document is not None: return aq_base(document).__of__(self) # Not found section method = request.get('REQUEST_METHOD', 'GET') if not method in ('GET', 'POST'): return NullResource(self, name, request).__of__(self) # Waaa. unrestrictedTraverse calls us with a fake REQUEST. # There is proabably a better fix for this. try: request.RESPONSE.notFoundError("%s\n%s" % (name, method)) except AttributeError: raise KeyError(name)
def __getitem__(self, key): if key in self: return self._getOb(key, None) request = getattr(self, 'REQUEST', None) if not isinstance(request, (str, NoneType)): method = request.get('REQUEST_METHOD', 'GET') if (request.maybe_webdav_client and method not in ('GET', 'POST')): return NullResource(self, key, request).__of__(self) raise KeyError, key
def __getitem__(self, key): v=self._getOb(key, None) if v is not None: return v if hasattr(self, 'REQUEST'): request=self.REQUEST method=request.get('REQUEST_METHOD', 'GET') if request.maybe_webdav_client and not method in ('GET', 'POST'): return NullResource(self, key, request).__of__(self) raise KeyError, key
def __getitem__(self, key): if key in self: return self._getOb(key, None) request = getattr(self, 'REQUEST', None) if not (isinstance(request, str) or request is None): method = request.get('REQUEST_METHOD', 'GET') if (request.maybe_webdav_client and method not in ('GET', 'POST')): if bbb.HAS_ZSERVER: from webdav.NullResource import NullResource return NullResource(self, key, request).__of__(self) raise KeyError(key)
def __getitem__(self, key): value = self._getOb(key, None) if value is not None: return value # WebDAV PUT support if hasattr(self, 'REQUEST'): request = self.REQUEST method = request.get('REQUEST_METHOD', 'GET') if (getattr(request, 'maybe_webdav_client', False) and method not in ('GET', 'POST')): return NullResource(self, key, request).__of__(self) raise KeyError(key)
def __call__(self): context = self.context request = self.request response = request.response content_type = request.getHeader('content-type').strip(';') prefix = self._getPrefix(content_type) name = context.generateUniqueId(prefix) nullresouce = NullResource(context, name, request) nullresouce.__of__(context) nullresouce.PUT(request, response) # fix the request headers to get the correct metadata mappings request = self._updateRequest(request, content_type) # Look it up and finish up, then return it. obj = context._getOb(name) obj.PUT(request, response) obj.setTitle(request['Title']) obj.reindexObject(idxs='Title') return obj
def index_html(self, REQUEST=None, RESPONSE=None): """ Special case index_html """ if 'index_html' in self: return self._getOb('index_html') request = REQUEST if request is None: request = getattr(self, 'REQUEST', None) if request and 'REQUEST_METHOD' in request: if request.maybe_webdav_client: method = request['REQUEST_METHOD'] if method == 'PUT': # Very likely a WebDAV client trying to create something nr = NullResource(self, 'index_html') nr.__replaceable__ = REPLACEABLE return nr elif method in ('GET', 'HEAD', 'POST'): # Do nothing, let it go and acquire. pass else: raise AttributeError('index_html') # Acquire from parent parent = aq_parent(aq_inner(self)) target = parent.aq_acquire('index_html') return ReplaceableWrapper(target).__of__(parent).__of__(self)
def __bobo_traverse__(self, REQUEST, name): # Allows transparent access to session subobjects. # # Sometimes, the request doesn't have a response, e.g. when # PageTemplates traverse through the object path, they pass in # a phony request (a dict). RESPONSE = getattr(REQUEST, 'RESPONSE', None) # Is it a registered sub object data = self.getSubObject(name, REQUEST, RESPONSE) if data is not None: return data # Or a standard attribute (maybe acquired...) target = None method = REQUEST.get('REQUEST_METHOD', 'GET').upper() # Logic from "ZPublisher.BaseRequest.BaseRequest.traverse" # to check whether this is a browser request if (len(REQUEST.get('TraversalRequestNameStack', ())) == 0 and not (method in ('GET', 'HEAD', 'POST') and not isinstance(RESPONSE, xmlrpc.Response))): if shasattr(self, name): target = getattr(self, name) else: if shasattr(self, name): # attributes of self come first target = getattr(self, name) else: # then views gsm = getSiteManager() factory = gsm.adapters.lookup( (providedBy(self), providedBy(REQUEST)), Interface, name ) if factory is not None: # We don't return the view, we raise an # AttributeError instead (below) target = None else: # then acquired attributes target = getattr(self, name, None) if target is not None: return target elif (method not in ('GET', 'POST') and not isinstance(RESPONSE, xmlrpc.Response) and REQUEST.maybe_webdav_client): return NullResource(self, name, REQUEST).__of__(self) else: # Raising AttributeError will look up views for us raise AttributeError(name)
def index_html(self): """Acquire if not present.""" request = getattr(self, 'REQUEST', None) if request and 'REQUEST_METHOD' in request: if request.maybe_webdav_client: method = request['REQUEST_METHOD'] if bbb.HAS_ZSERVER and method in ('PUT', ): # Very likely a WebDAV client trying to create something return ReplaceableWrapper(NullResource(self, 'index_html')) elif method in ('GET', 'HEAD', 'POST'): # Do nothing, let it go and acquire. pass else: raise AttributeError('index_html') # Acquire from parent _target = aq_parent(aq_inner(self)).aq_acquire('index_html') return ReplaceableWrapper(aq_base(_target).__of__(self))
def index_html(self): """ Acquire if not present. """ request = getattr(self, 'REQUEST', None) if (request is not None and 'REQUEST_METHOD' in request and request.maybe_webdav_client): method = request['REQUEST_METHOD'] if bbb.HAS_ZSERVER and method in ('PUT', ): # Very likely a WebDAV client trying to create something result = NullResource(self, 'index_html') setattr(result, '__replaceable__', REPLACEABLE) return result elif method not in ('GET', 'HEAD', 'POST'): raise AttributeError('index_html') # Acquire from skin. _target = self.__getattr__('index_html') result = aq_base(_target).__of__(self) setattr(result, '__replaceable__', REPLACEABLE) return result
def index_html(self, REQUEST=None, RESPONSE=None): """Special case index_html""" request = REQUEST if request is None: request = getattr(self, 'REQUEST', None) if request and request.has_key('REQUEST_METHOD'): if request.maybe_webdav_client: method = request['REQUEST_METHOD'] if method in ('PUT', ): # Very likely a WebDAV client trying to create something return ReplaceableWrapper(NullResource(self, 'index_html')) elif method in ('GET', 'HEAD', 'POST'): # Do nothing, let it go and acquire. pass else: raise AttributeError, 'index_html' # Acquire from parent _target = aq_parent(aq_inner(self)).aq_acquire('index_html') return ReplaceableWrapper(aq_base(_target).__of__(self))
def __bobo_traverse__(self, REQUEST, name=None): try: return getattr(self, name) except AttributeError: pass try: return self[name] except KeyError: pass method = REQUEST.get('REQUEST_METHOD', 'GET') if not method in ('GET', 'POST'): return NullResource(self, name, REQUEST).__of__(self) # Waaa. unrestrictedTraverse calls us with a fake REQUEST. # There is proabably a better fix for this. try: REQUEST.RESPONSE.notFoundError("%s\n%s" % (name, method)) except AttributeError: raise KeyError, name
def _getStaticDocument(self, request, name): try: return self[name] except KeyError: pass document = self.getExtensibleContent(request, name) if document is not None: return aq_base(document).__of__(self) try: return getattr(self, name) except AttributeError: pass # Not found section method = request.get('REQUEST_METHOD', 'GET') if not method in ('GET', 'POST'): return NullResource(self, name, request).__of__(self) # Waaa. unrestrictedTraverse calls us with a fake REQUEST. # There is proabably a better fix for this. try: request.RESPONSE.notFoundError("%s\n%s" % (name, method)) except AttributeError: raise KeyError, name
def __bobo_traverse__(self, REQUEST, name): """Allows transparent access to session subobjects. """ # sometimes, the request doesn't have a response, e.g. when # PageTemplates traverse through the object path, they pass in # a phony request (a dict). RESPONSE = getattr(REQUEST, 'RESPONSE', None) # Is it a registered sub object data = self.getSubObject(name, REQUEST, RESPONSE) if data is not None: return data # Or a standard attribute (maybe acquired...) target = None method = REQUEST.get('REQUEST_METHOD', 'GET').upper() # Logic from "ZPublisher.BaseRequest.BaseRequest.traverse" # to check whether this is a browser request if (len(REQUEST.get('TraversalRequestNameStack', ())) == 0 and # NOQA not (method in ('GET', 'HEAD', 'POST') and not isinstance(RESPONSE, xmlrpc.Response))): if shasattr(self, name): target = getattr(self, name) else: if shasattr(self, name): # attributes of self come first target = getattr(self, name) else: # then views target = queryMultiAdapter((self, REQUEST), Interface, name) if target is not None: # We don't return the view, we raise an # AttributeError instead (below) target = None else: # then acquired attributes target = getattr(self, name, None) if target is not None: logger.debug( 'traverse without explicit acquisition ' 'object=%r name=%r subobject=%r url=%r referer=%r', self, name, target, REQUEST.get('ACTUAL_URL'), REQUEST.get('HTTP_REFERER', '-')) # # STOP TRAVERSING WITHOUT EXPLICIT ACQUISITION # if REQUEST.get('ACTUAL_URL') and ( IContentish.providedBy(target) or # NOQA IPloneSiteRoot.providedBy(target)): logger.warning( 'traverse without explicit acquisition ' 'object=%r name=%r subobject=%r url=%r referer=%r', self, name, target, REQUEST.get('ACTUAL_URL'), REQUEST.get('HTTP_REFERER', '-')) if not config.DRYRUN: target = None if target is not None: return target elif (method not in ('GET', 'POST') and not isinstance(RESPONSE, xmlrpc.Response) and # NOQA REQUEST.maybe_webdav_client): return NullResource(self, name, REQUEST).__of__(self) else: # Raising AttributeError will look up views for us raise AttributeError(name)
def testPUT_factoryAddsImageNoTraverse(self): request = self.app.REQUEST new = NullResource(self.folder, 'image', request).__of__(self.folder) new.PUT(request, request.RESPONSE) self.failUnless(hasattr(aq_base(self.folder), 'image')) self.failUnless(self._exists('image.gif.tmp'))
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 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