Пример #1
0
def init_events(path, msg=''):
    ev = Events()
    if msg:
        ev.store('Init', '{} {} {}'.format(10 * '=', msg, 10 * '='))
    else:
        ev.store('Init', 40 * '=')
    req = HTTPRequest(path, method=cherrypy.request.method)
    try:
        req.authz = cherrypy.request.headers['Authorization']
    except KeyError:
        pass
    ev.store(EV_HTTP_REQUEST, req)
    return ev
Пример #2
0
def init_events(path, msg=''):
    ev = Events()
    if msg:
        ev.store('Init', '{} {} {}'.format(10 * '=', msg, 10 * '='))
    else:
        ev.store('Init', 40 * '=')
    req = HTTPRequest(path, method=cherrypy.request.method)
    try:
        req.authz = cherrypy.request.headers['Authorization']
    except KeyError:
        pass
    ev.store(EV_HTTP_REQUEST, req)
    return ev
Пример #3
0
class Application(object):
    def __init__(self, base_url, **kwargs):
        self.base_url = base_url
        self.kwargs = kwargs
        self.events = Events()
        self.endpoints = {}
        self.session_conf = {}

    def store_response(self, response):
        self.events.store(EV_RESPONSE, response.info())

    def wsgi_wrapper(self, environ, func, **kwargs):
        kwargs = extract_from_request(environ, kwargs)
        self.events.store(EV_REQUEST, kwargs)
        args = func(**kwargs)

        try:
            resp, state = args
            self.store_response(resp)
            return resp
        except TypeError:
            resp = args
            self.store_response(resp)
            return resp
        except Exception as err:
            logger.error("%s" % err)
            raise

    def handle(self, environ, tester, sid, path, qs=''):
        _sh = tester.sh
        if qs:
            msg = qs
        else:
            try:
                msg = get_or_post(environ)
            except AttributeError:
                msg = {}

        filename = self.kwargs['profile_handler'](_sh).log_path(
            sid, _sh['conv'].test_id)

        _sh['conv'].entity_id = sid
        return tester.do_next(msg, filename,
                              profile_handler=self.kwargs['profile_handler'],
                              path=path)

    @staticmethod
    def pick_grp(name):
        return name.split('-')[1]

    # publishes the OP endpoints
    def application(self, environ, start_response):
        logger.info("Connection from: %s" % environ["REMOTE_ADDR"])
        session = environ['beaker.session']

        path = environ.get('PATH_INFO', '').lstrip('/')
        logger.info("path: %s" % path)
        self.events.store(EV_REQUEST, path)

        try:
            sh = session['session_info']
        except KeyError:
            sh = SessionHandler(**self.kwargs)
            sh.session_init()
            session['session_info'] = sh

        inut = WebIO(session=sh, **self.kwargs)
        inut.environ = environ
        inut.start_response = start_response

        tester = WebTester(inut, sh, **self.kwargs)

        if path == "robots.txt":
            return static_mime("static/robots.txt", environ, start_response)
        elif path.startswith("static/"):
            return static_mime(path, environ, start_response)
        elif path == "list":
            try:
                qs = parse_qs(get_post(environ))
            except Exception as err:
                pass
            else:
                sh['test_conf'] = dict([(k,v[0]) for k,v in qs.items()])
                self.session_conf[sh['sid']] = sh

            return tester.display_test_list()
        elif path == '' or path == 'config':
            sid = rndstr(24)
            sh['sid'] = sid
            try:
                args = sh['test_conf']
            except:
                args = {}
            return tester.do_config(sid, **args)
        elif path in self.kwargs['flows'].keys():  # Run flow
            try:
                _ = tester.sh['test_conf']
            except KeyError:
                resp = SeeOther('/')
                return resp(environ, start_response)
            try:
                _sid = tester.sh['sid']
            except KeyError:
                _sid = rndstr(24)
                tester.sh['sid'] = _sid
                self.session_conf[_sid] = sh

            resp = tester.run(path, sid=_sid, **self.kwargs)
            if isinstance(resp, requests.Response):
                loc = resp.headers['location']
                #tester.conv.events.store('Cookie', resp.headers['set-cookie'])
                if loc.startswith(tester.base_url):
                    path = loc[len(tester.base_url):]
                else:
                    return resp
            elif resp is True or resp is False or resp is None:
                return tester.display_test_list()
            else:
                return resp(environ, start_response)
        elif path == 'display':
            return inut.flow_list()
        elif path == "opresult":
            resp = SeeOther(
                "/display#{}".format(self.pick_grp(sh['conv'].test_id)))
            return resp(environ, start_response)
        elif path.startswith("test_info"):
            p = path.split("/")
            try:
                return inut.test_info(p[1])
            except KeyError:
                return inut.not_found()
        elif path == 'all':
            for test_id in sh['flow_names']:
                resp = tester.run(test_id, **self.kwargs)
                if resp is True or resp is False:
                    continue
                elif resp:
                    return resp(environ, start_response)
                else:
                    resp = ServiceError('Unkown service error')
                    return resp(environ, start_response)
            return tester.display_test_list()

        # Whatever gets here should be of the form <session_id>/<path>
        try:
            sid, _path = path.split('/', 1)
        except ValueError:
            pass
        else:
            if _path.startswith("static/"):
                return static_mime(_path, environ, start_response)

            try:
                _sh = self.session_conf[sid]
            except KeyError:
                resp = ServiceError("Unknown session")
                return resp(environ, start_response)

            tester.sh = _sh
            if 'HTTP_AUTHORIZATION' in environ:
                _sh['conv'].events.store('HTTP_AUTHORIZATION',
                                      environ['HTTP_AUTHORIZATION'])
            _p = _path.split('?')
            if _p[0] in _sh['conv'].entity.endpoints():
                resp = self.handle(environ, tester, sid, *_p)
                self.session_conf[sid] = tester.sh
                return resp(environ, start_response)

            for endpoint, service in self.endpoints.items():
                if _path == endpoint:
                    logger.info("service: {}".format(service))
                    try:
                        resp = self.handle(environ, tester, sid, service)
                        return resp(environ, start_response)
                    except Exception as err:
                        print("%s" % err)
                        message = traceback.format_exception(*sys.exc_info())
                        print(message)
                        logger.exception("%s" % err)
                        resp = ServiceError("%s" % err)
                        return resp(environ)

        logger.debug("unknown side: %s" % path)
        resp = NotFound("Couldn't find the side you asked for!")
        return resp(environ, start_response)
