Beispiel #1
0
 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)
Beispiel #2
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
Beispiel #3
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
Beispiel #4
0
 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))
Beispiel #5
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
Beispiel #6
0
    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)
Beispiel #7
0
 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
Beispiel #8
0
    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)
Beispiel #9
0
    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
Beispiel #10
0
 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
Beispiel #11
0
    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 ()
Beispiel #12
0
    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')
Beispiel #13
0
    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)
Beispiel #14
0
    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)
Beispiel #15
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
Beispiel #16
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=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
Beispiel #17
0
    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)
Beispiel #18
0
    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)
Beispiel #19
0
    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)
Beispiel #20
0
    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))
Beispiel #21
0
    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
Beispiel #23
0
    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')
Beispiel #24
0
    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