示例#1
0
    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, processing, request: Request, response: Response,
                Gateway: Context, Match: Context, **keyargs):
        '''
        @see: HandlerBranchingProceed.process
        
        Obtains the repository.
        '''
        assert isinstance(processing,
                          Processing), 'Invalid processing %s' % processing
        assert isinstance(request, Request), 'Invalid request %s' % request
        if response.isSuccess is False:
            return  # Skip in case the response is in error

        assert isinstance(
            request.decoderHeader, IDecoderHeader
        ), 'Invalid decoder header %s' % request.decoderHeader
        authentication = request.decoderHeader.retrieve(self.nameAuthorization)
        if not authentication: return

        repository = self._repositories.get(authentication)
        if repository is None:
            robj, status, text = self.obtainGateways(processing,
                                                     self.uri % authentication)
            if robj is None or not isSuccess(status):
                if status == BAD_REQUEST.status:
                    response.code, response.status, response.isSuccess = INVALID_AUTHORIZATION
                    if request.repository:
                        assert isinstance(
                            request.repository, IRepository
                        ), 'Invalid repository %s' % request.repository
                        request.match = request.repository.find(
                            request.method, request.headers, request.uri,
                            INVALID_AUTHORIZATION.status)
                else:
                    log.info(
                        'Cannot fetch the authorized gateways from URI \'%s\', with response %s %s',
                        self.uri, status, text)
                    response.code, response.status, response.isSuccess = BAD_GATEWAY
                    response.text = text
                return
            assert 'GatewayList' in robj, 'Invalid objects %s, not GatewayList' % robj
            repository = Repository([
                self.populate(Identifier(Gateway()), obj)
                for obj in robj['GatewayList']
            ], Match)
            self._repositories[authentication] = repository
        self._lastAccess[authentication] = datetime.now()

        if request.repository:
            request.repository = RepositoryJoined(repository,
                                                  request.repository)
        else:
            request.repository = repository
示例#3
0
    def request(self, uri):
        '''
        Request the OPTIONS headers for URI.
        
        @param uri: string
            The URI to call, parameters are allowed.
        @return: dictionary{string: string}|None
            The OPTIONS header or None if OPTIONS has not been delivered successful.
        '''
        assert isinstance(uri, str), 'Invalid URI %s' % uri

        proc = self._processing
        assert isinstance(proc, Processing)

        request = proc.ctx.request()
        assert isinstance(request, RequestHTTP), 'Invalid request %s' % request

        request.scheme, request.method = self._scheme, HTTP_OPTIONS
        request.uri = urlparse(uri).path.lstrip('/')
        request.parameters = []

        arg = proc.execute(FILL_ALL, request=request)
        response, responseCnt = arg.response, arg.responseCnt
        assert isinstance(response,
                          ResponseHTTP), 'Invalid response %s' % response
        assert isinstance(
            responseCnt,
            ResponseContentHTTP), 'Invalid response content %s' % responseCnt

        # We need to ensure that we close the response source.
        if ResponseContentHTTP.source in responseCnt and isinstance(
                responseCnt.source, IClosable):
            responseCnt.source.close()

        if isSuccess(response.status) and ResponseHTTP.headers in response:
            return response.headers

        if __debug__:
            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
            log.error('Cannot get OPTIONS from \'%s\', with response %s %s',
                      request.uri, response.status, text)
示例#4
0
    def populate(self, data, content, response, responseCnt):
        '''
        Populates the content object based on the response and response content.
        
        @param data: Data
            The data to use for content populating.
        @param content: ContentResponse
            The content to populate.
        @param response: ResponseHTTP
            The response to populate the content based on.
        @param responseCnt: ResponseContent
            The response content to populate the content based on.
        @return: ContentResponse
            The populated content.
        '''
        assert isinstance(content,
                          ContentResponse), 'Invalid content %s' % content
        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:
            content.errorStatus, content.errorText = UNAVAILABLE
            return content

        if isinstance(responseCnt.source, IInputStream):
            content.source = responseCnt.source
        elif isinstance(responseCnt.source, Iterable):
            content.source = StreamOnIterable(responseCnt.source)

        if content.charSet: charSet = codecs.lookup(content.charSet).name
        else: charSet = codecs.lookup(self.charSetDefault).name
        content.doEncode = self.createEncode(data, charSet)
        content.doDecode = self.createDecode(charSet)

        if not isSuccess(response.status):
            content.errorStatus = response.status
            if ResponseHTTP.text in response and response.text:
                content.errorText = response.text
            elif ResponseHTTP.code in response and response.code:
                content.errorText = response.code

        return content
示例#5
0
 def populate(self, data, content, response, responseCnt):
     '''
     Populates the content object based on the response and response content.
     
     @param data: Data
         The data to use for content populating.
     @param content: ContentResponse
         The content to populate.
     @param response: ResponseHTTP
         The response to populate the content based on.
     @param responseCnt: ResponseContent
         The response content to populate the content based on.
     @return: ContentResponse
         The populated content.
     '''
     assert isinstance(content, ContentResponse), 'Invalid content %s' % content
     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:
         content.errorStatus, content.errorText = UNAVAILABLE
         return content
     
     if isinstance(responseCnt.source, IInputStream): content.source = responseCnt.source
     elif isinstance(responseCnt.source, Iterable): content.source = StreamOnIterable(responseCnt.source)
     
     if content.charSet: charSet = codecs.lookup(content.charSet).name
     else: charSet = codecs.lookup(self.charSetDefault).name
     content.doEncode = self.createEncode(data, charSet)
     content.doDecode = self.createDecode(charSet)
     
     if not isSuccess(response.status):
         content.errorStatus = response.status
         if ResponseHTTP.text in response and response.text: content.errorText = response.text
         elif ResponseHTTP.code in response and response.code: content.errorText = response.code
     
     return content
