Ejemplo n.º 1
0
    def urlhandler_acs_post(self, sh, environ, local_webenv, path, start_response, tester, webio):
        formdata = get_post(environ).decode('utf8')
        resp = dict([(k, v[0]) for k, v in parse_qs(formdata).items()])

        try:
            test_id = sh['conv'].test_id
        except KeyError as err:
            test_id = None

        if not test_id:
            """
                Do we have been initialized already, or is the user just on the wrong page ?
            """
            if not resp:
                return tester.display_test_list()
            """
            In other words: we've been contacted by robobrowser and are in a different environment now, than the
            code expects us to be. .... Hopefully, trickery and recreating of the environment will lead mostly
            to more intended effects than unintended ones.

            This is unfinished business: You can add other bindings here, to expand what RB can be used to test.
            """
            try:
                txt = resp['SAMLResponse']
                xmlstr = Entity.unravel(txt, BINDING_HTTP_POST)
            except Exception as e:
                msg = 'Decoding not supported in the SP'
                raise Exception(msg)

            rsp = samlp.any_response_from_string(xmlstr)
            original_request_id = rsp.in_response_to
            requester_session = self.session_store.get_session_by_conv_id(original_request_id)

            # recreating the environment. lets hope it is somewhat reentrant resistant
            sh = requester_session
            webio = WebIO(session=sh, **local_webenv)
            webio.environ = environ
            webio.start_response = start_response

            tester = Tester(webio, sh, **local_webenv)

        profile_handler = local_webenv['profile_handler']
        _sh = profile_handler(sh)
        # filename = self.webenv['profile_handler'](sh).log_path(test_id)
        # _sh.session.update({'conv': 'foozbar'})
        logfilename = _sh.log_path(test_id)

        content = do_next(tester, resp, sh, webio, logfilename, path)
        return content
Ejemplo n.º 2
0
    def application(self, environ, start_response):
        path = environ.get('PATH_INFO', '').lstrip('/')
        LOGGER.info("request PATH_INFO: %s, client: %s" % (path, environ["REMOTE_ADDR"]))

        session = environ['beaker.session']
        try:
            sh = session['session_info']
            local_webenv = session['webenv']
        except KeyError:
            sh = SessionHandler(**self.webenv)
            sh.session_init()
            local_webenv = self.webenv
            session['session_info'] = sh
            session['webenv'] = local_webenv
        self.session_store.append(session)

        webio = WebIO(session=sh, **local_webenv)
        webio.environ = environ # WSGI environment
        webio.start_response = start_response
        tester = Tester(webio, sh, **local_webenv)

        _static_path = self.is_static_path(path)
        if _static_path:
            return webio.static(_static_path)

        if path == "" or path == "/":  # list
            return tester.display_test_list()
        elif "flow_names" not in sh:
            sh.session_init()

        if path == "acs/artifact":
            pass
        elif path == "acs/post":
            return self.urlhandler_acs_post(sh, environ, local_webenv, path,
                                            start_response, tester, webio)
        elif path == "acs/redirect":
            formdata = environ['QUERY_STRING']
            resp = dict([(k, v[0]) for k, v in parse_qs(formdata).items()])
            logfilename = local_webenv['profile_handler'](sh).log_path(sh['conv'].test_id)
            return do_next(tester, resp, sh, webio, logfilename, path)
        elif path == 'all':
            return self.urlhandler_all(sh, environ, local_webenv, start_response, tester, webio)
        elif path == "continue":
            return tester.cont(environ, local_webenv)
        elif path == "disco":
            formdata = parse_qs(environ['QUERY_STRING'])
            resp = dict([(k, v[0]) for k, v in formdata.items()])
            logfilename = local_webenv['profile_handler'](sh).log_path(sh['conv'].test_id)
            return do_next(tester, resp, sh, webio, logfilename, path=path)
        # expected path format: /<testid>[/<endpoint>]
        elif path in sh["flow_names"]:
            return self.urlhandler_flownames(sh, environ, local_webenv, path, tester, webio)
        elif path.startswith("log"):
            return self.urlhandler_log(webio)
        elif path == "logs":
            return webio.display_log("log", issuer="", profile="", testid="")
        elif path == "opresult":
            if tester.conv is None:
                return webio.sorry_response(local_webenv['base_url'],
                                            "No result to report (no conv log)")
            return webio.opresult(tester.conv, sh)
        elif path == 'reset':
            return self.urlhandler_reset(sh, tester)
        elif path == "slo":
            pass
        elif path == 'swconf':
            return self.urlhandler_swconf(environ, local_webenv, session, start_response, webio)
        elif path.startswith("tar"):
            path = path.replace(":", "%3A")
            return webio.static(path)
        elif path.startswith("test_info"):
            p = path.split("/")
            try:
                return webio.test_info(p[1])
            except KeyError:
                return webio.not_found()
        else:
            resp = BadRequest()
            return resp(environ, start_response)