Пример #4
0
class Application(object):
    def __init__(self, base_url, **kwargs):
        self.base_url = base_url
        self.kwargs = kwargs
        self.events = Events()
        self.endpoints = {}
        self.session_conf = {}
        self.internal = kwargs['internal']

    def store_response(self, response):
        self.events.store(EV_RESPONSE, response.info())

    def wsgi_wrapper(self, environ, func, **kwargs):
        kwargs = extract_from_request(environ, kwargs)
        self.events.store(EV_REQUEST, kwargs)
        args = func(**kwargs)

        try:
            resp, state = args
            self.store_response(resp)
            return resp
        except TypeError:
            resp = args
            self.store_response(resp)
            return resp
        except Exception as err:
            logger.error("%s" % err)
            raise

    def handle(self, environ, tester, sid, path, qs=''):
        _sh = tester.sh
        if qs:
            msg = qs
        else:
            try:
                msg = get_or_post(environ)
            except AttributeError:
                msg = {}

        filename = self.kwargs['profile_handler'](_sh).log_path(
            sid=sid, test_id=_sh['conv'].test_id)

        _sh['conv'].entity_id = sid
        return tester.do_next(msg, filename,
                              profile_handler=self.kwargs['profile_handler'],
                              path=path)

    @staticmethod
    def pick_grp(name):
        return name.split('-')[1]

    @staticmethod
    def see_other_to_get(resp, sh):
        loc = resp.message
        res = sh['conv'].entity.server.http_request(loc, 'GET')
        return res

    def store_session_handler(self, sh):
        sid = rndstr(24)
        while sid in self.session_conf:
            sid = rndstr(24)
        sh['sid'] = sid
        self.session_conf[sid] = sh
        return sid

    def init_session(self, tester, sh, test_id=''):
        sid = self.store_session_handler(sh)
        # session['session_info'] = sh
        try:
            del self.session_conf[sid]['flow']
        except KeyError:
            pass

        try:
            args = sh['test_conf']
        except:
            args = {}

        args['test_id'] = test_id
        return tester.do_config(sid, **args)

    def run_test(self, tester, _path, _sid, environ, start_response):
        _op = '{} {}'.format(environ['REQUEST_METHOD'], _path)
        resp = tester.run(_path, sid=_sid, op=_op, **self.kwargs)
        if resp:
            logger.info(
                'Response class: {}'.format(resp.__class__.__name__))

        if isinstance(resp, requests.Response):
            try:
                loc = resp.headers['location']
            except KeyError:
                logger.info(
                    'Response type: {}, missing location'.format(
                        type(resp)))
                resp = ServiceError(
                    'Wrong response: {}:{}'.format(resp.status_code,
                                                   resp.text))
                return resp(environ, start_response), 0
            else:
                try:
                    tester.conv.events.store('Cookie',
                                             resp.headers['set-cookie'])
                except KeyError:
                    pass
                # For me !
                if loc.startswith(tester.base_url):
                    _path = loc[len(tester.base_url):]
                    if _path[0] == '/':
                        _path = _path[1:]
                    return 0, _path
                else:
                    if self.internal:
                        _url = absolute_url(loc,
                                            tester.sh['test_conf'][
                                                'start_page'])
                        logging.info('Redirect not to me => {}'.format(_url))
                        res = tester.conv.entity.server.http_request(_url)
                        logging.info('{} response'.format(res.status_code))
                        logging.debug('txt: {}'.format(res.text))
                        res = tester.display_test_list()
                        return res, 0
                    else:
                        res = SeeOther(loc)
                        return res(environ, start_response), 0
        elif resp is True or resp is False or resp is None:
            return tester.display_test_list(), 0
        else:
            return resp(environ, start_response), 0

    # publishes the OP endpoints
    def application(self, environ, start_response):
        session = environ['beaker.session']

        jlog = JLog(logger, session.id)
        path = environ.get('PATH_INFO', '').lstrip('/')
        jlog.info({"remote_addr": environ["REMOTE_ADDR"],
                   "path": path})

        # self.events.store(EV_REQUEST, path)

        try:
            sh = session['session_info']
        except KeyError:
            sh = SessionHandler(**self.kwargs)
            #sh.session_init()
            session['session_info'] = sh

        info = WebIh(session=sh, **self.kwargs)
        info.environ = environ
        info.start_response = start_response

        tester = WebTester(info, sh, **self.kwargs)

        if 'path' in self.kwargs and path.startswith(self.kwargs['path']):
            _path = path[len(kwargs['path']) + 1:]
        else:
            _path = path

        if _path == "robots.txt":
            return static_mime("static/robots.txt", environ, start_response)
        elif _path.startswith("static/"):
            return static_mime(_path, environ, start_response)

        if _path == "list":
            try:
                qs = parse_qs(get_or_post(environ))
            except Exception as err:
                jlog.error({'message': err})
                qs = {}
            else:
                if qs:
                    sh['test_conf'] = dict([(k, v[0]) for k, v in qs.items()])
                    # self.session_conf[sh['sid']] = sh
                else:
                    return self.init_session(tester, sh)

                logger.info('test_conf: {}'.format(sh['test_conf']))

                if 'start_page' not in sh['test_conf']:
                    resp = BadRequest('You MUST provide a start_page')
                    return resp(environ, start_response)

            info.profile = tester.sh.profile = qs['response_type'][0]
            sh.session_init()

            if 'test_id' in qs:
                (res, _path) = self.run_test(tester, qs['test_id'][0],
                                             sh['sid'], environ,
                                             start_response)
                if res:
                    return res
            else:
                res = tester.display_test_list()
                return res
        elif _path == '' or _path == 'config':
            return self.init_session(tester, sh)
        elif _path in self.kwargs['flows'].keys():  # Run flow
            # Will use the same test configuration
            try:
                _ = tester.sh['test_conf']
            except KeyError:
                return self.init_session(tester, sh)

            try:
                _sid = tester.sh['sid']
            except KeyError:
                _sid = self.store_session_handler(sh)

            # First time around this should not be set
            try:
                _ = self.session_conf[_sid]['flow']
            except KeyError:
                pass
            else:
                return self.init_session(tester, sh, _path)

            (res, _path) = self.run_test(tester, _path, _sid, environ,
                                         start_response)
            if res:
                return res
        elif _path == 'display':
            return info.flow_list()
        elif _path == "opresult":
            try:
                _display_path = '/{}/display'.format(self.kwargs['path'])
            except KeyError:
                _display_path = '/display'
            resp = SeeOther(
                "{}#{}".format(_display_path,
                               self.pick_grp(sh['conv'].test_id)))
            return resp(environ, start_response)
        elif _path.startswith("test_info"):
            p = _path.split("/")
            try:
                return info.test_info(p[1])
            except KeyError:
                return info.not_found()
        elif _path == 'all':
            for test_id in sh['flow_names']:
                resp = tester.run(test_id, **self.kwargs)
                if resp is True or resp is False:
                    continue
                elif resp:
                    return resp(environ, start_response)
                else:
                    resp = ServiceError('Unkown service error')
                    return resp(environ, start_response)
            return tester.display_test_list()

        # Whatever gets here should be of the form <session_id>/<path>
        try:
            sid, _path = _path.split('/', 1)
        except ValueError:
            pass
        else:
            if _path.startswith("static/"):
                return static_mime(_path, environ, start_response)

            try:
                _sh = self.session_conf[sid]
            except KeyError:
                resp = ServiceError("Unknown session")
                return resp(environ, start_response)

            tester.sh = _sh
            if 'HTTP_AUTHORIZATION' in environ:
                _sh['conv'].events.store('HTTP_AUTHORIZATION',
                                         environ['HTTP_AUTHORIZATION'])
            _p = _path.split('?')
            _sh['conv'].events.store('http request', '{} /{}'.format(
                environ['REQUEST_METHOD'], _path))
            if _p[0] in _sh['conv'].entity.endpoints():
                resp = self.handle(environ, tester, sid, *_p)
                self.session_conf[sid] = tester.sh
                # The only redirect should be the one to the redirect_uri
                if isinstance(resp, SeeOther):
                    if self.internal:
                        # res = self.see_other_to_get(resp, sh)
                        # res is probably a redirect
                        # send the user back to the test list page
                        return info.flow_list()
                    else:
                        return resp(environ, start_response)
                elif isinstance(resp, Response):
                    return resp(environ, start_response)
                else:
                    return resp

            for endpoint, service in self.endpoints.items():
                if _path == endpoint:
                    jlog.info({"service": service})
                    try:
                        resp = self.handle(environ, tester, sid, service)
                        return resp(environ, start_response)
                    except Exception as err:
                        print("%s" % err)
                        message = traceback.format_exception(*sys.exc_info())
                        print(message)
                        jlog.exception(err)
                        resp = ServiceError("%s" % err)
                        return resp(environ)

        jlog.debug({"unknown side": path})
        resp = NotFound("Couldn't find the side you asked for!")
        return resp(environ, start_response)