示例#6
0
 def process(self, processing, request:Request, response:Response, Gateway:Context, Match:Context, **keyargs):
     '''
     @see: HandlerBranchingProceed.process
     
     Obtains the repository.
     '''
     assert isinstance(processing, Processing), 'Invalid processing %s' % processing
     assert isinstance(request, Request), 'Invalid request %s' % request
     if response.isSuccess is False: return  # Skip in case the response is in error
     
     assert isinstance(request.decoderHeader, IDecoderHeader), 'Invalid decoder header %s' % request.decoderHeader
     authentication = request.decoderHeader.retrieve(self.nameAuthorization)
     if not authentication: return
     
     repository = self._repositories.get(authentication)
     if repository is None:
         robj, status, text = self.obtainGateways(processing, self.uri % authentication)
         if robj is None or not isSuccess(status):
             if status == BAD_REQUEST.status:
                 response.code, response.status, response.isSuccess = INVALID_AUTHORIZATION
                 if request.repository:
                     assert isinstance(request.repository, IRepository), 'Invalid repository %s' % request.repository
                     request.match = request.repository.find(request.method, request.headers, request.uri,
                                                             INVALID_AUTHORIZATION.status)
             else:
                 log.info('Cannot fetch the authorized gateways from URI \'%s\', with response %s %s', self.uri, status, text)
                 response.code, response.status, response.isSuccess = BAD_GATEWAY
                 response.text = text
             return
         assert 'GatewayList' in robj, 'Invalid objects %s, not GatewayList' % robj
         repository = Repository([self.populate(Identifier(Gateway()), obj) for obj in robj['GatewayList']], Match)
         self._repositories[authentication] = repository
     self._lastAccess[authentication] = datetime.now()
     
     if request.repository: request.repository = RepositoryJoined(repository, request.repository)
     else: request.repository = repository
示例#7
0
 def process(self, processing, request:Request, response:Response, Gateway:GatewayRepository, Match:MatchRepository, **keyargs):
     '''
     @see: HandlerBranchingProceed.process
     
     Obtains the repository.
     '''
     assert isinstance(processing, Processing), 'Invalid processing %s' % processing
     assert isinstance(request, Request), 'Invalid request %s' % request
     assert isinstance(response, Response), 'Invalid response %s' % response
     assert issubclass(Gateway, GatewayRepository), 'Invalid gateway class %s' % Gateway
     assert issubclass(Match, MatchRepository), 'Invalid match class %s' % Match
     
     if not self._repository:
         robj, status, text = self.obtainGateways(processing, self.uri)
         if robj is None or not isSuccess(status):
             log.info('Cannot fetch the gateways from URI \'%s\', with response %s %s', self.uri, status, text)
             response.code, response.status, response.isSuccess = BAD_GATEWAY
             response.text = text
             return
         assert 'GatewayList' in robj, 'Invalid objects %s, not GatewayList' % robj
         self._repository = Repository([self.populate(Identifier(Gateway()), obj) for obj in robj['GatewayList']], Match)
         
     if request.repository: request.repository = RepositoryJoined(request.repository, self._repository)
     else: request.repository = self._repository
示例#8
0
    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
示例#9
0
    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
示例#10
0
    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
示例#11
0
    def request(self, uri, details=False, headers=None):
        '''
        Request the JSON object for URI.
        
        @param uri: string
            The URI to call, parameters are allowed.
        @param details: boolean
            If True will provide beside the JSON object also the response status and text.
        @param headers: dictionary{string: string}|None
            Additional headers to be placed on the request.
        @return: object|tuple(object, integer, string)
            Provides the loaded JSON object if details is False, otherwise a tuple containing as the first entry the JSON
            object, None if the object cannot be fetched, on the second position the response status and on the last
            position the response text.
        '''
        assert isinstance(uri, str), 'Invalid URI %s' % uri
        assert isinstance(details, bool), 'Invalid details flag %s' % details
        assert headers is None or isinstance(
            headers, dict), 'Invalid headers %s' % headers

        proc = self._processing
        assert isinstance(proc, Processing)

        request = proc.ctx.request()
        assert isinstance(
            request, RequesterGetJSON.Request), 'Invalid request %s' % request

        url = urlparse(uri)
        request.scheme, request.method = self._scheme, HTTP_GET
        request.uri = url.path.lstrip('/')
        request.parameters = parse_qsl(url.query, True, False)
        request.accTypes = [self._contentType]
        request.accCharSets = [self._encoding]
        request.headers = headers

        arg = proc.execute(FILL_ALL, request=request)
        response, responseCnt = arg.response, 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):
            assert log.error(
                'Cannot get JSON from \'%s\', with response %s %s',
                request.uri, response.status, text) or True
            if details:
                return None, RequesterGetJSON.Error(response.status, text)
            return

        if isinstance(responseCnt.source, IInputStream):
            source = responseCnt.source
        else:
            source = BytesIO()
            for bytes in responseCnt.source:
                source.write(bytes)
            source.seek(0)

        jobj = json.load(codecs.getreader(self._encoding)(source))
        if isinstance(source, IClosable):
            source.close(
            )  # We need to ensure that we close the response source.
        if details: return jobj, RequesterGetJSON.Error(response.status, text)
        return jobj
示例#12
0
    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