def transform(self, context, handler, result): try: acl = result.__acl__ except AttributeError: return result acl = ACL(*acl, context=context) valid = acl.is_authorized if valid.result is False: log.error("Response rejected due to return value authorization failure.", extra=dict( grant = False, predicate = repr(valid.predicate) if valid.predicate else None, path = str(valid.path) if valid.path else None, result = safe_name(type(result)) )) return HTTPForbidden() elif __debug__: log.debug("Successful response authorization.", extra=dict( grant = valid.result, predicate = repr(valid.predicate) if valid.predicate else None, path = str(valid.path) if valid.path else None, result = safe_name(type(result)) )) return result
def mutate(self, context, handler, args, kw): if not context.acl: if __debug__: log.debug("Skipping validation of empty ACL.", extra=dict(request=id(context))) return grant = context.acl.is_authorized if grant.result is False: log.error("Endpoint authorization failed: " + repr(grant), extra=dict( grant = False, predicate = repr(grant.predicate) if grant.predicate else None, path = str(grant.path) if grant.path else None, source = safe_name(grant.source) if grant.source else None )) raise HTTPForbidden() elif __debug__: log.debug("Successful endpoint authorization: " + repr(grant), extra=dict( grant = False, predicate = repr(grant.predicate) if grant.predicate else None, path = str(grant.path) if grant.path else None, source = safe_name(grant.source) if grant.source else None ))
def dispatch(self, context, consumed, handler, is_endpoint): """Called as dispatch descends into a tier. The ACL extension uses this to build up the current request's ACL. """ acl = getattr(handler, '__acl__', ()) inherit = getattr(handler, '__acl_inherit__', True) if __debug__: log.debug("Handling dispatch event: " + repr(handler) + " " + repr(acl), extra=dict( request = id(context), consumed = consumed, handler = safe_name(handler), endpoint = is_endpoint, acl = [repr(i) for i in acl], inherit = inherit, )) if not inherit: if __debug__: log.debug("Clearing collected access control list.") del context.acl[:] context.acl.extend((Path(context.request.path), i, handler) for i in acl)
def _mutate(self, context, endpoint, args, kw): try: if callable(endpoint) and not isroutine(endpoint): endpoint = endpoint.__call__ # Handle instances that are callable. getcallargs(endpoint, *args, **kw) except TypeError as e: # If the argument specification doesn't match, the handler can't process this request. # This is one policy. Another possibility is more computationally expensive and would pass only # valid arguments, silently dropping invalid ones. This can be implemented as a mutate handler. log.error(str(e).replace(endpoint.__name__, safe_name(endpoint)), extra=dict( request = id(context), endpoint = safe_name(endpoint), endpoint_args = args, endpoint_kw = kw, )) raise HTTPNotFound("Incorrect endpoint arguments: " + str(e))
def dispatch(self, context, consumed, handler, is_endpoint): """Called as dispatch descends into a tier. The base extension uses this to maintain the "current url". """ request = context.request if __debug__: log.debug("Handling dispatch event.", extra=dict( request = id(context), consumed = consumed, handler = safe_name(handler), endpoint = is_endpoint )) # The leading path element (leading slash) requires special treatment. if not consumed and context.request.path_info_peek() == '': consumed = [''] nConsumed = 0 if consumed: # Migrate path elements consumed from the `PATH_INFO` to `SCRIPT_NAME` WSGI environment variables. if not isinstance(consumed, (list, tuple)): consumed = consumed.split('/') for element in consumed: if element == context.request.path_info_peek(): context.request.path_info_pop() nConsumed += 1 else: break # Update the breadcrumb list. context.path.append(Crumb(handler, Path(request.script_name))) if consumed: # Lastly, update the remaining path element list. request.remainder = request.remainder[nConsumed:]
def dispatch(self, context, consumed, handler, is_endpoint): """Called as dispatch descends into a tier. The base extension uses this to maintain the "current url". """ request = context.request if __debug__: log.debug("Handling dispatch event.", extra=dict(request=id(context), consumed=consumed, handler=safe_name(handler), endpoint=is_endpoint)) # The leading path element (leading slash) requires special treatment. if not consumed and context.request.path_info_peek() == '': consumed = [''] nConsumed = 0 if consumed: # Migrate path elements consumed from the `PATH_INFO` to `SCRIPT_NAME` WSGI environment variables. if not isinstance(consumed, (list, tuple)): consumed = consumed.split('/') for element in consumed: if element == context.request.path_info_peek(): context.request.path_info_pop() nConsumed += 1 else: break # Update the breadcrumb list. context.path.append(Crumb(handler, Path(request.script_name))) if consumed: # Lastly, update the remaining path element list. request.remainder = request.remainder[nConsumed:]
def handlers(self): return ', '.join(safe_name(i.handler) for i in self._ctx.path)