Пример #5
0
class Application(object):
    def __init__(self, base_url, **kwargs):
        self.base_url = base_url
        self.kwargs = kwargs
        self.events = Events()
        self.endpoints = {}
        self.session_conf = {}

    def store_response(self, response):
        self.events.store(EV_RESPONSE, response.info())

    def wsgi_wrapper(self, environ, func, **kwargs):
        kwargs = extract_from_request(environ, kwargs)
        self.events.store(EV_REQUEST, kwargs)
        args = func(**kwargs)

        try:
            resp, state = args
            self.store_response(resp)
            return resp
        except TypeError:
            resp = args
            self.store_response(resp)
            return resp
        except Exception as err:
            logger.error("%s" % err)
            raise

    def handle(self, environ, tester, sid, path, qs=''):
        _sh = tester.sh
        if qs:
            msg = qs
        else:
            try:
                msg = get_or_post(environ)
            except AttributeError:
                msg = {}

        filename = self.kwargs['profile_handler'](_sh).log_path(
            sid, _sh['conv'].test_id)

        _sh['conv'].entity_id = sid
        return tester.do_next(msg,
                              filename,
                              profile_handler=self.kwargs['profile_handler'],
                              path=path)

    @staticmethod
    def pick_grp(name):
        return name.split('-')[1]

    # publishes the OP endpoints
    def application(self, environ, start_response):
        logger.info("Connection from: %s" % environ["REMOTE_ADDR"])
        session = environ['beaker.session']

        path = environ.get('PATH_INFO', '').lstrip('/')
        logger.info("path: %s" % path)
        self.events.store(EV_REQUEST, path)

        try:
            sh = session['session_info']
        except KeyError:
            sh = SessionHandler(**self.kwargs)
            sh.session_init()
            session['session_info'] = sh

        inut = WebIO(session=sh, **self.kwargs)
        inut.environ = environ
        inut.start_response = start_response

        tester = WebTester(inut, sh, **self.kwargs)

        if path == "robots.txt":
            return static_mime("static/robots.txt", environ, start_response)
        elif path.startswith("static/"):
            return static_mime(path, environ, start_response)
        elif path == "list":
            try:
                qs = parse_qs(get_post(environ))
            except Exception as err:
                pass
            else:
                sh['test_conf'] = dict([(k, v[0]) for k, v in qs.items()])
                self.session_conf[sh['sid']] = sh

            return tester.display_test_list()
        elif path == '' or path == 'config':
            sid = rndstr(24)
            sh['sid'] = sid
            try:
                args = sh['test_conf']
            except:
                args = {}
            return tester.do_config(sid, **args)
        elif path in self.kwargs['flows'].keys():  # Run flow
            try:
                _ = tester.sh['test_conf']
            except KeyError:
                resp = SeeOther('/')
                return resp(environ, start_response)
            try:
                _sid = tester.sh['sid']
            except KeyError:
                _sid = rndstr(24)
                tester.sh['sid'] = _sid
                self.session_conf[_sid] = sh

            resp = tester.run(path, sid=_sid, **self.kwargs)
            if isinstance(resp, requests.Response):
                loc = resp.headers['location']
                #tester.conv.events.store('Cookie', resp.headers['set-cookie'])
                if loc.startswith(tester.base_url):
                    path = loc[len(tester.base_url):]
                else:
                    return resp
            elif resp is True or resp is False or resp is None:
                return tester.display_test_list()
            else:
                return resp(environ, start_response)
        elif path == 'display':
            return inut.flow_list()
        elif path == "opresult":
            resp = SeeOther("/display#{}".format(
                self.pick_grp(sh['conv'].test_id)))
            return resp(environ, start_response)
        elif path.startswith("test_info"):
            p = path.split("/")
            try:
                return inut.test_info(p[1])
            except KeyError:
                return inut.not_found()
        elif path == 'all':
            for test_id in sh['flow_names']:
                resp = tester.run(test_id, **self.kwargs)
                if resp is True or resp is False:
                    continue
                elif resp:
                    return resp(environ, start_response)
                else:
                    resp = ServiceError('Unkown service error')
                    return resp(environ, start_response)
            return tester.display_test_list()

        # Whatever gets here should be of the form <session_id>/<path>
        try:
            sid, _path = path.split('/', 1)
        except ValueError:
            pass
        else:
            if _path.startswith("static/"):
                return static_mime(_path, environ, start_response)

            try:
                _sh = self.session_conf[sid]
            except KeyError:
                resp = ServiceError("Unknown session")
                return resp(environ, start_response)

            tester.sh = _sh
            if 'HTTP_AUTHORIZATION' in environ:
                _sh['conv'].events.store('HTTP_AUTHORIZATION',
                                         environ['HTTP_AUTHORIZATION'])
            _p = _path.split('?')
            if _p[0] in _sh['conv'].entity.endpoints():
                resp = self.handle(environ, tester, sid, *_p)
                self.session_conf[sid] = tester.sh
                return resp(environ, start_response)

            for endpoint, service in self.endpoints.items():
                if _path == endpoint:
                    logger.info("service: {}".format(service))
                    try:
                        resp = self.handle(environ, tester, sid, service)
                        return resp(environ, start_response)
                    except Exception as err:
                        print("%s" % err)
                        message = traceback.format_exception(*sys.exc_info())
                        print(message)
                        logger.exception("%s" % err)
                        resp = ServiceError("%s" % err)
                        return resp(environ)

        logger.debug("unknown side: %s" % path)
        resp = NotFound("Couldn't find the side you asked for!")
        return resp(environ, start_response)