Ejemplo n.º 3
0
    def urlhandler_swconf(self, environ, local_webenv, session, start_response, webio):
        """
            switch config by user request
            url param: ?github=<name of the github repo>&email=<user email>&branch=<repobranch>
        """
        formdata = parse_qs(environ['QUERY_STRING'])
        resp = dict([(k, v[0]) for k, v in formdata.items()])

        try:
            ac_file_name = local_webenv['conf'].ACCESS_CONTROL_FILE
        except Exception as e:
            ac_file_name = None

        if ac_file_name:
            try:
                ac_file = WebUserAccessControlFile(local_webenv['conf'].ACCESS_CONTROL_FILE)
            except Exception as e:
                return webio.sorry_response(local_webenv['base_url'], e,
                    context='reading ' + local_webenv['conf'].ACCESS_CONTROL_FILE)

            has_access = ac_file.test(resp['github'], resp['email'])
            if not has_access:
                return webio.sorry_response(local_webenv['base_url'], 'permission denied',
                    context="access checking: email does not match repo user.")

        # reading from github should set readjson, but to be sure ...
        setup_cargs=type('setupcarg', (object,),
                         {'github': True,
                          'configdir': resp['github'],
                          'readjson': True })()
        if 'branch' in resp:
            setattr(setup_cargs, 'repobranch', resp['branch'])
        else:
            setattr(setup_cargs, 'repobranch', None)

        try:
            user_cargs, user_kwargs, user_CONF = setup('wb', setup_cargs)
        except FileNotFoundError as e:
            return webio.sorry_response(local_webenv['base_url'], e,
                                        context="Configuration Setup via URL parameter - trying to read generated/config.json")
        except ConfigError as e:
            errstr = e.error_details_as_string()
            print('Error: {}'.format(errstr))
            return webio.sorry_response(local_webenv['base_url'], errstr,
                                        context="configuration setup",
                                        exception=traceback.format_exc())
        except Exception as e:
            return webio.sorry_response(local_webenv['base_url'], e,
                                        context="Configuration Setup",
                                        exception=traceback.format_exc())

        """
            picking the config stuff that the user is allowed to override
        """
        local_webenv['conf'] = user_CONF
        local_webenv['flows'] = user_kwargs['flows']

        """
            Todo: having this not cluttered would be nicer
            In other words: refactoring of setup.py
        """
        local_webenv['entity_id'] = local_webenv['conf'].ENTITY_ID
        local_webenv["insecure"] = local_webenv['conf'].DO_NOT_VALIDATE_TLS
        local_webenv["profile"] = local_webenv['conf'].FLOWS_PROFILES

        import copy
        from saml2test import metadata
        spconf = copy.deepcopy(user_CONF.CONFIG)
        acnf = list(spconf.values())[0]
        mds = metadata.load(True, acnf, user_CONF.METADATA, 'sp')
        local_webenv["metadata"] = mds


        # new webenv into session
        session['webenv'] = local_webenv

        sh = SessionHandler(**local_webenv)
        sh.session_init()
        session['session_info'] = sh

        webio = WebIO(session=sh, **local_webenv)
        webio.environ = environ
        webio.start_response = start_response

        tester = Tester(webio, sh, **local_webenv)
        return tester.display_test_list()
