def checkCaptcha(self, processing, clientIP, challenge, resolve): ''' Checks the filter URI. @param processing: Processing The processing used for delivering the request. @return: boolean True if the captcha is valid, False otherwise. ''' assert isinstance(processing, Processing), 'Invalid processing %s' % processing request, requestCnt = processing.ctx.request( ), processing.ctx.requestCnt() assert isinstance(request, RequestHTTP), 'Invalid request %s' % request assert isinstance( requestCnt, RequestContentHTTP), 'Invalid request content %s' % requestCnt request.scheme, request.method = self.scheme, HTTP_POST request.headers = {} request.uri = self.uriVerify request.parameters = [] message = self.message % dict(key=self.privateKey, clientIP=clientIP, challenge=challenge, resolve=resolve) message = message.encode(encoding='ascii') requestCnt.source = (message, ) request.headers['Content-Length'] = str(len(message)) # TODO: It should be like after integration with refactored: requestCnt.length = len(requestCnt.source) chain = Chain(processing) chain.process(request=request, requestCnt=requestCnt, response=processing.ctx.response(), responseCnt=processing.ctx.responseCnt()).doAll() response, responseCnt = chain.arg.response, chain.arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance( responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt if ResponseContentHTTP.source not in responseCnt or responseCnt.source is None or not isSuccess( response.status): return b'server-error' if isinstance(responseCnt.source, IInputStream): source = responseCnt.source else: source = BytesIO() for bytes in responseCnt.source: source.write(bytes) source.seek(0) content = source.read() if content.startswith(b'true'): return True return content
def obtainFilter(self, processing, uri): ''' Checks the filter URI. @param processing: Processing The processing used for delivering the request. @param uri: string The URI to call, parameters are allowed. @return: tuple(boolean|None, integer, string) A tuple containing as the first True if the filter URI provided a True value, None if the filter cannot be fetched, on the second position the response status and on the last position the response text. ''' assert isinstance(processing, Processing), 'Invalid processing %s' % processing assert isinstance(uri, str), 'Invalid URI %s' % uri request = processing.ctx.request() assert isinstance(request, RequestFilter), 'Invalid request %s' % request url = urlparse(uri) request.scheme, request.method = self.scheme, HTTP_GET request.headers = {} request.uri = url.path.lstrip('/') request.parameters = parse_qsl(url.query, True, False) request.accTypes = [self.mimeTypeJson] request.accCharSets = [self.encodingJson] chain = Chain(processing) chain.process(request=request, requestCnt=processing.ctx.requestCnt(), response=processing.ctx.response(), responseCnt=processing.ctx.responseCnt()).doAll() response, responseCnt = chain.arg.response, chain.arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance( responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt if ResponseHTTP.text in response and response.text: text = response.text elif ResponseHTTP.code in response and response.code: text = response.code else: text = None if ResponseContentHTTP.source not in responseCnt or responseCnt.source is None or not isSuccess( response.status): return None, response.status, text if isinstance(responseCnt.source, IInputStream): source = responseCnt.source else: source = BytesIO() for bytes in responseCnt.source: source.write(bytes) source.seek(0) allowed = json.load(codecs.getreader(self.encodingJson)(source)) return allowed['HasAccess'] == 'True', response.status, text
def _process(self, method): assert isinstance(method, str), 'Invalid method %s' % method proc = self.server.processing assert isinstance(proc, Processing), 'Invalid processing %s' % proc request, requestCnt = proc.ctx.request(), proc.ctx.requestCnt() assert isinstance(request, RequestHTTP), 'Invalid request %s' % request assert isinstance( requestCnt, RequestContentHTTP), 'Invalid request content %s' % requestCnt if RequestHTTP.clientIP in request: request.clientIP = self.client_address[0] url = urlparse(self.path) request.scheme, request.method = HTTP, method.upper() request.headers = dict(self.headers) request.uri = url.path.lstrip('/') request.parameters = parse_qsl(url.query, True, False) requestCnt.source = self.rfile chain = Chain(proc) chain.process( **proc.fillIn(request=request, requestCnt=requestCnt, response=proc.ctx.response(), responseCnt=proc.ctx.responseCnt())).doAll() response, responseCnt = chain.arg.response, chain.arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance( responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt if ResponseHTTP.headers in response and response.headers is not None: for name, value in response.headers.items(): self.send_header(name, value) assert isinstance( response.status, int), 'Invalid response status code %s' % response.status if ResponseHTTP.text in response and response.text: text = response.text elif ResponseHTTP.code in response and response.code: text = response.code else: text = None self.send_response(response.status, text) self.end_headers() if ResponseContentHTTP.source in responseCnt and responseCnt.source is not None: if isinstance(responseCnt.source, IInputStream): source = readGenerator(responseCnt.source) else: source = responseCnt.source for bytes in source: self.wfile.write(bytes)
def _process(self, method): assert isinstance(method, str), 'Invalid method %s' % method proc = self.server.processing assert isinstance(proc, Processing), 'Invalid processing %s' % proc request, requestCnt = proc.ctx.request(), proc.ctx.requestCnt() assert isinstance(request, RequestHTTP), 'Invalid request %s' % request assert isinstance(requestCnt, RequestContentHTTP), 'Invalid request content %s' % requestCnt if RequestHTTP.clientIP in request: request.clientIP = self.client_address[0] url = urlparse(self.path) request.scheme, request.method = HTTP, method.upper() request.headers = dict(self.headers) request.uri = url.path.lstrip('/') request.parameters = parse_qsl(url.query, True, False) requestCnt.source = self.rfile chain = Chain(proc) chain.process(**proc.fillIn(request=request, requestCnt=requestCnt, response=proc.ctx.response(), responseCnt=proc.ctx.responseCnt())) def respond(): response, responseCnt = chain.arg.response, chain.arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance(responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt if ResponseHTTP.headers in response and response.headers is not None: for name, value in response.headers.items(): self.send_header(name, value) assert isinstance(response.status, int), 'Invalid response status code %s' % response.status if ResponseHTTP.text in response and response.text: text = response.text elif ResponseHTTP.code in response and response.code: text = response.code else: text = None self.send_response(response.status, text) self.end_headers() if ResponseContentHTTP.source in responseCnt and responseCnt.source is not None: if isinstance(responseCnt.source, IInputStream): source = readGenerator(responseCnt.source, self.bufferSize) else: source = responseCnt.source self._writeq.append((WRITE_ITER, iter(source))) self._writeq.append((WRITE_CLOSE, None)) chain.callBack(respond) while True: if not chain.do(): self._next(3) # Now we proceed to write stage break if RequestContentHTTPAsyncore.contentReader in requestCnt and requestCnt.contentReader is not None: self._next(2) # Now we proceed to read stage self._reader = requestCnt.contentReader break
def getAnonymous(self): ''' @see: IGatewayService.getAnonymous ''' proc = self._processing assert isinstance(proc, Processing), 'Invalid processing %s' % proc chain = Chain(proc) chain.process(reply=proc.ctx.reply()).doAll() reply = chain.arg.reply assert isinstance(reply, Reply), 'Invalid reply %s' % reply if Reply.gateways not in reply: return () return reply.gateways
def testMethodInvoker(self): handler = MethodInvokerHandler() ioc.initialize(handler) request, response = Request(), Response() node = NodeRoot() request.method, request.path = HTTP_GET, Path([], node) def callProcess(chain, **keyargs): handler.process(**keyargs) chain = Chain([callProcess]) chain.process(request=request, response=response).doAll() self.assertEqual(response.allows, []) self.assertTrue(response.isSuccess is False)
def __call__(self, req): ''' Process the Mongrel2 call. @param req: Request The request to process. ''' assert isinstance(req, Request), 'Invalid request %s' % req proc = self.processing assert isinstance(proc, Processing), 'Invalid processing %s' % proc request, requestCnt = proc.ctx.request(), proc.ctx.requestCnt() assert isinstance(request, RequestHTTP), 'Invalid request %s' % request assert isinstance(requestCnt, RequestContentHTTP), 'Invalid request content %s' % requestCnt if RequestHTTP.clientIP in request: request.clientIP = req.headers.pop('x-forwarded-for') request.scheme, request.method = self.scheme, req.headers.pop('METHOD').upper() request.parameters = parse_qsl(req.headers.pop('QUERY', ''), True, False) request.headers = dict(req.headers) request.uri = req.path.lstrip('/') if isinstance(req.body, IInputStream): requestCnt.source = req.body else: requestCnt.source = BytesIO(req.body) chain = Chain(proc) chain.process(**proc.fillIn(request=request, requestCnt=requestCnt, response=proc.ctx.response(), responseCnt=proc.ctx.responseCnt())).doAll() response, responseCnt = chain.arg.response, chain.arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance(responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt responseHeaders = dict(self.defaultHeaders) if ResponseHTTP.headers in response and response.headers is not None: responseHeaders.update(response.headers) assert isinstance(response.status, int), 'Invalid response status code %s' % response.status if ResponseHTTP.text in response and response.text: text = response.text elif ResponseHTTP.code in response and response.code: text = response.code else: try: text, _long = BaseHTTPRequestHandler.responses[response.status] except KeyError: text = '???' self._respond(req, response.status, text, responseHeaders) if ResponseContentHTTP.source in responseCnt and responseCnt.source is not None: req.push(responseCnt.source) self._end(req)
def testTextConversion(self): handler = ConversionSetHandler() handler.normalizer = Normalizer() handler.converter = Converter() ioc.initialize(handler) requestCnt, response = Content(), Content() def callProcess(chain, **keyargs): handler.process(**keyargs) chain = Chain([callProcess]) chain.process(requestCnt=requestCnt, response=response).doAll() self.assertEqual(handler.normalizer, requestCnt.normalizer) self.assertEqual(handler.normalizer, response.normalizer) self.assertEqual(handler.converter, response.converter) self.assertEqual(handler.converter, response.converter)
def authenticate(self, session): ''' @see: IAuthenticationService.authenticate ''' olderThan = self.session().query(current_timestamp()).scalar() olderThan -= self._sessionTimeOut sql = self.session().query(LoginMapped) sql = sql.filter(LoginMapped.Session == session) sql = sql.filter(LoginMapped.AccessedOn > olderThan) try: login = sql.one() except NoResultFound: raise InputError(Ref(_('Invalid session'), ref=Login.Session)) assert isinstance(login, LoginMapped), 'Invalid login %s' % login login.AccessedOn = current_timestamp() self.session().flush((login, )) self.session().expunge(login) commitNow() # We need to fore the commit because if there is an exception while processing the request we need to make # sure that the last access has been updated. proc = self._processing assert isinstance(proc, Processing), 'Invalid processing %s' % proc solicitation = proc.ctx.solicitation() assert isinstance( solicitation, Solicitation), 'Invalid solicitation %s' % solicitation solicitation.userId = login.User solicitation.types = self.acl.types chain = Chain(proc) chain.process(**proc.fillIn(solicitation=solicitation, reply=proc.ctx.reply())).doAll() reply = chain.arg.reply assert isinstance(reply, Reply), 'Invalid reply %s' % reply if reply.gateways is None: return () return sorted(reply.gateways, key=lambda gateway: (gateway.Pattern, gateway.Methods))
def processParsing(self, parsing, request, requestCnt, response, responseCnt, **keyargs): ''' Process the parsing for the provided contexts. @return: boolean True if the parsing has been successfully done on the request content. ''' assert isinstance(parsing, Processing), 'Invalid processing %s' % parsing assert isinstance(request, Request), 'Invalid request %s' % request assert isinstance( requestCnt, RequestContent), 'Invalid request content %s' % requestCnt assert isinstance(response, Response), 'Invalid response %s' % response assert isinstance( responseCnt, ResponseContent), 'Invalid response content %s' % responseCnt # Resolving the character set if requestCnt.charSet: try: codecs.lookup(requestCnt.charSet) except LookupError: requestCnt.charSet = self.charSetDefault else: requestCnt.charSet = self.charSetDefault if not requestCnt.type: requestCnt.type = responseCnt.type chain = Chain(parsing) chain.process(request=request, requestCnt=requestCnt, response=response, responseCnt=responseCnt, **keyargs) if not chain.doAll().isConsumed(): return True if response.isSuccess is not False: response.code, response.isSuccess = ENCODING_UNKNOWN response.text = 'Content type \'%s\' not supported for parsing' % requestCnt.type
def __call__(self): ''' Provides the next multi part request content based on the provided multi part stream. ''' if self._nextCnt is not None: return self._nextCnt stream, processing = self._stream, self._processing assert isinstance(stream, StreamMultiPart), 'Invalid stream %s' % stream assert isinstance(processing, Processing), 'Invalid processing %s' % processing if not stream._flag & (FLAG_CONTENT_END | FLAG_MARK_END): if not stream._flag & FLAG_MARK_START: while True: stream._readToMark(self._data.packageSize) if stream._flag & FLAG_MARK_START: break if stream._flag & FLAG_END: return req = processing.ctx.request() self._nextCnt = reqCnt = self._requestCnt.__class__() assert isinstance(req, RequestPopulate), 'Invalid request %s' % req assert isinstance( reqCnt, RequestContentMultiPart), 'Invalid request content %s' % reqCnt req.headers = stream._pullHeaders() if stream._flag & FLAG_CLOSED: stream._flag ^= FLAG_CLOSED reqCnt.source = stream reqCnt.fetchNextContent = NextContent(reqCnt, self._response, self._processing, self._data, stream) reqCnt.previousContent = self._requestCnt chain = Chain(self._processing).process(request=req, requestCnt=reqCnt, response=self._response) return chain.doAll().arg.requestCnt
def _process(self, method): assert isinstance(method, str), 'Invalid method %s' % method proc = self.server.processing assert isinstance(proc, Processing), 'Invalid processing %s' % proc request, requestCnt = proc.ctx.request(), proc.ctx.requestCnt() assert isinstance(request, RequestHTTP), 'Invalid request %s' % request assert isinstance( requestCnt, RequestContentHTTP), 'Invalid request content %s' % requestCnt if RequestHTTP.clientIP in request: request.clientIP = self.client_address[0] url = urlparse(self.path) request.scheme, request.method = HTTP, method.upper() request.uri = url.path.lstrip('/') if RequestHTTP.headers in request: request.headers = dict(self.headers) if RequestHTTP.parameters in request: request.parameters = parse_qsl(url.query, True, False) chain = Chain(proc, FILL_ALL, request=request, requestCnt=requestCnt) chain.onFinalize(self._processRespond) if RequestContentHTTPAsyncore.doContentReader in requestCnt: while True: if not chain.do(): self._readContinue() break if requestCnt.doContentReader: assert callable( requestCnt.doContentReader ), 'Invalid content reader %s' % requestCnt.doContentReader self._chain, self._reader = chain, requestCnt.doContentReader self._readContent() # Now we proceed to read content stage break else: self._readContinue() chain.execute()
def process(self, chain, redirect, request: Request, response: Response, **keyargs): ''' @see: HandlerBranching.process Process the redirect. ''' assert isinstance(chain, Chain), 'Invalid processors chain %s' % chain assert isinstance(redirect, Processing), 'Invalid processing %s' % redirect assert isinstance(request, Request), 'Invalid request %s' % request assert isinstance(response, Response), 'Invalid response %s' % response if response.isSuccess is not False: # Skip in case the response is in error assert isinstance( request.invoker, Invoker), 'Invalid request invoker %s' % request.invoker assert isinstance( response.encoderHeader, IEncoderHeader ), 'Invalid header encoder %s' % response.encoderHeader assert isinstance( response.encoderPath, IEncoderPath), 'Invalid encoder path %s' % response.encoderPath typ = request.invoker.output if isinstance(typ, TypeModelProperty): typ = typ.type if isinstance(typ, TypeReference): Chain(redirect).process(request=request, response=response, **keyargs).doAll() if response.isSuccess is not False: response.encoderHeader.encode( self.nameLocation, response.encoderPath.encode(response.obj)) response.code, response.status, response.isSuccess = REDIRECT return chain.proceed()
def getAll(self, userId, path=None, origPath=None): ''' @see: IUserActionService.getAll ''' assert isinstance(userId, int), 'Invalid user id %s' % userId proc = self._processing assert isinstance(proc, Processing), 'Invalid processing %s' % proc solicitation = proc.ctx.solicitation() assert isinstance( solicitation, Solicitation), 'Invalid solicitation %s' % solicitation solicitation.userId = userId solicitation.types = (self.actionType, ) chain = Chain(proc) chain.process(solicitation=solicitation, reply=proc.ctx.reply()).doAll() reply = chain.arg.reply assert isinstance(reply, Reply), 'Invalid reply %s' % reply if Reply.rightsAvailable not in reply: return () actionPaths = set() for aclRight in reply.rightsAvailable: if isinstance(aclRight, RightAction): assert isinstance(aclRight, RightAction) for action in aclRight.actions(): assert isinstance(action, Action) actionPaths.add(action.Path) actions = [] for action in self.actionManagerService.getAll(path): if action.Path in actionPaths: actions.append(action) return processChildCount(actions)
def process(self, processing, request: Request, response: Response, **keyargs): ''' @see: HandlerBranchingProceed.process Filter the invoking if is the case. ''' assert isinstance(processing, Processing), 'Invalid processing %s' % processing assert isinstance(request, Request), 'Invalid request %s' % request assert isinstance(response, Response), 'Invalid response %s' % response if response.isSuccess is False: return # Skip in case the response is in error assert isinstance( request.decoderHeader, IDecoderHeader ), 'Invalid header decoder %s' % request.decoderHeader authenticated = request.decoderHeader.retrieve(self.nameHeader) if not authenticated: return # Skip if no authenticated header is provided try: userId = int(authenticated) except ValueError: response.code, response.status, response.isSuccess = HEADER_ERROR response.text = 'Invalid value for \'%s\'' % self.nameHeader return assert isinstance(request.path, Path), 'Invalid path %s' % request.path assert isinstance(request.invoker, Invoker), 'Invalid invoker %s' % request.invoker assert isinstance(request.arguments, dict), 'Invalid arguments %s' % request.arguments solFilter = processing.ctx.solicitation() assert isinstance(solFilter, SolicitationFilter) solFilter.userId = userId solFilter.method = request.invoker.method solFilter.types = self.acl.types chainFilter = Chain(processing) chainFilter.process( **processing.fillIn(solicitation=solFilter, **keyargs)).doAll() solFilter = chainFilter.arg.solicitation assert isinstance( solFilter, SolicitationFilter), 'Invalid solicitation %s' % solFilter if solFilter.permissions is None: return # No permissions available permissions = [] for permission in solFilter.permissions: assert isinstance( permission, PermissionFilter), 'Invalid permission %s' % permission if permission.path.node == request.path.node and permission.filtersModels: permissions.append(permission) if not permissions: return # There is no permission to filter by so nothing to do assert len(permissions > 1 ), 'To many permissions:\n%s\n, for filtering' % '\n'.join( str(perm) for perm in permissions) permission = permissions[0] assert isinstance( permission.filtersModels, list), 'Invalid model filters %s' % permission.filtersModels for modelFilter in permission.filtersModels: assert isinstance( modelFilter, ModelFilter), 'Invalid model filter %s' % modelFilter assert isinstance(modelFilter.filters, list), 'Invalid filters %s' % modelFilter.filters modelObj = request.arguments.get(modelFilter.inputName) if modelObj is None: continue # No model present to filter propertyObj = getattr(modelObj, modelFilter.propertyName) if propertyObj is None: continue # No property value present to filter for filterAcl in modelFilter.filters: assert isinstance(filterAcl, Filter), 'Invalid filter %s' % filterAcl assert isinstance( filterAcl.filter, IAclFilter), 'Invalid filter service %s' % filterAcl.filter assert isinstance( filterAcl.authenticated, TypeProperty ), 'Invalid authenticated %s' % filterAcl.authenticated clazz = filterAcl.authenticated.parent.clazz if clazz != User and not issubclass(clazz, User): continue # Not a user authenticated type if not filterAcl.filter.isAllowed(userId, propertyObj): response.code, response.status, response.isSuccess = FORBIDDEN_ACCESS return
def __call__(self, context, respond): ''' Process the WSGI call. ''' assert isinstance(context, dict), 'Invalid context %s' % context assert callable(respond), 'Invalid respond callable %s' % respond proc = self.processing assert isinstance(proc, Processing), 'Invalid processing %s' % proc request, requestCnt = proc.ctx.request(), proc.ctx.requestCnt() assert isinstance(request, RequestHTTP), 'Invalid request %s' % request assert isinstance( requestCnt, RequestContentHTTP), 'Invalid request content %s' % requestCnt if RequestHTTP.clientIP in request: request.clientIP = context.get('HTTP_X_FORWARDED_FOR') if request.clientIP: request.clientIP = request.clientIP.split(',')[-1].strip() else: request.clientIP = context.get('REMOTE_ADDR') request.scheme, request.method = context.get('wsgi.url_scheme', '').upper(), context.get( 'REQUEST_METHOD', '').upper() request.headers = { hname[self.headerPrefixLen:].replace('_', '-'): hvalue for hname, hvalue in context.items() if hname.startswith(self.headerPrefix) } request.headers.update({ hname.replace('_', '-'): hvalue for hname, hvalue in context.items() if hname in self.headers }) request.uri = context.get('PATH_INFO', '').lstrip('/') request.parameters = parse_qsl(context.get('QUERY_STRING', ''), True, False) requestCnt.source = context.get('wsgi.input') chain = Chain(proc) chain.process(request=request, requestCnt=requestCnt, response=proc.ctx.response(), responseCnt=proc.ctx.responseCnt()).doAll() response, responseCnt = chain.arg.response, chain.arg.responseCnt assert isinstance(response, ResponseHTTP), 'Invalid response %s' % response assert isinstance( responseCnt, ResponseContentHTTP), 'Invalid response content %s' % responseCnt responseHeaders = dict(self.defaultHeaders) if ResponseHTTP.headers in response and response.headers is not None: responseHeaders.update(response.headers) assert isinstance( response.status, int), 'Invalid response status code %s' % response.status if ResponseHTTP.text in response and response.text: status = '%s %s' % (response.status, response.text) elif ResponseHTTP.code in response and response.code: status = '%s %s' % (response.status, response.code) else: status = str(response.status) respond(status, list(responseHeaders.items())) if ResponseContentHTTP.source in responseCnt and responseCnt.source is not None: if isinstance(responseCnt.source, IInputStream): return readGenerator(responseCnt.source) return responseCnt.source return ()
def process(self, rendering, request: Request, response: Response, responseCnt: ResponseContent, **keyargs): ''' @see: HandlerBranchingProceed.process Create the render for the response object. ''' assert isinstance(rendering, Processing), 'Invalid processing %s' % rendering assert isinstance(request, Request), 'Invalid request %s' % request assert isinstance(response, Response), 'Invalid response %s' % response assert isinstance( responseCnt, ResponseContent), 'Invalid response content %s' % responseCnt # Resolving the character set if responseCnt.charSet: try: codecs.lookup(responseCnt.charSet) except LookupError: responseCnt.charSet = None else: responseCnt.charSet = None if not responseCnt.charSet: if Request.accCharSets in request and request.accCharSets is not None: for charSet in request.accCharSets: try: codecs.lookup(charSet) except LookupError: continue responseCnt.charSet = charSet break if not responseCnt.charSet: responseCnt.charSet = self.charSetDefault resolved = False if responseCnt.type: renderChain = Chain(rendering) renderChain.process(request=request, response=response, responseCnt=responseCnt, **keyargs) if renderChain.doAll().isConsumed(): if response.isSuccess is not False: response.code, response.isSuccess = ENCODING_UNKNOWN response.text = 'Content type \'%s\' not supported for rendering' % responseCnt.type else: resolved = True if not resolved: # Adding None in case some encoder is configured as default. if Request.accTypes in request and request.accTypes is not None: contentTypes = itertools.chain(request.accTypes, self.contentTypeDefaults) else: contentTypes = self.contentTypeDefaults for contentType in contentTypes: responseCnt.type = contentType renderChain = Chain(rendering) renderChain.process(request=request, response=response, responseCnt=responseCnt, **keyargs) if not renderChain.doAll().isConsumed(): break else: raise DevelError( 'There is no renderer available, this is more likely a setup issues since the ' 'default content types should have resolved the renderer')