Пример #6
0
class Application(object):
    def __init__(self, base_url, **kwargs):
        self.base_url = base_url
        self.kwargs = kwargs
        self.events = Events()
        self.endpoints = {}
        self.session_conf = {}
        self.internal = kwargs['internal']

    def store_response(self, response):
        self.events.store(EV_RESPONSE, response.info())

    def wsgi_wrapper(self, environ, func, **kwargs):
        kwargs = extract_from_request(environ, kwargs)
        self.events.store(EV_REQUEST, kwargs)
        args = func(**kwargs)

        try:
            resp, state = args
            self.store_response(resp)
            return resp
        except TypeError:
            resp = args
            self.store_response(resp)
            return resp
        except Exception as err:
            logger.error("%s" % err)
            raise

    def handle(self, environ, tester, sid, path, qs=''):
        _sh = tester.sh
        if qs:
            msg = qs
        else:
            try:
                msg = get_or_post(environ)
            except AttributeError:
                msg = {}

        filename = self.kwargs['profile_handler'](_sh).log_path(
            sid=sid, test_id=_sh['conv'].test_id)

        _sh['conv'].entity_id = sid
        return tester.do_next(msg,
                              filename,
                              profile_handler=self.kwargs['profile_handler'],
                              path=path)

    @staticmethod
    def pick_grp(name):
        return name.split('-')[1]

    @staticmethod
    def see_other_to_get(resp, sh):
        loc = resp.message
        res = sh['conv'].entity.server.http_request(loc, 'GET')
        return res

    def store_session_handler(self, sh):
        sid = rndstr(24)
        while sid in self.session_conf:
            sid = rndstr(24)
        sh['sid'] = sid
        self.session_conf[sid] = sh
        return sid

    def init_session(self, tester, sh, test_id=''):
        sid = self.store_session_handler(sh)
        # session['session_info'] = sh
        try:
            del self.session_conf[sid]['flow']
        except KeyError:
            pass

        try:
            args = sh['test_conf']
        except:
            args = {}

        args['test_id'] = test_id
        return tester.do_config(sid, **args)

    def run_test(self, tester, _path, _sid, environ, start_response):
        _op = '{} {}'.format(environ['REQUEST_METHOD'], _path)
        resp = tester.run(_path, sid=_sid, op=_op, **self.kwargs)
        if resp:
            logger.info('Response class: {}'.format(resp.__class__.__name__))

        if isinstance(resp, requests.Response):
            try:
                loc = resp.headers['location']
            except KeyError:
                logger.info('Response type: {}, missing location'.format(
                    type(resp)))
                resp = ServiceError('Wrong response: {}:{}'.format(
                    resp.status_code, resp.text))
                return resp(environ, start_response), 0
            else:
                try:
                    tester.conv.events.store('Cookie',
                                             resp.headers['set-cookie'])
                except KeyError:
                    pass
                # For me !
                if loc.startswith(tester.base_url):
                    _path = loc[len(tester.base_url):]
                    if _path[0] == '/':
                        _path = _path[1:]
                    return 0, _path
                else:
                    if self.internal:
                        _url = absolute_url(
                            loc, tester.sh['test_conf']['start_page'])
                        logging.info('Redirect not to me => {}'.format(_url))
                        res = tester.conv.entity.server.http_request(_url)
                        logging.info('{} response'.format(res.status_code))
                        logging.debug('txt: {}'.format(res.text))
                        res = tester.display_test_list()
                        return res, 0
                    else:
                        res = SeeOther(loc)
                        return res(environ, start_response), 0
        elif resp is True or resp is False or resp is None:
            return tester.display_test_list(), 0
        else:
            return resp(environ, start_response), 0

    # publishes the OP endpoints
    def application(self, environ, start_response):
        session = environ['beaker.session']

        jlog = JLog(logger, session.id)
        path = environ.get('PATH_INFO', '').lstrip('/')
        jlog.info({"remote_addr": environ["REMOTE_ADDR"], "path": path})

        # self.events.store(EV_REQUEST, path)

        try:
            sh = session['session_info']
        except KeyError:
            sh = SessionHandler(**self.kwargs)
            #sh.session_init()
            session['session_info'] = sh

        info = WebIh(session=sh, **self.kwargs)
        info.environ = environ
        info.start_response = start_response

        tester = WebTester(info, sh, **self.kwargs)

        if 'path' in self.kwargs and path.startswith(self.kwargs['path']):
            _path = path[len(kwargs['path']) + 1:]
        else:
            _path = path

        if _path == "robots.txt":
            return static_mime("static/robots.txt", environ, start_response)
        elif _path.startswith("static/"):
            return static_mime(_path, environ, start_response)

        if _path == "list":
            try:
                qs = parse_qs(get_or_post(environ))
            except Exception as err:
                jlog.error({'message': err})
                qs = {}
            else:
                if qs:
                    sh['test_conf'] = dict([(k, v[0]) for k, v in qs.items()])
                    # self.session_conf[sh['sid']] = sh
                else:
                    return self.init_session(tester, sh)

                logger.info('test_conf: {}'.format(sh['test_conf']))

                if 'start_page' not in sh['test_conf']:
                    resp = BadRequest('You MUST provide a start_page')
                    return resp(environ, start_response)

            info.profile = tester.sh.profile = qs['response_type'][0]
            sh.session_init()

            if 'test_id' in qs:
                (res, _path) = self.run_test(tester, qs['test_id'][0],
                                             sh['sid'], environ,
                                             start_response)
                if res:
                    return res
            else:
                res = tester.display_test_list()
                return res
        elif _path == '' or _path == 'config':
            return self.init_session(tester, sh)
        elif _path in self.kwargs['flows'].keys():  # Run flow
            # Will use the same test configuration
            try:
                _ = tester.sh['test_conf']
            except KeyError:
                return self.init_session(tester, sh)

            try:
                _sid = tester.sh['sid']
            except KeyError:
                _sid = self.store_session_handler(sh)

            # First time around this should not be set
            try:
                _ = self.session_conf[_sid]['flow']
            except KeyError:
                pass
            else:
                return self.init_session(tester, sh, _path)

            (res, _path) = self.run_test(tester, _path, _sid, environ,
                                         start_response)
            if res:
                return res
        elif _path == 'display':
            return info.flow_list()
        elif _path == "opresult":
            try:
                _display_path = '/{}/display'.format(self.kwargs['path'])
            except KeyError:
                _display_path = '/display'
            resp = SeeOther("{}#{}".format(_display_path,
                                           self.pick_grp(sh['conv'].test_id)))
            return resp(environ, start_response)
        elif _path.startswith("test_info"):
            p = _path.split("/")
            try:
                return info.test_info(p[1])
            except KeyError:
                return info.not_found()
        elif _path == 'all':
            for test_id in sh['flow_names']:
                resp = tester.run(test_id, **self.kwargs)
                if resp is True or resp is False:
                    continue
                elif resp:
                    return resp(environ, start_response)
                else:
                    resp = ServiceError('Unkown service error')
                    return resp(environ, start_response)
            return tester.display_test_list()

        # Whatever gets here should be of the form <session_id>/<path>
        try:
            sid, _path = _path.split('/', 1)
        except ValueError:
            pass
        else:
            if _path.startswith("static/"):
                return static_mime(_path, environ, start_response)

            try:
                _sh = self.session_conf[sid]
            except KeyError:
                resp = ServiceError("Unknown session")
                return resp(environ, start_response)

            tester.sh = _sh
            if 'HTTP_AUTHORIZATION' in environ:
                _sh['conv'].events.store('HTTP_AUTHORIZATION',
                                         environ['HTTP_AUTHORIZATION'])
            _p = _path.split('?')
            _sh['conv'].events.store(
                'http request', '{} /{}'.format(environ['REQUEST_METHOD'],
                                                _path))
            if _p[0] in _sh['conv'].entity.endpoints():
                resp = self.handle(environ, tester, sid, *_p)
                self.session_conf[sid] = tester.sh
                # The only redirect should be the one to the redirect_uri
                if isinstance(resp, SeeOther):
                    if self.internal:
                        # res = self.see_other_to_get(resp, sh)
                        # res is probably a redirect
                        # send the user back to the test list page
                        return info.flow_list()
                    else:
                        return resp(environ, start_response)
                elif isinstance(resp, Response):
                    return resp(environ, start_response)
                else:
                    return resp

            for endpoint, service in self.endpoints.items():
                if _path == endpoint:
                    jlog.info({"service": service})
                    try:
                        resp = self.handle(environ, tester, sid, service)
                        return resp(environ, start_response)
                    except Exception as err:
                        print("%s" % err)
                        message = traceback.format_exception(*sys.exc_info())
                        print(message)
                        jlog.exception(err)
                        resp = ServiceError("%s" % err)
                        return resp(environ)

        jlog.debug({"unknown side": path})
        resp = NotFound("Couldn't find the side you asked for!")
        return resp(environ, start_response)