Ejemplo n.º 4
0
    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)

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

        webio = WebIO(session=sh, **self.webenv)
        webio.environ = environ
        webio.start_response = start_response

        tester = Tester(webio, sh, **self.webenv)

        if path == "robots.txt":
            return webio.static("static/robots.txt")
        elif path == "favicon.ico":
            return webio.static("static/favicon.ico")
        elif path.startswith('acs/site/static'):
            path = path[4:]
            return webio.static(path)
        elif path.startswith("site/static/") or path.startswith('static/'):
            return webio.static(path)
        elif path.startswith("export/"):
            return webio.static(path)

        if path == "" or path == "/":  # list
            return tester.display_test_list()
        elif "flow_names" not in sh:
            sh.session_init()

        if path == "logs":
            return webio.display_log("log", issuer="", profile="", testid="")
        elif path.startswith("log"):
            if path == "log" or path == "log/":
                _cc = webio.conf.CLIENT
                try:
                    _iss = _cc["srv_discovery_url"]
                except KeyError:
                    _iss = _cc["provider_info"]["issuer"]
                parts = [quote_plus(_iss)]
            else:
                parts = []
                while path != "log":
                    head, tail = os.path.split(path)
                    # tail = tail.replace(":", "%3A")
                    # if tail.endswith("%2F"):
                    #     tail = tail[:-3]
                    parts.insert(0, tail)
                    path = head

            return webio.display_log("log", *parts)
        elif path.startswith("tar"):
            path = path.replace(":", "%3A")
            return webio.static(path)

        elif path.startswith("test_info"):
            p = path.split("/")
            try:
                return webio.test_info(p[1])
            except KeyError:
                return webio.not_found()
        elif path == "continue":
            return tester.cont(environ, self.webenv)
        elif path == 'reset':
            for param in ['flow', 'flow_names', 'index', 'node', 'profile',
                          'sequence', 'test_info', 'test_id', 'tests']:
                del sh[param]
            return tester.display_test_list()
        elif path == "opresult":
            if tester.conv is None:
                return webio.sorry_response("", "No result to report")

            return webio.opresult(tester.conv, sh)
        # expected path format: /<testid>[/<endpoint>]
        elif path in sh["flow_names"]:
            resp = tester.run(path, **self.webenv)
            store_test_state(sh, sh['conv'].events)
            filename = self.webenv['profile_handler'](sh).log_path(path)
            if isinstance(resp, Response):
                res = Result(sh, self.webenv['profile_handler'])
                res.store_test_info()
                res.print_info(path, tester.fname(path))
                return webio.respond(resp)
            else:
                return webio.flow_list(filename)
        elif path == "acs/post":
            qs = get_post(environ).decode('utf8')
            resp = dict([(k, v[0]) for k, v in parse_qs(qs).items()])
            filename = self.webenv['profile_handler'](sh).log_path(tester.conv.test_id)

            return do_next(tester, resp, sh, webio, filename, path)
        elif path == "acs/redirect":
            qs = environ['QUERY_STRING']
            resp = dict([(k, v[0]) for k, v in parse_qs(qs).items()])
            filename = self.webenv['profile_handler'](sh).log_path(tester.conv.test_id)

            return do_next(tester, resp, sh, webio, filename, path)
        elif path == "acs/artifact":
            pass
        elif path == "ecp":
            pass
        elif path == "disco":
            pass
        elif path == "slo":
            pass
        else:
            resp = BadRequest()
            return resp(environ, start_response)