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 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 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 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 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 __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.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 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 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 __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 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 obtainGateways(self, processing, uri): ''' Get the gateway objects representation. @param processing: Processing The processing used for delivering the request. @param uri: string The URI to call, parameters are allowed. @return: tuple(dictionary{...}|None, integer, string) A tuple containing as the first position the gateway objects representation, None if the gateways 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, RequestGateway), '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) return json.load(codecs.getreader(self.encodingJson)(source)), response.status, text
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=quote_plus(self.privateKey, safe=''), clientIP=quote_plus(clientIP, safe=''), challenge=quote_plus(challenge, safe=''), resolve=quote_plus(resolve, safe='')) message = message.encode(encoding='ascii') requestCnt.source = (message,) request.headers['Content-Length'] = str(len(message)) request.headers['Content-type'] = 'application/x-www-form-urlencoded' # 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 __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 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 _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.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 __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, 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')
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 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 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 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 _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 __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, 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 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 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')