Пример #7
0
    def application(self, environ, start_response):
        """
        :param environ: The HTTP application environment
        :param start_response: The application to run when the handling of the
            request is done
        :return: The response as a list of lines
        """

        path = environ.get('PATH_INFO', '').lstrip('/')
        response_encoder = ResponseEncoder(environ=environ,
                                           start_response=start_response)
        parameters = parse_qs(environ["QUERY_STRING"])

        session_info = {
            "addr": get_client_address(environ),
            'cookie': environ.get("HTTP_COOKIE", ''),
            'path': path,
            'parameters': parameters
        }

        jlog = JLog(LOGGER, session_info['addr'])
        jlog.info(session_info)

        if path == "robots.txt":
            return static(environ, start_response, "static/robots.txt")

        if path.startswith("static/"):
            return static(environ, start_response, path)
        elif path.startswith("tar/"):
            return static(environ, start_response, path)
        elif path.startswith("log"):
            return display_log(path, environ, start_response, lookup=LOOKUP)
        elif path.startswith('clear/'):
            return clear_log(path, environ, start_response, lookup=LOOKUP)
        elif path.startswith('mktar/'):
            return make_tar(path, environ, start_response, lookup=LOOKUP)
        elif path.startswith("_static/"):
            return static(environ, start_response, path)
        elif path.startswith("jwks.json"):
            try:
                mode, endpoint = extract_mode(self.op_args["baseurl"])
                events = Events()
                events.store('Init',
                             '===========================================')
                op, path, jlog.id = self.op_setup(environ, mode, events,
                                                  self.test_conf, endpoint)
                jwks = op.generate_jwks(mode)
                resp = Response(jwks,
                                headers=[('Content-Type', 'application/json')])
                return resp(environ, start_response)
            except KeyError:
                # Try to load from static file
                return static(environ, start_response, "static/jwks.json")

        events = Events()
        events.store('Init', '===========================================')

        if path == "test_list":
            return rp_test_list(environ, start_response)
        elif path == "":
            return registration(environ, start_response)
        elif path == "generate_client_credentials":
            client_id, client_secret = generate_static_client_credentials(
                parameters)
            return response_encoder.return_json(
                json.dumps({"client_id": client_id,
                            "client_secret": client_secret}))
        elif path == "3rd_party_init_login":
            return rp_support_3rd_party_init_login(environ, start_response)

        # path should be <oper_id>/<test_id>/<endpoint>
        try:
            mode = parse_path(path)
        except ValueError:
            resp = BadRequest('Illegal path')
            return resp(environ, start_response)

        try:
            endpoint = mode['endpoint']
        except KeyError:
            _info = {'error': 'No endpoint', 'mode': mode}
            events.store(EV_FAULT, _info)
            jlog.error(_info)
            resp = BadRequest('Illegal path')
            return resp(environ, start_response)

        if endpoint == ".well-known/webfinger":
            session_info['endpoint'] = endpoint
            try:
                _p = urlparse(parameters["resource"][0])
            except KeyError:
                events.store(EV_FAULT,
                             FailedOperation('webfinger',
                                             'No resource defined'))
                jlog.error({'reason': 'No resource defined'})
                resp = ServiceError("No resource defined")
                return resp(environ, start_response)

            if _p.scheme in ["http", "https"]:
                events.store(EV_REQUEST,
                             Operation(name='webfinger', type='url',
                                       path=_p.path))
                mode = parse_path(_p.path)
            elif _p.scheme == "acct":
                _l, _ = _p.path.split('@')

                _a = _l.split('.')
                if len(_a) == 2:
                    _oper_id = _a[0]
                    _test_id = _a[1]
                elif len(_a) > 2:
                    _oper_id = ".".join(_a[:-1])
                    _test_id = _a[-1]
                else:
                    _oper_id = _a[0]
                    _test_id = 'default'

                mode.update({'oper_id': _oper_id, 'test_id': _test_id})
                events.store(EV_REQUEST,
                             Operation(name='webfinger', type='acct',
                                       oper_id=_oper_id, test_id=_test_id))
            else:
                _msg = "Unknown scheme: {}".format(_p.scheme)
                events.events(EV_FAULT, FailedOperation('webfinger', _msg))
                jlog.error({'reason': _msg})
                resp = ServiceError(_msg)
                return resp(environ, start_response)
        elif endpoint == "claim":
            authz = environ["HTTP_AUTHORIZATION"]
            _ev = Operation('claim')
            try:
                assert authz.startswith("Bearer")
            except AssertionError:
                resp = BadRequest()
            else:
                _ev.authz = authz
                events.store(EV_REQUEST, _ev)
                tok = authz[7:]
                # mode, endpoint = extract_mode(self.op_args["baseurl"])
                _op, _, sid = self.op_setup(environ, mode, events,
                                            self.test_conf, endpoint)
                try:
                    _claims = _op.claim_access_token[tok]
                except KeyError:
                    resp = BadRequest()
                else:
                    del _op.claim_access_token[tok]
                    _info = Message(**_claims)
                    jwt_key = _op.keyjar.get_signing_key()
                    resp = Response(_info.to_jwt(key=jwt_key,
                                                 algorithm="RS256"),
                                    content='application/jwt')
            return resp(environ, start_response)

        if mode:
            session_info.update(mode)
            jlog.id = mode['oper_id']

        try:
            _op, path, jlog.id = self.op_setup(environ, mode, events,
                                               self.test_conf,
                                               endpoint)
        except UnknownTestID as err:
            resp = BadRequest('Unknown test ID: {}'.format(err.args[0]))
            return resp(environ, start_response)

        session_info["op"] = _op
        session_info["path"] = path
        session_info['test_conf'] = self.test_conf[session_info['test_id']]

        for regex, callback in URLS:
            match = re.search(regex, endpoint)
            if match is not None:
                _op = HTTPRequest(endpoint=endpoint,
                                  method=environ["REQUEST_METHOD"])
                try:
                    _op.authz = environ["HTTP_AUTHORIZATION"]
                except KeyError:
                    pass
                events.store(EV_HTTP_REQUEST, _op)
                try:
                    environ['oic.url_args'] = match.groups()[0]
                except IndexError:
                    environ['oic.url_args'] = endpoint

                jlog.info({'callback': callback.__name__})
                try:
                    return callback(environ, start_response, session_info,
                                    events, op_arg=self.op_args, jlog=jlog)
                except Exception as err:
                    print("%s" % err)
                    message = traceback.format_exception(*sys.exc_info())
                    print(message)
                    events.store(EV_EXCEPTION, err)
                    LOGGER.exception("%s" % err)
                    resp = ServiceError("%s" % err)
                    return resp(environ, start_response)

        LOGGER.debug("unknown page: '{}'".format(endpoint))
        events.store(EV_FAULT, 'No such page: {}'.format(endpoint))
        resp = NotFound("Couldn't find the side you asked for!")
        return resp(environ, start_response)