コード例 #1
0
    def parse_request(self, environ):
        def rebuild_header_name(environ_key):
            """Construct the HTTP header name from a WSGI environ variable.
            """
            header_name = environ_key[5:]  # strip 'HTTP_'
            name_parts = header_name.split("_")
            header_name = "-".join(part.capitalize() for part in name_parts)
            return header_name

        request = {}
        request["host"] = environ.get("HTTP_HOST", None)
        request["path"] = environ.get("PATH_INFO", None)
        request["query"] = dict(parse_qsl(environ.get("QUERY_STRING", None)))
        request["method"] = environ.get("REQUEST_METHOD", None)

        request["headers"] = {}
        for key in environ:
            if key.startswith("HTTP_"):
                header_name = rebuild_header_name(key)
                request["headers"][header_name] = environ[key]

        if "CONTENT_TYPE" in environ:
            request["headers"]["Content-Type"] = environ["CONTENT_TYPE"]
        if "CONTENT_LENGTH" in environ:
            request["headers"]["Content-Length"] = environ["CONTENT_LENGTH"]

        if environ["CONTENT_LENGTH"]:
            request["body"] = get_post(environ)

        return request
コード例 #2
0
ファイル: proof_of_possesion.py プロジェクト: Omosofe/pyoidc
    def parse_request(self, environ):
        def rebuild_header_name(environ_key):
            """Construct the HTTP header name from a WSGI environ variable.
            """
            header_name = environ_key[5:]  # strip 'HTTP_'
            name_parts = header_name.split("_")
            header_name = "-".join(part.capitalize() for part in name_parts)
            return header_name

        request = {}
        request["host"] = environ.get("HTTP_HOST", None)
        request["path"] = environ.get("PATH_INFO", None)
        request["query"] = dict(parse_qsl(environ.get("QUERY_STRING", None)))
        request["method"] = environ.get("REQUEST_METHOD", None)

        request["headers"] = {}
        for key in environ:
            if key.startswith("HTTP_"):
                header_name = rebuild_header_name(key)
                request["headers"][header_name] = environ[key]

        if "CONTENT_TYPE" in environ:
            request["headers"]["Content-Type"] = environ["CONTENT_TYPE"]
        if "CONTENT_LENGTH" in environ:
            request["headers"]["Content-Length"] = environ["CONTENT_LENGTH"]

        if environ["CONTENT_LENGTH"]:
            request["body"] = get_post(environ)

        return request
コード例 #3
0
ファイル: frontend.py プロジェクト: its-dirg/oidc-fed
    def _register_client(self, context):
        http_authz = context.wsgi_environ.get("HTTP_AUTHORIZATION")
        try:
            post_body = get_post(context.wsgi_environ)
            http_resp = self.OP.register_client(http_authz, post_body)
        except OIDCFederationError as e:
            satosa_logging(LOGGER, logging.ERROR,
                           "OIDCFederation frontend error: {}".format(str(e)), context.state)
            return Response(str(e))

        if not isinstance(http_resp, Created):
            return http_resp

        return self._fixup_registration_response(http_resp)
コード例 #4
0
ファイル: service.py プロジェクト: its-dirg/id_token_verify
def app(environ, start_response):
    if environ['REQUEST_METHOD'] != 'POST':
        start_response('405 Not Allowed', [('Content-Type', 'text/plain')])
        return ['Only POST is supported.'.encode('utf-8')]

    post_data = get_post(environ)
    parsed_data = dict(parse_qsl(post_data))

    start_response('200 OK', [('Content-Type', 'application/json')])
    try:
        verified_token = verify_signed_id_token(**parsed_data)
    except IDTokenVerificationError as e:
        return [json.dumps({"error": str(e)}).encode('utf-8')]

    return [verified_token.encode('utf-8')]
コード例 #5
0
ファイル: server.py プロジェクト: htobenothing/pyoidc
    def wrapper(environ, start_response):
        data = get_post(environ)
        kwargs = dict(urlparse.parse_qsl(data))
        kwargs["state"] = json.loads(urlparse.unquote(kwargs["state"]))
        val, completed = verifier.verify(**kwargs)
        if not completed:
            return val(environ, start_response)
        if val:
            set_cookie, cookie_value = verifier.create_cookie(val, "auth")
            cookie_value += "; path=/"

            url = "{base_url}?{query_string}".format(base_url="/authorization", query_string=kwargs["state"]["query"])
            response = SeeOther(url, headers=[(set_cookie, cookie_value)])
            return response(environ, start_response)
        else:  # Unsuccessful authentication
            url = "{base_url}?{query_string}".format(base_url="/authorization", query_string=kwargs["state"]["query"])
            response = SeeOther(url)
            return response(environ, start_response)
コード例 #6
0
ファイル: tool.py プロジェクト: simudream/oauth2test
    def set_profile(self, environ):
        info = parse_qs(get_post(environ))
        try:
            cp = self.sh.session["profile"].split(".")
            cp[0] = info["rtype"][0]

            crsu = []
            for name, cs in list(CRYPTSUPPORT.items()):
                try:
                    if info[name] == ["on"]:
                        crsu.append(cs)
                except KeyError:
                    pass

            if len(cp) == 3:
                if len(crsu) == 3:
                    pass
                else:
                    cp.append("".join(crsu))
            else:  # len >= 4
                cp[3] = "".join(crsu)

            try:
                if info["extra"] == ['on']:
                    if len(cp) == 3:
                        cp.extend(["", "+"])
                    elif len(cp) == 4:
                        cp.append("+")
                    elif len(cp) == 5:
                        cp[4] = "+"
                else:
                    if len(cp) == 5:
                        cp = cp[:-1]
            except KeyError:
                if len(cp) == 5:
                    cp = cp[:-1]

            # reset all test flows
            self.sh.reset_session(profile=".".join(cp))
            return self.io.flow_list(self.sh.session)
        except Exception as err:
            return self.io.err_response(self.sh.session, "profile", err)
コード例 #7
0
    def set_profile(self, environ):
        info = parse_qs(get_post(environ))
        try:
            cp = self.sh.session["profile"].split(".")
            cp[0] = info["rtype"][0]

            crsu = []
            for name, cs in list(CRYPTSUPPORT.items()):
                try:
                    if info[name] == ["on"]:
                        crsu.append(cs)
                except KeyError:
                    pass

            if len(cp) == 3:
                if len(crsu) == 3:
                    pass
                else:
                    cp.append("".join(crsu))
            else:  # len >= 4
                cp[3] = "".join(crsu)

            try:
                if info["extra"] == ['on']:
                    if len(cp) == 3:
                        cp.extend(["", "+"])
                    elif len(cp) == 4:
                        cp.append("+")
                    elif len(cp) == 5:
                        cp[4] = "+"
                else:
                    if len(cp) == 5:
                        cp = cp[:-1]
            except KeyError:
                if len(cp) == 5:
                    cp = cp[:-1]

            # reset all test flows
            self.sh.reset_session(profile=".".join(cp))
            return self.io.flow_list(self.sh.session)
        except Exception as err:
            return self.io.err_response(self.sh.session, "profile", err)
コード例 #8
0
ファイル: json_resource_server.py プロジェクト: dv10den/pyuma
    def do(self, path, environ, permission=None, user=""):
        """

        """
        method = environ["REQUEST_METHOD"]

        if method == "GET":
            if "QUERY_STRING" in environ and environ["QUERY_STRING"]:
                method = "QUERY"

        # Verify that the permission is sufficient
        allowed = False
        if user:
            _pat = "%s%s" % (self.base, user)
            if path.startswith(_pat) or path == _pat:
                allowed = True
        elif permission and self.check_permission(permission, method):
            allowed = True

        if not allowed:
            return ErrorResponse(error="Unauthorized")

        if method in ["PUT", "POST", "PATCH"]:
            info = get_post(environ)
        else:
            info = ""

        if method == "GET":
            return self.do_get(path)
        elif method == "QUERY":
            return self.do_query(path, environ["QUERY_STRING"])
        elif method == "DELETE":
            return self.do_delete(path)
        elif method == "PUT":
            return self.do_put(path, info)
        elif method == "POST":
            return self.do_post(path, info, user)
        elif method == "PATCH":
            return self.do_patch(path, info)
        else:
            return ErrorResponse(error="unsupported_method")
コード例 #9
0
    def do(self, path, environ, permission=None, user=""):
        """

        """
        method = environ["REQUEST_METHOD"]

        if method == "GET":
            if "QUERY_STRING" in environ and environ["QUERY_STRING"]:
                method = "QUERY"

        # Verify that the permission is sufficient
        allowed = False
        if user:
            _pat = "%s%s" % (self.base, user)
            if path.startswith(_pat) or path == _pat:
                allowed = True
        elif permission and self.check_permission(permission, method):
            allowed = True

        if not allowed:
            return ErrorResponse(error="Unauthorized")

        if method in ["PUT", "POST", "PATCH"]:
            info = get_post(environ)
        else:
            info = ""

        if method == "GET":
            return self.do_get(path)
        elif method == "QUERY":
            return self.do_query(path, environ["QUERY_STRING"])
        elif method == "DELETE":
            return self.do_delete(path)
        elif method == "PUT":
            return self.do_put(path, info)
        elif method == "POST":
            return self.do_post(path, info, user)
        elif method == "PATCH":
            return self.do_patch(path, info)
        else:
            return ErrorResponse(error="unsupported_method")
コード例 #10
0
    def wrapper(environ, start_response):
        data = get_post(environ)
        kwargs = dict(urlparse.parse_qsl(data))
        kwargs["state"] = json.loads(urlparse.unquote(kwargs["state"]))
        val, completed = verifier.verify(**kwargs)
        if not completed:
            return val(environ, start_response)
        if val:
            set_cookie, cookie_value = verifier.create_cookie(val, "auth")
            cookie_value += "; path=/"

            url = "{base_url}?{query_string}".format(
                base_url="/authorization",
                query_string=kwargs["state"]["query"])
            response = SeeOther(url, headers=[(set_cookie, cookie_value)])
            return response(environ, start_response)
        else:  # Unsuccessful authentication
            url = "{base_url}?{query_string}".format(
                base_url="/authorization",
                query_string=kwargs["state"]["query"])
            response = SeeOther(url)
            return response(environ, start_response)
コード例 #11
0
def application(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('/')

    if path == "":
        return registration(environ, start_response)
    elif path == "generate_client_credentials":
        post_data = get_post(environ)
        query_params = json.loads(post_data)
        client_id, client_secret = generate_static_client_credentials(
            query_params)
        resp = Response(json.dumps({
            "client_id": client_id,
            "client_secret": client_secret
        }),
                        headers=[('Content-Type', "application/json")])
        return resp(environ, start_response)

    return NotFound("'/" + path + "' not found")(environ, start_response)
コード例 #12
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)
        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)
コード例 #13
0
ファイル: oprp2.py プロジェクト: simudream/oictest
def application(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)

    oprp = OPRP(**RP_ARGS)
    oprp.environ = environ
    oprp.start_response = start_response

    if path == "robots.txt":
        return oprp.static("static/robots.txt")
    elif path == "favicon.ico":
        return oprp.static("static/favicon.ico")
    elif path.startswith("static/"):
        return oprp.static(path)
    elif path.startswith("export/"):
        return oprp.static(path)

    if path == "":  # list
        try:
            if oprp.session_init(session):
                return oprp.flow_list(session)
            else:
                try:
                    resp = Redirect("%sopresult#%s" %
                                    (oprp.conf.BASE, session["testid"][0]))
                except KeyError:
                    return oprp.flow_list(session)
                else:
                    return resp(environ, start_response)
        except Exception as err:
            return oprp.err_response(session, "session_setup", err)
    elif path == "logs":
        return oprp.display_log("log", issuer="", profile="", testid="")
    elif path.startswith("log"):
        if path == "log" or path == "log/":
            _cc = oprp.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 oprp.display_log("log", *parts)
    elif path.startswith("tar"):
        path = path.replace(":", "%3A")
        return oprp.static(path)
    elif "flow_names" not in session:
        oprp.session_init(session)

    if path == "reset":
        oprp.reset_session(session)
        return oprp.flow_list(session)
    elif path == "pedit":
        try:
            return oprp.profile_edit(session)
        except Exception as err:
            return oprp.err_response(session, "pedit", err)
    elif path == "profile":
        info = parse_qs(get_post(environ))
        try:
            cp = session["profile"].split(".")
            cp[0] = info["rtype"][0]

            crsu = []
            for name, cs in list(CRYPTSUPPORT.items()):
                try:
                    if info[name] == ["on"]:
                        crsu.append(cs)
                except KeyError:
                    pass

            if len(cp) == 3:
                if len(crsu) == 3:
                    pass
                else:
                    cp.append("".join(crsu))
            else:  # len >= 4
                cp[3] = "".join(crsu)

            try:
                if info["extra"] == ['on']:
                    if len(cp) == 3:
                        cp.extend(["", "+"])
                    elif len(cp) == 4:
                        cp.append("+")
                    elif len(cp) == 5:
                        cp[4] = "+"
                else:
                    if len(cp) == 5:
                        cp = cp[:-1]
            except KeyError:
                if len(cp) == 5:
                    cp = cp[:-1]

            # reset all test flows
            RP_ARGS["test_profile"] = ".".join(cp)
            oprp.reset_session(session, ".".join(cp))
            return oprp.flow_list(session)
        except Exception as err:
            return oprp.err_response(session, "profile", err)
    elif path.startswith("test_info"):
        p = path.split("/")
        try:
            return oprp.test_info(p[1], session)
        except KeyError:
            return oprp.not_found()
    elif path == "continue":
        try:
            sequence_info = session["seq_info"]
        except KeyError:  # Cookie delete broke session
            query = parse_qs(environ["QUERY_STRING"])
            path = query["path"][0]
            index = int(query["index"][0])
            conv, sequence_info, ots, trace, index = oprp.session_setup(
                session, path, index)

            try:
                conv = RP_ARGS["cache"][query["ckey"][0]]
            except KeyError:
                pass
            else:
                ots.client = conv.client
                session["conv"] = conv
        except Exception as err:
            return oprp.err_response(session, "session_setup", err)
        else:
            index = session["index"]
            ots = session["ots"]
            conv = session["conv"]

        index += 1
        try:
            return oprp.run_sequence(sequence_info, session, conv, ots,
                                     conv.trace, index)
        except Exception as err:
            return oprp.err_response(session, "run_sequence", err)
    elif path == "opresult":

        try:
            conv = session["conv"]
        except KeyError as err:
            homepage = ""
            return oprp.sorry_response(homepage, err)

        return oprp.opresult(conv, session)
    # expected path format: /<testid>[/<endpoint>]
    elif path in session["flow_names"]:
        LOGGER.info("<=<=<=<=< %s >=>=>=>=>" % path)
        conv, sequence_info, ots, trace, index = oprp.session_setup(
            session, path)
        session["node"].complete = False
        try:
            return oprp.run_sequence(sequence_info, session, conv, ots, trace,
                                     index)
        except Exception as err:
            return oprp.err_response(session, "run_sequence", err)
    elif path in ["authz_cb", "authz_post"]:
        try:
            sequence_info = session["seq_info"]
            index = session["index"]
            ots = session["ots"]
            conv = session["conv"]
        except KeyError as err:
            # Todo: find out which port I'm listening on
            return oprp.sorry_response(oprp.conf.BASE, err)
        (req_c, resp_c), _ = sequence_info["sequence"][index]
        try:
            response_mode = conv.AuthorizationRequest["response_mode"]
        except KeyError:
            response_mode = None

        if path == "authz_cb":
            if response_mode == "form_post":
                pass
            elif session["response_type"] and not \
                    session["response_type"] == ["code"]:
                # but what if it's all returned as a query ?
                try:
                    qs = environ["QUERY_STRING"]
                except KeyError:
                    pass
                else:
                    session["conv"].trace.response("QUERY_STRING:%s" % qs)
                    session["conv"].query_component = qs

                return oprp.opresult_fragment()

        if resp_c:  # None in cases where no OIDC response is expected
            _ctype = resp_c.ctype

            # parse the response
            if response_mode == "form_post":
                info = parse_qs(get_post(environ))
                _ctype = "dict"
            elif path == "authz_post":
                query = parse_qs(get_post(environ))
                try:
                    info = query["fragment"][0]
                except KeyError:
                    return oprp.sorry_response(oprp.conf.BASE,
                                               "missing fragment ?!")
                _ctype = "urlencoded"
            elif resp_c.where == "url":
                info = environ["QUERY_STRING"]
                _ctype = "urlencoded"
            else:  # resp_c.where == "body"
                info = get_post(environ)

            LOGGER.info("Response: %s" % info)
            conv.trace.reply(info)
            resp_cls = message_factory(resp_c.response)

            kwargs = {
                "algs": ots.client.sign_enc_algs("id_token"),
                "keyjar": ots.client.keyjar
            }
            if "issuer_mismatch" in ots.client.allow:
                kwargs["sender"] = ots.client.provider_info["issuer"]

            try:
                response = ots.client.parse_response(
                    resp_cls, info, _ctype, conv.AuthorizationRequest["state"],
                    **kwargs)
            except ResponseError as err:
                return oprp.err_response(session, "run_sequence", err)
            except Exception as err:
                return oprp.err_response(session, "run_sequence", err)

            LOGGER.info("Parsed response: %s" % response.to_dict())
            conv.protocol_response.append((response, info))
            conv.trace.response(response)

        try:
            post_tests(conv, req_c, resp_c)
        except Exception as err:
            return oprp.err_response(session, "post_test", err)

        index += 1
        try:
            return oprp.run_sequence(sequence_info, session, conv, ots,
                                     conv.trace, index)
        except Exception as err:
            return oprp.err_response(session, "run_sequence", err)
    else:
        resp = BadRequest()
        return resp(environ, start_response)
コード例 #14
0
    def application(self, environ, start_response):
        logger.info("Connection from: %s" % environ["REMOTE_ADDR"])

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

        _io = IO(rest=self.rest,
                 environ=environ,
                 start_response=start_response,
                 lookup=self.lookup,
                 baseurl=self.baseurl)

        if path == "robots.txt":
            return _io.static("static/robots.txt")
        elif path == "favicon.ico":
            return _io.static("static/favicon.ico")
        elif path.startswith("static/"):
            return _io.static(path)
        elif path.startswith("export/"):
            return _io.static(path)

        if path == '':
            return _io.main()
        if path == 'new':
            return _io.new_iss()
        if path == 'entity':
            return _io.list_iss()
        elif path.startswith('entity/'):
            p = path.split('/')
            while p[-1] == '':
                p = p[:-1]

            if len(p) == 2:
                return _io.list_tag(p[1])
            elif len(p) == 3:
                return _io.show_tag(p)
            elif len(p) == 4:
                _com = p[-1]
                if _com == 'action':
                    _qs = parse_qs(environ.get('QUERY_STRING'))
                    try:
                        _act = _qs['action'][0]
                    except KeyError:
                        resp = BadRequest('missing query parameter')
                        return resp(environ, start_response)

                    if _act == 'delete':
                        return _io.delete_instance(p[1:3],
                                                   pid=self.get_pid(p[1:3]),
                                                   app=self)
                    elif _act == 'restart':
                        return _io.restart_instance(self, p[1:3])
                    elif _act == 'configure':
                        return _io.update_instance(*p[1:3])
                    else:
                        resp = BadRequest('Unknown action')
                        return resp(environ, start_response)

        elif path.startswith('form/'):
            return self.form_handling(path, _io)
        elif path == 'create':
            loc = self.basic_entity_configuration(_io)
            resp = SeeOther(loc)
            return resp(_io.environ, _io.start_response)
        elif path.startswith('run/'):
            _iss, _tag = get_iss_and_tag(path)
            if _iss == '' or _tag == '':
                resp = BadRequest('Path must be of the form /run/<iss>/<tag>')
                return resp(environ, start_response)
            _qiss = quote_plus(_iss)
            _qtag = quote_plus(_tag)
            _info = parse_qs(get_post(environ))
            ent_conf = expand_dict(_info)
            if not verify_config(ent_conf):
                resp = BadRequest('Incorrect configuration')
            else:
                self.rest.write(_qiss, _qtag, ent_conf)
                resp = self.run_test_instance(_qiss, _qtag)
                if not isinstance(resp, Response):
                    resp = SeeOther(resp)
            return resp(_io.environ, _io.start_response)
        elif path.startswith('model/'):
            p = path.split('/')
            prof = p[1]
            if verify_profile(prof):
                info = create_model(prof)
                if info:
                    res = Response(json.dumps(info), content='applicaton/json')
                else:
                    res = ServiceError()
            else:
                res = BadRequest('Syntax error in profile specification')
            return res(environ, start_response)
        elif path.startswith('register/'):
            _iss, _tag = get_iss_and_tag(path)
            _qiss = quote_plus(_iss)
            _qtag = quote_plus(_tag)
            _met = environ.get('REQUEST_METHOD')
            if _met == 'GET':
                return self.assigned_ports.register_port(_qiss, _qtag)
            elif _met == 'DELETE':
                return self.return_port(_qiss, _qtag)
        else:
            # check if this a REST request
            _iss, _tag = get_iss_and_tag(path)
            _qiss = quote_plus(_iss)
            _qtag = quote_plus(_tag)
            _path = '/{}/{}'.format(_qiss, _qtag)
            _met = environ.get('REQUEST_METHOD')
            if _met == 'GET':
                resp = self.rest.read(_qiss, _qtag, _path)
            elif _met == 'POST':
                resp = self.rest.replace(_qiss, _qtag, get_post(environ),
                                         _path)
            elif _met == 'PUT':
                resp = self.rest.store(_qiss, _qtag, get_post(environ))
            elif _met == 'DELETE':
                resp = self.rest.delete(_qiss, _qtag)
            else:
                resp = BadRequest('Unsupported request method')

            return resp(environ, start_response)
コード例 #15
0
    def application(self, environ, start_response):
        b_session = environ['beaker.session']

        jlog = JLog(LOGGER, b_session.id)

        path = environ.get('PATH_INFO', '').lstrip('/')
        try:
            jlog.info({'cookie': environ['HTTP_COOKIE'].split(';'),
                       'path': path})
        except KeyError:
            jlog.info({'path': path})

        if path == "robots.txt":
            return static(environ, start_response, LOGGER, "static/robots.txt")
        elif path.startswith("static/"):
            return static(environ, start_response, LOGGER, path)
        elif '/static/' in path:
            pre, post = path.split('static')
            return static(environ, start_response, LOGGER, 'static' + post)

        query = parse_qs(environ["QUERY_STRING"])

        try:
            session = b_session['session_info']
        except KeyError:
            session = self.find_session(**query)
            if session:
                b_session['session_info'] = session
            else:
                session = {}
                b_session['session_info'] = session
                self.session[b_session.id] = session

        if path == '':
            if 'access_token' not in session:
                return opchoice(environ, start_response, self.clients)
            else:
                client = self.clients[session["op"]]
                # check_session_iframe_url = None
                try:
                    # check_session_iframe_url = client.provider_info[
                    #     "check_session_iframe"]

                    session["session_management"] = {
                        "session_state": query["session_state"][0],
                        "client_id": client.client_id,
                        "issuer": client.provider_info["issuer"]
                    }
                except KeyError:
                    pass

                kwargs = dict(
                    [(p, session[p]) for p in
                     ['id_token', 'userinfo', 'user_id'] if
                     p in session])

                return opresult(environ, start_response, **kwargs)
        elif path == "rp":  # After having chosen which OP to authenticate at
            if "uid" in query:
                try:
                    client = self.clients.dynamic_client(userid=query["uid"][0])
                except (ConnectionError, OIDCError) as err:
                    return operror(environ, start_response, '{}'.format(err))
            elif 'issuer' in query:
                try:
                    client = self.clients[query["issuer"][0]]
                except (ConnectionError, OIDCError) as err:
                    return operror(environ, start_response, '{}'.format(err))
            else:
                client = self.clients[query["op"][0]]

            return self.init_client(client, session, query, environ,
                                    start_response)
        elif path.endswith('authz_post'):
            try:
                _iss = session['op']
            except KeyError:
                jlog.error({'reason': 'No active session',
                            'remote_addr': environ['REMOTE_ADDR']})

                return opchoice(environ, start_response, self.clients)
            else:
                client = self.clients[_iss]

            query = parse_qs(get_post(environ))
            try:
                info = query["fragment"][0]
            except KeyError:
                return sorry_response(environ, start_response, self.base,
                                      "missing fragment ?!")
            if info == ['x']:
                return sorry_response(environ, start_response, self.base,
                                      "Expected fragment didn't get one ?!")

            jlog.info({'fragment': info})

            try:
                result = client.callback(info, session, 'urlencoded')
                if isinstance(result, SeeOther):
                    return result(environ, start_response)
            except OIDCError as err:
                return operror(environ, start_response, "%s" % err)
            except Exception as err:
                raise
            else:
                session.update(result)
                res = SeeOther(self.conf['base_url'])
                return res(environ, start_response)
        elif path in self.clients.return_paths():  # After having
            # authenticated at the OP
            jlog.info({'query': query})

            _client = None
            for cli in self.clients.client.values():
                if query['state'][0] in cli.authz_req:
                    _client = cli
                    break

            if not _client:
                jlog.error({
                    'reason': 'No active session',
                    'remote_addr': environ['REMOTE_ADDR'],
                    'state': query['state'][0]
                })
                return opchoice(environ, start_response, self.clients)

            if 'error' in query:  # something amiss
                if query['error'][0] == 'access_denied':  # Try reregistering
                    _iss = _client.provider_info['issuer']
                    del self.clients[_iss]
                    try:
                        client = self.clients[_iss]
                    except (ConnectionError, OIDCError) as err:
                        return operror(environ, start_response,
                                       '{}'.format(err))
                    return self.init_client(client, session, query, environ,
                                            start_response)

            try:
                _iss = query['iss'][0]
            except KeyError:
                pass
            else:
                if _iss != _client.provider_info['issuer']:
                    jlog.error({'reason': 'Got response from wrong OP'})
                    return opchoice(environ, start_response, self.clients)

            _response_type = _client.behaviour["response_type"]
            try:
                _response_mode = _client.authz_req[session['state']][
                    'response_mode']
            except KeyError:
                _response_mode = ''

            jlog.info({
                "response_type": _response_type,
                "response_mode": _response_mode})

            if _response_type and _response_type != "code":
                # Fall through if it's a query response anyway
                if query:
                    pass
                elif _response_mode:
                    # form_post encoded
                    pass
                else:
                    return opresult_fragment(environ, start_response)

            try:
                result = _client.callback(query, session)
                if isinstance(result, SeeOther):
                    return result(environ, start_response)
            except OIDCError as err:
                return operror(environ, start_response, "%s" % err)
            except Exception:
                raise
            else:
                session.update(result)
                res = SeeOther(self.conf['base_url'])
                return res(environ, start_response)
        elif path == "logout":  # After the user has pressed the logout button
            try:
                _iss = session['op']
            except KeyError:
                jlog.error(
                    {'reason': 'No active session',
                     'remote_addr': environ['REMOTE_ADDR']})
                return opchoice(environ, start_response, self.clients)
            client = self.clients[_iss]
            try:
                del client.authz_req[session['state']]
            except KeyError:
                pass

            logout_url = client.end_session_endpoint
            try:
                # Specify to which URL the OP should return the user after
                # log out. That URL must be registered with the OP at client
                # registration.
                logout_url += "?" + urlencode(
                    {"post_logout_redirect_uri": client.registration_response[
                        "post_logout_redirect_uris"][0]})
            except KeyError:
                pass
            else:
                # If there is an ID token send it along as a id_token_hint
                _idtoken = get_id_token(client, session)
                if _idtoken:
                    logout_url += "&" + urlencode({
                        "id_token_hint": id_token_as_signed_jwt(client,
                                                                _idtoken,
                                                                "HS256")})
                # Also append the ACR values
                logout_url += "&" + urlencode({"acr_values": self.acr_values},
                                              True)

            session.delete()
            resp = SeeOther(str(logout_url))
            return resp(environ, start_response)
        elif path == "logout_success":  # post_logout_redirect_uri
            return Response("Logout successful!")(environ, start_response)
        elif path == "session_iframe":  # session management
            kwargs = session["session_management"]
            resp = Response(mako_template="rp_session_iframe.mako",
                            template_lookup=LOOKUP)
            return resp(environ, start_response,
                        session_change_url="{}session_change".format(
                            self.conf["base_url"]),
                        **kwargs)
        elif path == "session_change":
            try:
                _iss = session['op']
            except KeyError:
                jlog.error({
                    'reason': 'No active session',
                    'remote_addr': environ['REMOTE_ADDR']})
                return opchoice(environ, start_response, self.clients)

            try:
                client = self.clients[_iss]
            except KeyError:
                return Response("No valid session.")(environ, start_response)

            kwargs = {"prompt": "none"}
            # If there is an ID token send it along as a id_token_hint
            idt = get_id_token(client, session)
            if idt:
                kwargs["id_token_hint"] = id_token_as_signed_jwt(client, idt,
                                                                 "HS256")
            resp = client.create_authn_request(session, self.acr_values,
                                               **kwargs)
            return resp(environ, start_response)

        return opchoice(environ, start_response, self.clients)
コード例 #16
0
ファイル: umarp.py プロジェクト: dallerbarn/oictest
def application(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)

    oprp = UMAoprp(**RP_ARGS)

    oprp.environ = environ
    oprp.start_response = start_response

    if path == "robots.txt":
        return oprp.static("static/robots.txt")
    elif path == "favicon.ico":
        return oprp.static("static/favicon.ico")

    if path.startswith("static/"):
        return oprp.static(path)

    if path.startswith("export/"):
        return oprp.static(path)

    if path == "":  # list
        try:
            if oprp.session_init(session):
                return oprp.flow_list(session)
            else:
                try:
                    resp = Redirect("%sopresult#%s" % (
                        oprp.conf.BASE, session["testid"][0]))
                except KeyError:
                    return oprp.flow_list(session)
                else:
                    return resp(environ, start_response)
        except Exception as err:
            return oprp.err_response(session, "session_setup", err)
    elif path == "logs":
        return oprp.display_log("log", "log")
    elif path.startswith("log"):
        if path == "log":
            path = os.path.join(
                path, quote_plus(oprp.conf.CLIENT["srv_discovery_url"]))
            tail = path
        else:
            head, tail = os.path.split(path)
        return oprp.display_log(path, tail)
    elif "flow_names" not in session:
        oprp.session_init(session)

    if path == "reset":
        oprp.reset_session(session)
        return oprp.flow_list(session)
    elif path == "pedit":
        return oprp.profile_edit(session)
    elif path == "profile":
        info = parse_qs(get_post(environ))
        cp = session["profile"].split(".")
        cp[0] = info["rtype"][0]

        crsu = []
        for name, cs in CRYPTSUPPORT.items():
            try:
                if info[name] == ["on"]:
                    crsu.append(cs)
            except KeyError:
                pass

        if len(cp) == 3:
            if len(crsu) == 3:
                pass
            else:
                cp.append("".join(crsu))
        else:  # len >= 4
            cp[3] = "".join(crsu)

        try:
            if info["extra"] == ['on']:
                if len(cp) == 3:
                    cp.extend(["", "+"])
                elif len(cp) == 4:
                    cp.append("+")
                elif len(cp) == 5:
                    cp[4] = "+"
            else:
                if len(cp) == 5:
                    cp = cp[:-1]
        except KeyError:
            if len(cp) == 5:
                cp = cp[:-1]

        # reset all testsflows
        oprp.reset_session(session, ".".join(cp))
        return oprp.flow_list(session)
    elif path.startswith("test_info"):
        p = path.split("/")
        try:
            return oprp.test_info(p[1], session)
        except KeyError:
            return oprp.not_found()
    elif path == "continue":
        try:
            sequence_info = session["seq_info"]
        except KeyError:  # Cookie delete broke session
            query = parse_qs(environ["QUERY_STRING"])
            path = query["path"][0]
            index = int(query["index"][0])
            conv, sequence_info, ots, trace, index = oprp.session_setup(
                session, path, index)
            try:
                conv.cache_key = query["key"][0]
            except KeyError:
                pass
        except Exception as err:
            return oprp.err_response(session, "session_setup", err)
        else:
            index = session["index"]
            ots = session["ots"]
            conv = session["conv"]

        index += 1
        try:
            return oprp.run_sequence(sequence_info, session, conv, ots,
                                     conv.trace, index)
        except Exception, err:
            return oprp.err_response(session, "run_sequence", err)
コード例 #17
0
 def _key_rollover(self):
     # expects a post containing the necessary information
     _jwks = json.loads(get_post(request.environ))
     self.provider.do_key_rollover(_jwks, "key_%d_%%d" % int(time.time()))
     return Response("OK")
コード例 #18
0
            exception_trace("run_sequence", err, trace)
            return test_error(environ, start_response, conv, err)
    else:
        if path != "authz_post":
            if not session["response_type"] == ["code"]:
                return opresult_fragment(environ, start_response, session)
        sequence_info = session["seq_info"]
        index = session["index"]
        ots = session["ots"]
        conv = session["conv"]
        req_c, resp_c = sequence_info["sequence"][index]

        if resp_c:  # None in cases where no OIDC response is expected
            # parse the response
            if path == "authz_post":
                query = parse_qs(get_post(environ))
                info = query["fragment"][0]
            elif resp_c.where == "url":
                info = environ["QUERY_STRING"]
            else:  # resp_c.where == "body"
                info = get_post(environ)

            LOGGER.info("Response: %s" % info)
            resp_cls = factory(resp_c.response)
            response = ots.client.parse_response(resp_cls,
                                                 info,
                                                 resp_c.ctype,
                                                 session["state"],
                                                 keyjar=ots.client.keyjar)

            LOGGER.info("Parsed response: %s" % response.to_dict())
コード例 #19
0
ファイル: rprp.py プロジェクト: dallerbarn/oictest
def application(environ, start_response):
    session = environ['beaker.session']
    path = environ.get('PATH_INFO', '').lstrip('/')

    try:
        _cli = session["client"]
    except KeyError:
        _cli = session["client"] = Client(
            client_authn_method=CLIENT_AUTHN_METHOD, keyjar=KEYJAR)
        _cli.kid = KIDD
        #_cli.allow["issuer_mismatch"] = True
        _cli.jwks_uri = JWKS_URI
        for arg, val in CONF.CLIENT_INFO.items():
            setattr(_cli, arg, val)
        session["done"] = []


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

    if path == "":  # list
        return flow_list(environ, start_response, FLOWS.FLOWS, session["done"])
    elif path in FLOWS.FLOWS.keys():
        session["flow"] = FLOWS.FLOWS[path]
        session["index"] = 0
        session["item"] = path
        session["test_id"] = path

        try:
            resp = run_flow(_cli, session["index"], session, path)
        except Exception as err:
            resp = ServiceError("%s" % err)
            return resp(environ, start_response)
        else:
            if resp:
                return resp(environ, start_response)
            else:
                return flow_list(environ, start_response, FLOWS.FLOWS,
                                 session["done"])
    elif path in ["authz_cb", "authz_post"]:
        if path != "authz_post":
            args = session["flow"]["flow"][session["index"]-1]["args"]
            if args["response_type"] != ["code"]:
                return opresult_fragment(environ, start_response)

        # Got a real Authn response
        ctype = "urlencoded"
        if path == "authz_post":
            query = parse_qs(get_post(environ))
            info = query["fragment"][0]
        else:
            info = environ["QUERY_STRING"]

        LOGGER.info("Response: %s" % info)
        try:
            _cli = session["client"]
            response = _cli.parse_response(AuthorizationResponse, info, ctype,
                                           session["state"], keyjar=_cli.keyjar)
        except ResponseError as err:
            LOGGER.error("%s" % err)
            resp = ServiceError("%s" % err)
            return resp(environ, start_response)
        except Exception as err:
            _spec = session["flow"]["flow"][session["index"]-1]
            try:
                assert isinstance(err, _spec["error"])
            except KeyError:
                raise
        else:
            pass

        try:
            resp = run_flow(_cli, session["index"], session, session["test_id"])
        except Exception as err:
            LOGGER.error("%s" % err)
            resp = ServiceError("%s" % err)
            return resp(environ, start_response)
        else:
            if resp:
                return resp(environ, start_response)
            else:
                return flow_list(environ, start_response, FLOWS.FLOWS,
                                 session["done"])
    else:
        LOGGER.debug("unknown side: %s" % path)
        resp = NotFound("Couldn't find the side you asked for!")
        return resp(environ, start_response)
コード例 #20
0
ファイル: request.py プロジェクト: simudream/oauth2test
    def parse_response(self, path, io, message_factory):
        _ctype = self.response_type
        _conv = self.conv

        if self.csi is None:
            url, body, ht_args, csi = _conv.entity.request_info(
                self.request, method=self.method, request_args=self.req_args,
                **self.op_args)

            self.csi = csi

        try:
            response_mode = self.csi["response_mode"]
        except KeyError:
            response_mode = None

        if self.request_cls == "AuthorizationRequest":
            try:
                _rt = self.csi["response_type"]
            except KeyError:
                response_where = ""
            else:
                if _rt == ["code"]:
                    response_where = "url"
                elif _rt == [""]:
                    response_where = ""
                else:
                    response_where = "fragment"
        else:
            response_where = self.response_where

        # parse the response
        if response_mode == "form_post":
            info = parse_qs(get_post(io.environ))
            _ctype = "dict"
        elif response_where == "url":
            info = io.environ["QUERY_STRING"]
            _ctype = "urlencoded"
        elif response_where == "fragment":
            query = parse_qs(get_post(io.environ))
            try:
                info = query["fragment"][0]
            except KeyError:
                return io.sorry_response(io.conf.BASE, "missing fragment ?!")
        elif response_where == "":
            info = io.environ["QUERY_STRING"]
            _ctype = "urlencoded"
        else:  # resp_c.where == "body"
            info = get_post(io.environ)

        logger.info("Response: %s" % info)

        _conv.trace.reply(info)
        ev_index = _conv.events.store('reply', info)

        resp_cls = message_factory(self.response_cls)
        algs = _conv.entity.sign_enc_algs("id_token")
        try:
            response = _conv.entity.parse_response(
                resp_cls, info, _ctype,
                self.csi["state"],
                keyjar=_conv.entity.keyjar, algs=algs)
        except ResponseError as err:
            return io.err_response(self.sh.session, "run_sequence", err)
        except Exception as err:
            return io.err_response(self.sh.session, "run_sequence", err)

        logger.info("Parsed response: %s" % response.to_dict())

        _conv.trace.response(response)
        _conv.events.store('response', response, ref=ev_index)

        if self.expect_error:
            self.expected_error_response(response)
        else:
            if isinstance(response, ErrorResponse):
                raise Break("Unexpected error response")
コード例 #21
0
ファイル: server.py プロジェクト: its-dirg/software-statement
def key_rollover(environ, start_response, _):
    # expects a post containing the necessary information
    _jwks = json.loads(get_post(environ))
    OAS.do_key_rollover(_jwks, "key_%d_%%d" % int(time.time()))
    resp = Response("OK")
    return resp(environ, start_response)
コード例 #22
0
def application(environ, start_response):
    session = environ['beaker.session']
    path = environ.get('PATH_INFO', '').lstrip('/')

    try:
        _cli = session["client"]
    except KeyError:
        _cli = session["client"] = Client(
            client_authn_method=CLIENT_AUTHN_METHOD, keyjar=KEYJAR)
        _cli.kid = KIDD
        #_cli.allow["issuer_mismatch"] = True
        _cli.jwks_uri = JWKS_URI
        for arg, val in CONF.CLIENT_INFO.items():
            setattr(_cli, arg, val)
        session["done"] = []

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

    if path == "":  # list
        return flow_list(environ, start_response, FLOWS.FLOWS, session["done"])
    elif path in FLOWS.FLOWS.keys():
        session["flow"] = FLOWS.FLOWS[path]
        session["index"] = 0
        session["item"] = path
        session["test_id"] = path

        try:
            resp = run_flow(_cli, session["index"], session, path)
        except Exception as err:
            resp = ServiceError("%s" % err)
            return resp(environ, start_response)
        else:
            if resp:
                return resp(environ, start_response)
            else:
                return flow_list(environ, start_response, FLOWS.FLOWS,
                                 session["done"])
    elif path in ["authz_cb", "authz_post"]:
        if path != "authz_post":
            args = session["flow"]["flow"][session["index"] - 1]["args"]
            if args["response_type"] != ["code"]:
                return opresult_fragment(environ, start_response)

        # Got a real Authn response
        ctype = "urlencoded"
        if path == "authz_post":
            query = parse_qs(get_post(environ))
            info = query["fragment"][0]
        else:
            info = environ["QUERY_STRING"]

        LOGGER.info("Response: %s" % info)
        try:
            _cli = session["client"]
            response = _cli.parse_response(AuthorizationResponse,
                                           info,
                                           ctype,
                                           session["state"],
                                           keyjar=_cli.keyjar)
        except ResponseError as err:
            LOGGER.error("%s" % err)
            resp = ServiceError("%s" % err)
            return resp(environ, start_response)
        except Exception as err:
            _spec = session["flow"]["flow"][session["index"] - 1]
            try:
                assert isinstance(err, _spec["error"])
            except KeyError:
                raise
        else:
            pass

        try:
            resp = run_flow(_cli, session["index"], session,
                            session["test_id"])
        except Exception as err:
            LOGGER.error("%s" % err)
            resp = ServiceError("%s" % err)
            return resp(environ, start_response)
        else:
            if resp:
                return resp(environ, start_response)
            else:
                return flow_list(environ, start_response, FLOWS.FLOWS,
                                 session["done"])
    else:
        LOGGER.debug("unknown side: %s" % path)
        resp = NotFound("Couldn't find the side you asked for!")
        return resp(environ, start_response)
コード例 #23
0
ファイル: app_conf.py プロジェクト: rohe/oidctest
    def application(self, environ, start_response):
        logger.info("Connection from: %s" % environ["REMOTE_ADDR"])

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

        _io = IO(rest=self.rest, environ=environ, start_response=start_response,
                 lookup=self.lookup, baseurl=self.baseurl)

        if path == "robots.txt":
            return _io.static("static/robots.txt")
        elif path == "favicon.ico":
            return _io.static("static/favicon.ico")
        elif path.startswith("static/"):
            return _io.static(path)
        elif path.startswith("export/"):
            return _io.static(path)

        if path == '':
            return _io.main()
        if path == 'new':
            return _io.new_iss()
        if path == 'entity':
            return _io.list_iss()
        elif path.startswith('entity/'):
            p = path.split('/')
            while p[-1] == '':
                p = p[:-1]

            if len(p) == 2:
                return _io.list_tag(p[1])
            elif len(p) == 3:
                return _io.show_tag(p)
            elif len(p) == 4:
                _com = p[-1]
                if _com == 'action':
                    _qs = parse_qs(environ.get('QUERY_STRING'))
                    try:
                        _act = _qs['action'][0]
                    except KeyError:
                        resp = BadRequest('missing query parameter')
                        return resp(environ, start_response)

                    if _act == 'delete':
                        return _io.delete_instance(p[1:3],
                                                   pid=self.get_pid(p[1:3]),
                                                   app=self)
                    elif _act == 'restart':
                        return _io.restart_instance(self, p[1:3])
                    elif _act == 'configure':
                        return _io.update_instance(*p[1:3])
                    else:
                        resp = BadRequest('Unknown action')
                        return resp(environ, start_response)

        elif path.startswith('form/'):
            return self.form_handling(path, _io)
        elif path == 'create':
            loc = self.basic_entity_configuration(_io)
            resp = SeeOther(loc)
            return resp(_io.environ, _io.start_response)
        elif path.startswith('run/'):
            _iss, _tag = get_iss_and_tag(path)
            if _iss == '' or _tag == '':
                resp = BadRequest('Path must be of the form /run/<iss>/<tag>')
                return resp(environ, start_response)
            _qiss = quote_plus(_iss)
            _qtag = quote_plus(_tag)
            _info = parse_qs(get_post(environ))
            ent_conf = expand_dict(_info)
            if not verify_config(ent_conf):
                resp = BadRequest('Incorrect configuration')
            else:
                self.rest.write(_qiss, _qtag, ent_conf)
                resp = self.run_test_instance(_qiss, _qtag)
                if not isinstance(resp, Response):
                    resp = SeeOther(resp)
            return resp(_io.environ, _io.start_response)
        elif path.startswith('model/'):
            p = path.split('/')
            prof = p[1]
            if verify_profile(prof):
                info = create_model(prof)
                if info:
                    res = Response(json.dumps(info), content='applicaton/json')
                else:
                    res = ServiceError()
            else:
                res = BadRequest('Syntax error in profile specification')
            return res(environ, start_response)
        elif path.startswith('register/'):
            _iss, _tag = get_iss_and_tag(path)
            _qiss = quote_plus(_iss)
            _qtag = quote_plus(_tag)
            _met = environ.get('REQUEST_METHOD')
            if _met == 'GET':
                return self.assigned_ports.register_port(_qiss, _qtag)
            elif _met == 'DELETE':
                return self.return_port(_qiss, _qtag)
        else:
            # check if this a REST request
            _iss, _tag = get_iss_and_tag(path)
            _qiss = quote_plus(_iss)
            _qtag = quote_plus(_tag)
            _path = '/{}/{}'.format(_qiss, _qtag)
            _met = environ.get('REQUEST_METHOD')
            if _met == 'GET':
                resp = self.rest.read(_qiss, _qtag, _path)
            elif _met == 'POST':
                resp = self.rest.replace(_qiss, _qtag, get_post(environ), _path)
            elif _met == 'PUT':
                resp = self.rest.store(_qiss, _qtag, get_post(environ))
            elif _met == 'DELETE':
                resp = self.rest.delete(_qiss, _qtag)
            else:
                resp = BadRequest('Unsupported request method')

            return resp(environ, start_response)
コード例 #24
0
ファイル: oprp2.py プロジェクト: dallerbarn/oictest
def application(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)

    oprp = OPRP(**RP_ARGS)
    oprp.environ = environ
    oprp.start_response = start_response

    if path == "robots.txt":
        return oprp.static("static/robots.txt")
    elif path == "favicon.ico":
        return oprp.static("static/favicon.ico")
    elif path.startswith("static/"):
        return oprp.static(path)
    elif path.startswith("export/"):
        return oprp.static(path)

    if path == "":  # list
        try:
            if oprp.session_init(session):
                return oprp.flow_list(session)
            else:
                try:
                    resp = Redirect("%sopresult#%s" % (
                        oprp.conf.BASE, session["testid"][0]))
                except KeyError:
                    return oprp.flow_list(session)
                else:
                    return resp(environ, start_response)
        except Exception as err:
            return oprp.err_response(session, "session_setup", err)
    elif path == "logs":
        return oprp.display_log("log", issuer="", profile="", testid="")
    elif path.startswith("log"):
        if path == "log" or path == "log/":
            _cc = oprp.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 oprp.display_log("log", *parts)
    elif path.startswith("tar"):
        path = path.replace(":", "%3A")
        return oprp.static(path)
    elif "flow_names" not in session:
        oprp.session_init(session)

    if path == "reset":
        oprp.reset_session(session)
        return oprp.flow_list(session)
    elif path == "pedit":
        try:
            return oprp.profile_edit(session)
        except Exception as err:
            return oprp.err_response(session, "pedit", err)
    elif path == "profile":
        info = parse_qs(get_post(environ))
        try:
            cp = session["profile"].split(".")
            cp[0] = info["rtype"][0]

            crsu = []
            for name, cs in list(CRYPTSUPPORT.items()):
                try:
                    if info[name] == ["on"]:
                        crsu.append(cs)
                except KeyError:
                    pass

            if len(cp) == 3:
                if len(crsu) == 3:
                    pass
                else:
                    cp.append("".join(crsu))
            else:  # len >= 4
                cp[3] = "".join(crsu)

            try:
                if info["extra"] == ['on']:
                    if len(cp) == 3:
                        cp.extend(["", "+"])
                    elif len(cp) == 4:
                        cp.append("+")
                    elif len(cp) == 5:
                        cp[4] = "+"
                else:
                    if len(cp) == 5:
                        cp = cp[:-1]
            except KeyError:
                if len(cp) == 5:
                    cp = cp[:-1]

            # reset all test flows
            oprp.reset_session(session, ".".join(cp))
            return oprp.flow_list(session)
        except Exception as err:
            return oprp.err_response(session, "profile", err)
    elif path.startswith("test_info"):
        p = path.split("/")
        try:
            return oprp.test_info(p[1], session)
        except KeyError:
            return oprp.not_found()
    elif path == "continue":
        try:
            sequence_info = session["seq_info"]
        except KeyError:  # Cookie delete broke session
            query = parse_qs(environ["QUERY_STRING"])
            path = query["path"][0]
            index = int(query["index"][0])
            conv, sequence_info, ots, trace, index = oprp.session_setup(
                session, path, index)

            try:
                conv = RP_ARGS["cache"][query["ckey"][0]]
            except KeyError:
                pass
            else:
                ots.client = conv.client
                session["conv"] = conv
        except Exception as err:
            return oprp.err_response(session, "session_setup", err)
        else:
            index = session["index"]
            ots = session["ots"]
            conv = session["conv"]

        index += 1
        try:
            return oprp.run_sequence(sequence_info, session, conv, ots,
                                     conv.trace, index)
        except Exception as err:
            return oprp.err_response(session, "run_sequence", err)
    elif path == "opresult":

        try:
            conv = session["conv"]
        except KeyError as err:
            homepage = ""
            return oprp.sorry_response(homepage, err)

        return oprp.opresult(conv, session)
    # expected path format: /<testid>[/<endpoint>]
    elif path in session["flow_names"]:
        LOGGER.info("<=<=<=<=< %s >=>=>=>=>" % path)
        conv, sequence_info, ots, trace, index = oprp.session_setup(session,
                                                                    path)
        session["node"].complete = False
        try:
            return oprp.run_sequence(sequence_info, session, conv, ots,
                                     trace, index)
        except Exception as err:
            return oprp.err_response(session, "run_sequence", err)
    elif path in ["authz_cb", "authz_post"]:
        try:
            sequence_info = session["seq_info"]
            index = session["index"]
            ots = session["ots"]
            conv = session["conv"]
        except KeyError as err:
            # Todo: find out which port I'm listening on
            return oprp.sorry_response(oprp.conf.BASE, err)
        (req_c, resp_c), _ = sequence_info["sequence"][index]
        try:
            response_mode = conv.AuthorizationRequest["response_mode"]
        except KeyError:
            response_mode = None

        if path == "authz_cb":
            if response_mode == "form_post":
                pass
            elif session["response_type"] and not \
                    session["response_type"] == ["code"]:
                # but what if it's all returned as a query ?
                try:
                    qs = environ["QUERY_STRING"]
                except KeyError:
                    pass
                else:
                    session["conv"].trace.response("QUERY_STRING:%s" % qs)
                    session["conv"].query_component = qs

                return oprp.opresult_fragment()

        if resp_c:  # None in cases where no OIDC response is expected
            _ctype = resp_c.ctype

            # parse the response
            if response_mode == "form_post":
                info = parse_qs(get_post(environ))
                _ctype = "dict"
            elif path == "authz_post":
                query = parse_qs(get_post(environ))
                try:
                    info = query["fragment"][0]
                except KeyError:
                    return oprp.sorry_response(oprp.conf.BASE,
                                               "missing fragment ?!")
                _ctype = "urlencoded"
            elif resp_c.where == "url":
                info = environ["QUERY_STRING"]
                _ctype = "urlencoded"
            else:  # resp_c.where == "body"
                info = get_post(environ)

            LOGGER.info("Response: %s" % info)
            conv.trace.reply(info)
            resp_cls = message_factory(resp_c.response)
            algs = ots.client.sign_enc_algs("id_token")
            try:
                response = ots.client.parse_response(
                    resp_cls, info, _ctype,
                    conv.AuthorizationRequest["state"],
                    keyjar=ots.client.keyjar, algs=algs)
            except ResponseError as err:
                return oprp.err_response(session, "run_sequence", err)
            except Exception as err:
                return oprp.err_response(session, "run_sequence", err)

            LOGGER.info("Parsed response: %s" % response.to_dict())
            conv.protocol_response.append((response, info))
            conv.trace.response(response)

        try:
            post_tests(conv, req_c, resp_c)
        except Exception as err:
            return oprp.err_response(session, "post_test", err)

        index += 1
        try:
            return oprp.run_sequence(sequence_info, session, conv, ots,
                                     conv.trace, index)
        except Exception as err:
            return oprp.err_response(session, "run_sequence", err)
    else:
        resp = BadRequest()
        return resp(environ, start_response)
コード例 #25
0
    def application(self, environ, start_response):
        logger.info("Connection from: %s" % environ["REMOTE_ADDR"])

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

        _io = IO(rest=self.rest,
                 environ=environ,
                 start_response=start_response,
                 lookup=self.lookup)

        if path == "robots.txt":
            return _io.static("static/robots.txt")
        elif path == "favicon.ico":
            return _io.static("static/favicon.ico")
        elif path.startswith("static/"):
            return _io.static(path)
        elif path.startswith("export/"):
            return _io.static(path)

        if path == '':
            return _io.get_iss()
        elif path.startswith('form/'):
            return self.form_handling(path, _io)
        elif path == 'create':
            loc = self.basic_entity_configuration(_io)
            resp = SeeOther(loc)
            return resp(_io.environ, _io.start_response)
        elif path.startswith('run/'):
            _iss, _tag = get_iss_and_tag(path)
            if _iss == '' or _tag == '':
                resp = BadRequest('Path must be of the form /run/<iss>/<tag>')
                return resp(environ, start_response)
            _qiss = quote_plus(_iss)
            _qtag = quote_plus(_tag)
            _info = parse_qs(get_post(environ))
            ent_conf = expand_dict(_info)
            self.rest.write(_qiss, _qtag, ent_conf)
            resp = self.run_test_instance(_qiss, _qtag)
            if not isinstance(resp, Response):
                resp = SeeOther(resp)
            return resp(_io.environ, _io.start_response)
        elif path.startswith('model/'):
            p = path.split('/')
            prof = p[1]
            if verify_profile(prof):
                info = create_model(prof)
                if info:
                    res = Response(json.dumps(info), content='applicaton/json')
                else:
                    res = ServiceError()
            else:
                res = BadRequest('Syntax error in profile specification')
            return res(environ, start_response)
        else:
            # check if this a REST request
            _iss, _tag = get_iss_and_tag(path)
            _qiss = quote_plus(_iss)
            _qtag = quote_plus(_tag)
            _path = '/{}/{}'.format(_qiss, _qtag)
            _met = environ.get('REQUEST_METHOD')
            if _met == 'GET':
                resp = self.rest.read(_qiss, _qtag, _path)
            elif _met == 'POST':
                resp = self.rest.replace(_qiss, _qtag, get_post(environ),
                                         _path)
            elif _met == 'PUT':
                resp = self.rest.store(_qiss, _qtag, get_post(environ))
            elif _met == 'DELETE':
                resp = self.rest.delete(_qiss, _qtag)
            else:
                resp = BadRequest('Unsupported request method')

            return resp(environ, start_response)
コード例 #26
0
ファイル: oprp_gsma.py プロジェクト: simudream/oictest
def application(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)

    oprp = GSMAoprp(**RP_ARGS)

    oprp.environ = environ
    oprp.start_response = start_response

    if path == "robots.txt":
        return oprp.static("static/robots.txt")
    elif path == "favicon.ico":
        return oprp.static("static/favicon.ico")

    if path.startswith("static/"):
        return oprp.static(path)

    if path.startswith("export/"):
        return oprp.static(path)

    if path == "":  # list
        try:
            if oprp.session_init(session):
                return oprp.flow_list(session)
            else:
                try:
                    resp = Redirect("%sopresult#%s" % (
                        oprp.conf.BASE, session["testid"][0]))
                except KeyError:
                    return oprp.flow_list(session)
                else:
                    return resp(environ, start_response)
        except Exception as err:
            return oprp.err_response(session, "session_setup", err)
    elif path == "logs":
        return oprp.display_log("log", "log")
    elif path.startswith("log"):
        if path == "log":
            try:
                _id = oprp.conf.CLIENT["srv_discovery_url"]
            except KeyError:
                _id = oprp.conf.CLIENT["service_id"]
            path = os.path.join(path, quote_plus(_id))
            tail = path
        else:
            head, tail = os.path.split(path)
        return oprp.display_log(path, tail)
    elif "flow_names" not in session:
        oprp.session_init(session)

    if path == "reset":
        oprp.reset_session(session)
        return oprp.flow_list(session)
    elif path == "pedit":
        return oprp.profile_edit(session)
    elif path == "profile":
        info = parse_qs(get_post(environ))
        cp = session["profile"].split(".")
        cp[0] = info["rtype"][0]

        crsu = []
        for name, cs in CRYPTSUPPORT.items():
            try:
                if info[name] == ["on"]:
                    crsu.append(cs)
            except KeyError:
                pass

        if len(cp) == 3:
            if len(crsu) == 3:
                pass
            else:
                cp.append("".join(crsu))
        else:  # len >= 4
            cp[3] = "".join(crsu)

        try:
            if info["extra"] == ['on']:
                if len(cp) == 3:
                    cp.extend(["", "+"])
                elif len(cp) == 4:
                    cp.append("+")
                elif len(cp) == 5:
                    cp[4] = "+"
            else:
                if len(cp) == 5:
                    cp = cp[:-1]
        except KeyError:
            if len(cp) == 5:
                cp = cp[:-1]

        # reset all testsflows
        oprp.reset_session(session, ".".join(cp))
        return oprp.flow_list(session)
    elif path.startswith("test_info"):
        p = path.split("/")
        try:
            return oprp.test_info(p[1], session)
        except KeyError:
            return oprp.not_found()
    elif path == "continue":
        try:
            sequence_info = session["seq_info"]
        except KeyError:  # Cookie delete broke session
            query = parse_qs(environ["QUERY_STRING"])
            path = query["path"][0]
            index = int(query["index"][0])
            conv, sequence_info, ots, trace, index = oprp.session_setup(
                session, path, index)
            try:
                conv.cache_key = query["key"][0]
            except KeyError:
                pass
        except Exception as err:
            return oprp.err_response(session, "session_setup", err)
        else:
            index = session["index"]
            ots = session["ots"]
            conv = session["conv"]

        index += 1
        try:
            return oprp.run_sequence(sequence_info, session, conv, ots,
                                     conv.trace, index)
        except Exception, err:
            return oprp.err_response(session, "run_sequence", err)
コード例 #27
0
ファイル: umarp.py プロジェクト: dallerbarn/oictest
                    qs = environ["QUERY_STRING"]
                except KeyError:
                    qs = ""
                if qs:
                    session["conv"].trace.response("QUERY_STRING:%s" % qs)
                    session["conv"].info(
                        "Didn't expect response as query parameters")

                return oprp.opresult_fragment()

        if resp_c:  # None in cases where no OIDC response is expected
            _ctype = resp_c.ctype

            # parse the response
            if response_mode == "form_post":
                info = parse_qs(get_post(environ))
                _ctype = "dict"
            elif path == "authz_post":
                query = parse_qs(get_post(environ))
                try:
                    info = query["fragment"][0]
                except KeyError:
                    return oprp.sorry_response(oprp.conf.BASE,
                                               "missing fragment ?!")
                _ctype = "urlencoded"
            elif resp_c.where == "url":
                info = environ["QUERY_STRING"]
                _ctype = "urlencoded"
            else:  # resp_c.where == "body"
                info = get_post(environ)
コード例 #28
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)
        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)
コード例 #29
0
ファイル: __request.py プロジェクト: selfissued/oidctest
    def parse_response(self, path, inut, message_factory):
        _ctype = self.response_type
        _conv = self.conv

        if self.csi is None:
            url, body, ht_args, csi = _conv.entity.request_info(
                self.request,
                method=self.method,
                request_args=self.req_args,
                **self.op_args)

            self.csi = csi

        try:
            response_mode = self.csi["response_mode"]
        except KeyError:
            response_mode = None

        if self.request_cls == "AuthorizationRequest":
            try:
                _rt = self.csi["response_type"]
            except KeyError:
                response_where = ""
            else:
                if _rt == ["code"]:
                    response_where = "url"
                elif _rt == [""]:
                    response_where = ""
                else:
                    response_where = "fragment"
        else:
            response_where = self.response_where

        # parse the response
        if response_mode == "form_post":
            info = parse_qs(get_post(inut.environ))
            _ctype = "dict"
        elif response_where == "url":
            info = inut.environ["QUERY_STRING"]
            _ctype = "urlencoded"
        elif response_where == "fragment":
            query = parse_qs(get_post(inut.environ))
            try:
                info = query["fragment"][0]
            except KeyError:
                return inut.sorry_response(inut.conf.BASE,
                                           "missing fragment ?!")
        elif response_where == "":
            info = inut.environ["QUERY_STRING"]
            _ctype = "urlencoded"
        else:  # resp_c.where == "body"
            info = get_post(inut.environ)

        logger.info("Response: %s" % info)

        _conv.trace.reply(info)
        ev_index = _conv.events.store(EV_RESPONSE,
                                      info,
                                      sender=self.__class__.__name__)

        resp_cls = message_factory(self.response_cls)
        algs = _conv.entity.sign_enc_algs("id_token")
        try:
            response = _conv.entity.parse_response(resp_cls,
                                                   info,
                                                   _ctype,
                                                   self.csi["state"],
                                                   keyjar=_conv.entity.keyjar,
                                                   algs=algs)
        except ResponseError as err:
            return inut.err_response("run_sequence", err)
        except Exception as err:
            return inut.err_response("run_sequence", err)

        logger.info("Parsed response: %s" % response.to_dict())

        _conv.trace.response(response)
        _conv.events.store(EV_PROTOCOL_RESPONSE,
                           response,
                           ref=ev_index,
                           sender=self.__class__.__name__)

        if self.expect_error:
            self.expected_error_response(response)
        else:
            if isinstance(response, ErrorResponse):
                raise Break("Unexpected error response")
コード例 #30
0
def application(environ, start_response):
    session = environ['beaker.session']
    path = environ.get('PATH_INFO', '').lstrip('/')
    if path == "robots.txt":
        return static(environ, start_response, LOGGER, "static/robots.txt")
    elif path.startswith("static/"):
        return static(environ, start_response, LOGGER, path)
    elif '/static/' in path:
        pre, post = path.split('static')
        return static(environ, start_response, LOGGER, 'static' + post)

    query = parse_qs(environ["QUERY_STRING"])
    acr_values = session._params['acrs']
    clients = session._params['clients']
    server_env = session._params['server_env']

    LOGGER.info(50 * "=")
    LOGGER.info("[{}] path: {}".format(session.id, path))
    LOGGER.info(50 * "=")

    if path == '':
        if 'access_token' not in session:
            return opchoice(environ, start_response, clients)
        else:
            client = clients[session["op"]]
            # check_session_iframe_url = None
            try:
                # check_session_iframe_url = client.provider_info[
                #     "check_session_iframe"]

                session["session_management"] = {
                    "session_state": query["session_state"][0],
                    "client_id": client.client_id,
                    "issuer": client.provider_info["issuer"]
                }
            except KeyError:
                pass

            kwargs = dict([(p, session[p])
                           for p in ['id_token', 'userinfo', 'user_id']
                           if p in session])

            return opresult(environ, start_response, **kwargs)
    elif path == "rp":  # After having chosen which OP to authenticate at
        if "uid" in query:
            try:
                client = clients.dynamic_client(userid=query["uid"][0])
            except (ConnectionError, OIDCError) as err:
                return operror(environ, start_response, '{}'.format(err))
        elif 'issuer' in query:
            try:
                client = clients[query["issuer"][0]]
            except (ConnectionError, OIDCError) as err:
                return operror(environ, start_response, '{}'.format(err))
        else:
            client = clients[query["op"][0]]

        client.get_userinfo = session._params['userinfo']
        try:
            client.resource_server = session._params['resource_server']
        except KeyError:
            pass

        try:
            session['response_format'] = query["response_format"][0]
        except KeyError:
            session['response_format'] = 'html'

        session["op"] = client.provider_info["issuer"]

        try:
            resp = client.create_authn_request(session, acr_values)
        except Exception as err:
            logging.error(err)
            raise
        else:
            return resp(environ, start_response)
    elif path.endswith('authz_post'):
        try:
            _iss = session['op']
        except KeyError:
            LOGGER.info('[{}] No active session with {}'.format(
                session.id, environ['REMOTE_ADDR']))
            return opchoice(environ, start_response, clients)
        else:
            client = clients[_iss]

        query = parse_qs(get_post(environ))
        try:
            info = query["fragment"][0]
        except KeyError:
            return sorry_response(environ, start_response, conf.BASE,
                                  "missing fragment ?!")
        if info == ['x']:
            return sorry_response(environ, start_response, conf.BASE,
                                  "Expected fragment didn't get one ?!")

        LOGGER.info('[{}] Fragment part: {}'.format(session.id, info))

        try:
            result = client.callback(info, session, 'urlencoded')
            if isinstance(result, SeeOther):
                return result(environ, start_response)
        except OIDCError as err:
            return operror(environ, start_response, "%s" % err)
        except Exception as err:
            raise
        else:
            session.update(result)
            res = SeeOther(server_env['base_url'])
            return res(environ, start_response)
    elif path in clients.return_paths(
    ):  # After having authenticated at the OP
        try:
            _iss = session['op']
        except KeyError:
            LOGGER.info('[{}]No active session with {}'.format(
                session.id, environ['REMOTE_ADDR']))
            return opchoice(environ, start_response, clients)

        # mismatch between callback and return_uri
        # ignore trailing '/'
        if not url_eq(_iss, clients.path[path]):
            LOGGER.warning('[{}]issuer mismatch: {} != {}'.format(
                session.id, _iss, clients.path[path]))
            return operror(environ, start_response, "%s" % 'Not allowed')

        client = clients[clients.path[path]]

        _response_type = client.behaviour["response_type"]
        try:
            _response_mode = client.authz_req[
                session['state']]['response_mode']
        except KeyError:
            _response_mode = ''

        LOGGER.info("[{}]response_type: {}, response_mode: {}".format(
            session.id, _response_type, _response_mode))
        if _response_type and _response_type != "code":
            # Fall through if it's a query response anyway
            if query:
                pass
            elif _response_mode:
                # form_post encoded
                pass
            else:
                return opresult_fragment(environ, start_response)

        LOGGER.info("[{}]Query part: {}".format(session.id, query))

        try:
            result = client.callback(query, session)
            if isinstance(result, SeeOther):
                return result(environ, start_response)
        except OIDCError as err:
            return operror(environ, start_response, "%s" % err)
        except Exception:
            raise
        else:
            session.update(result)
            res = SeeOther(server_env['base_url'])
            return res(environ, start_response)
    elif path == "logout":  # After the user has pressed the logout button
        try:
            _iss = session['op']
        except KeyError:
            LOGGER.info('[{}]No active session with {}'.format(
                session.id, environ['REMOTE_ADDR']))
            return opchoice(environ, start_response, clients)
        client = clients[_iss]
        try:
            del client.authz_req[session['state']]
        except KeyError:
            pass

        logout_url = client.end_session_endpoint
        try:
            # Specify to which URL the OP should return the user after
            # log out. That URL must be registered with the OP at client
            # registration.
            logout_url += "?" + urlencode({
                "post_logout_redirect_uri":
                client.registration_response["post_logout_redirect_uris"][0]
            })
        except KeyError:
            pass
        else:
            # If there is an ID token send it along as a id_token_hint
            _idtoken = get_id_token(client, session)
            if _idtoken:
                logout_url += "&" + urlencode({
                    "id_token_hint":
                    id_token_as_signed_jwt(client, _idtoken, "HS256")
                })
            # Also append the ACR values
            logout_url += "&" + urlencode({"acr_values": acr_values}, True)

        LOGGER.debug("[{}]Logout URL: {}".format(session.id, logout_url))
        LOGGER.debug("Logging out from session: [{}]".format(session.id))
        session.delete()
        resp = SeeOther(str(logout_url))
        return resp(environ, start_response)
    elif path == "logout_success":  # post_logout_redirect_uri
        return Response("Logout successful!")(environ, start_response)
    elif path == "session_iframe":  # session management
        kwargs = session["session_management"]
        resp = Response(mako_template="rp_session_iframe.mako",
                        template_lookup=LOOKUP)
        return resp(environ,
                    start_response,
                    session_change_url="{}session_change".format(
                        server_env["base_url"]),
                    **kwargs)
    elif path == "session_change":
        try:
            _iss = session['op']
        except KeyError:
            LOGGER.info('[{}]No active session with {}'.format(
                session.id, environ['REMOTE_ADDR']))
            return opchoice(environ, start_response, clients)

        try:
            client = clients[_iss]
        except KeyError:
            return Response("No valid session.")(environ, start_response)

        kwargs = {"prompt": "none"}
        # If there is an ID token send it along as a id_token_hint
        idt = get_id_token(client, session)
        if idt:
            kwargs["id_token_hint"] = id_token_as_signed_jwt(
                client, idt, "HS256")
        resp = client.create_authn_request(session, acr_values, **kwargs)
        return resp(environ, start_response)

    return opchoice(environ, start_response, clients)
コード例 #31
0
ファイル: rp3.py プロジェクト: SilentCircle/pyoidc
def application(environ, start_response):
    session = environ['beaker.session']
    path = environ.get('PATH_INFO', '').lstrip('/')
    if path == "robots.txt":
        return static(environ, start_response, LOGGER, "static/robots.txt")
    elif path.startswith("static/"):
        return static(environ, start_response, LOGGER, path)

    query = parse_qs(environ["QUERY_STRING"])
    acr_values = session._params['acrs']
    clients = session._params['clients']
    server_env = session._params['server_env']

    LOGGER.info(50 * "=")
    LOGGER.info("[{}] path: {}".format(session.id, path))
    LOGGER.info(50 * "=")

    if path == '':
        if 'access_token' not in session:
            return opchoice(environ, start_response, clients)
        else:
            client = clients[session["op"]]
            check_session_iframe_url = None
            try:
                check_session_iframe_url = client.provider_info[
                    "check_session_iframe"]

                session["session_management"] = {
                    "session_state": query["session_state"][0],
                    "client_id": client.client_id,
                    "issuer": client.provider_info["issuer"]
                }
            except KeyError:
                pass

            kwargs = dict(
                [(p, session[p]) for p in ['id_token', 'userinfo', 'user_id'] if
                 p in session])

            return opresult(environ, start_response, **kwargs)


    elif path == "rp":  # After having chosen which OP to authenticate at
        if "uid" in query:
            try:
                client = clients.dynamic_client(userid=query["uid"][0])
            except (ConnectionError, OIDCError) as err:
                return operror(environ, start_response, '{}'.format(err))
        elif 'issuer' in query:
            try:
                client = clients[query["issuer"][0]]
            except KeyError:
                try:
                    client = clients.dynamic_client(issuer=query["issuer"][0])
                except (ConnectionError, OIDCError) as err:
                    return operror(environ, start_response, '{}'.format(err))
        else:
            client = clients[query["op"][0]]

        client.get_userinfo = session._params['userinfo']
        try:
            client.resource_server = session._params['resource_server']
        except KeyError:
            pass

        try:
            session['response_format'] = query["response_format"][0]
        except KeyError:
            session['response_format'] = 'html'

        session["op"] = client.provider_info["issuer"]

        try:
            resp = client.create_authn_request(session, acr_values)
        except Exception:
            raise
        else:
            return resp(environ, start_response)
    elif path.endswith('authz_post'):
        try:
            _iss = session['op']
        except KeyError:
            LOGGER.info(
                '[{}] No active session with {}'.format(session.id,
                                                        environ['REMOTE_ADDR']))
            return opchoice(environ, start_response, clients)
        else:
            client = clients[_iss]

        query = parse_qs(get_post(environ))
        try:
            info = query["fragment"][0]
        except KeyError:
            return sorry_response(environ, start_response, conf.BASE,
                                  "missing fragment ?!")
        if info == ['x']:
            return sorry_response(environ, start_response, conf.BASE,
                                  "Expected fragment didn't get one ?!")

        LOGGER.info('[{}] Fragment part: {}'.format(session.id, info))

        try:
            result = client.callback(info, session, 'urlencoded')
            if isinstance(result, SeeOther):
                return result(environ, start_response)
        except OIDCError as err:
            return operror(environ, start_response, "%s" % err)
        except Exception as err:
            raise
        else:
            session.update(result)
            res = SeeOther(location=server_env['base_url'])
            return res(environ, start_response)
    elif path in clients.return_paths():  # After having authenticated at the OP
        try:
            _iss = session['op']
        except KeyError:
            LOGGER.info(
                '[{}]No active session with {}'.format(session.id,
                                                       environ['REMOTE_ADDR']))
            return opchoice(environ, start_response, clients)

        # mismatch between callback and return_uri
        if _iss != clients.path[path]:
            LOGGER.warning(
                '[{}]issuer mismatch: {} != {}'.format(session.id, _iss,
                                                       clients.path[path]))
            return operror(environ, start_response, "%s" % 'Not allowed')

        client = clients[session["op"]]

        _response_type = client.behaviour["response_type"]
        try:
            _response_mode = client.authz_req[session['state']]['response_mode']
        except KeyError:
            _response_mode = ''

        LOGGER.info(
            "[{}]response_type: {}, response_mode: {}".format(session.id,
                                                              _response_type,
                                                              _response_mode))
        if _response_type and _response_type != "code":
            # Fall through if it's a query response anyway
            if query:
                pass
            elif _response_mode:
                # form_post encoded
                pass
            else:
                return opresult_fragment(environ, start_response)

        LOGGER.info("[{}]Query part: {}".format(session.id, query))

        try:
            result = client.callback(query, session)
            if isinstance(result, SeeOther):
                return result(environ, start_response)
        except OIDCError as err:
            return operror(environ, start_response, "%s" % err)
        except Exception:
            raise
        else:
            session.update(result)
            res = SeeOther(server_env['base_url'])
            return res(environ, start_response)
    elif path == "logout":  # After the user has pressed the logout button
        try:
            _iss = session['op']
        except KeyError:
            LOGGER.info(
                '[{}]No active session with {}'.format(session.id,
                                                       environ['REMOTE_ADDR']))
            return opchoice(environ, start_response, clients)
        client = clients[_iss]
        try:
            del client.authz_req[session['state']]
        except KeyError:
            pass

        logout_url = client.end_session_endpoint
        try:
            # Specify to which URL the OP should return the user after
            # log out. That URL must be registered with the OP at client
            # registration.
            logout_url += "?" + urlencode(
                {"post_logout_redirect_uri": client.registration_response[
                    "post_logout_redirect_uris"][0]})
        except KeyError:
            pass
        else:
            # If there is an ID token send it along as a id_token_hint
            _idtoken = get_id_token(client, session)
            if _idtoken:
                logout_url += "&" + urlencode({
                    "id_token_hint": id_token_as_signed_jwt(client, _idtoken,
                                                            "HS256")})
            # Also append the ACR values
            logout_url += "&" + urlencode({"acr_values": acr_values},
                                          True)

        LOGGER.debug("[{}]Logout URL: {}".format(session.id, logout_url))
        LOGGER.debug("Logging out from session: [{}]".format(session.id))
        session.delete()
        resp = SeeOther(str(logout_url))
        return resp(environ, start_response)
    elif path == "logout_success":  # post_logout_redirect_uri
        return Response("Logout successful!")(environ, start_response)
    elif path == "session_iframe":  # session management
        kwargs = session["session_management"]
        resp = Response(mako_template="rp_session_iframe.mako",
                        template_lookup=LOOKUP)
        return resp(environ, start_response,
                    session_change_url="{}session_change".format(
                        server_env["base_url"]),
                    **kwargs)
    elif path == "session_change":
        try:
            _iss = session['op']
        except KeyError:
            LOGGER.info(
                '[{}]No active session with {}'.format(session.id,
                                                       environ['REMOTE_ADDR']))
            return opchoice(environ, start_response, clients)

        try:
            client = clients[_iss]
        except KeyError:
            return Response("No valid session.")(environ, start_response)

        kwargs = {"prompt": "none"}
        # If there is an ID token send it along as a id_token_hint
        idt = get_id_token(client, session)
        if idt:
            kwargs["id_token_hint"] = id_token_as_signed_jwt(client, idt,
                                                             "HS256")
        resp = client.create_authn_request(session, acr_values, **kwargs)
        return resp(environ, start_response)

    return opchoice(environ, start_response, clients)
コード例 #32
0
ファイル: rp3.py プロジェクト: zckb/pyoidc
    def application(self, environ, start_response):
        b_session = environ['beaker.session']

        jlog = JLog(LOGGER, b_session.id)

        path = environ.get('PATH_INFO', '').lstrip('/')
        try:
            jlog.info({
                'cookie': environ['HTTP_COOKIE'].split(';'),
                'path': path
            })
        except KeyError:
            jlog.info({'path': path})

        if path == "robots.txt":
            return static(environ, start_response, LOGGER, "static/robots.txt")
        elif path.startswith("static/"):
            return static(environ, start_response, LOGGER, path)
        elif '/static/' in path:
            pre, post = path.split('static')
            return static(environ, start_response, LOGGER, 'static' + post)

        query = parse_qs(environ["QUERY_STRING"])

        try:
            session = b_session['session_info']
        except KeyError:
            session = self.find_session(**query)
            if session:
                b_session['session_info'] = session
            else:
                session = {}
                b_session['session_info'] = session
                self.session[b_session.id] = session

        if path == '':
            if 'access_token' not in session:
                return opchoice(environ, start_response, self.clients)
            else:
                client = self.clients[session["op"]]
                # check_session_iframe_url = None
                try:
                    # check_session_iframe_url = client.provider_info[
                    #     "check_session_iframe"]

                    session["session_management"] = {
                        "session_state": query["session_state"][0],
                        "client_id": client.client_id,
                        "issuer": client.provider_info["issuer"]
                    }
                except KeyError:
                    pass

                kwargs = dict([(p, session[p])
                               for p in ['id_token', 'userinfo', 'user_id']
                               if p in session])

                return opresult(environ, start_response, **kwargs)
        elif path == "rp":  # After having chosen which OP to authenticate at
            if "uid" in query:
                try:
                    client = self.clients.dynamic_client(
                        userid=query["uid"][0])
                except (ConnectionError, OIDCError) as err:
                    return operror(environ, start_response, '{}'.format(err))
            elif 'issuer' in query:
                try:
                    client = self.clients[query["issuer"][0]]
                except (ConnectionError, OIDCError) as err:
                    return operror(environ, start_response, '{}'.format(err))
            else:
                client = self.clients[query["op"][0]]

            return self.init_client(client, session, query, environ,
                                    start_response)
        elif path.endswith('authz_post'):
            try:
                _iss = session['op']
            except KeyError:
                jlog.error({
                    'reason': 'No active session',
                    'remote_addr': environ['REMOTE_ADDR']
                })

                return opchoice(environ, start_response, self.clients)
            else:
                client = self.clients[_iss]

            query = parse_qs(get_post(environ))
            try:
                info = query["fragment"][0]
            except KeyError:
                return sorry_response(environ, start_response, self.base,
                                      "missing fragment ?!")
            if info == ['x']:
                return sorry_response(environ, start_response, self.base,
                                      "Expected fragment didn't get one ?!")

            jlog.info({'fragment': info})

            try:
                result = client.callback(info, session, 'urlencoded')
                if isinstance(result, SeeOther):
                    return result(environ, start_response)
            except OIDCError as err:
                return operror(environ, start_response, "%s" % err)
            except Exception as err:
                raise
            else:
                session.update(result)
                res = SeeOther(self.conf['base_url'])
                return res(environ, start_response)
        elif path in self.clients.return_paths():  # After having
            # authenticated at the OP
            jlog.info({'query': query})

            _client = None
            for cli in self.clients.client.values():
                if query['state'][0] in cli.authz_req:
                    _client = cli
                    break

            if not _client:
                jlog.error({
                    'reason': 'No active session',
                    'remote_addr': environ['REMOTE_ADDR'],
                    'state': query['state'][0]
                })
                return opchoice(environ, start_response, self.clients)

            if 'error' in query:  # something amiss
                if query['error'][0] == 'access_denied':  # Try reregistering
                    _iss = _client.provider_info['issuer']
                    del self.clients[_iss]
                    try:
                        client = self.clients[_iss]
                    except (ConnectionError, OIDCError) as err:
                        return operror(environ, start_response,
                                       '{}'.format(err))
                    return self.init_client(client, session, query, environ,
                                            start_response)

            try:
                _iss = query['iss'][0]
            except KeyError:
                pass
            else:
                if _iss != _client.provider_info['issuer']:
                    jlog.error({'reason': 'Got response from wrong OP'})
                    return opchoice(environ, start_response, self.clients)

            _response_type = _client.behaviour["response_type"]
            try:
                _response_mode = _client.authz_req[
                    session['state']]['response_mode']
            except KeyError:
                _response_mode = ''

            jlog.info({
                "response_type": _response_type,
                "response_mode": _response_mode
            })

            if _response_type and _response_type != "code":
                # Fall through if it's a query response anyway
                if query:
                    pass
                elif _response_mode:
                    # form_post encoded
                    pass
                else:
                    return opresult_fragment(environ, start_response)

            try:
                result = _client.callback(query, session)
                if isinstance(result, SeeOther):
                    return result(environ, start_response)
            except OIDCError as err:
                return operror(environ, start_response, "%s" % err)
            except Exception:
                raise
            else:
                session.update(result)
                res = SeeOther(self.conf['base_url'])
                return res(environ, start_response)
        elif path == "logout":  # After the user has pressed the logout button
            try:
                _iss = session['op']
            except KeyError:
                jlog.error({
                    'reason': 'No active session',
                    'remote_addr': environ['REMOTE_ADDR']
                })
                return opchoice(environ, start_response, self.clients)
            client = self.clients[_iss]
            try:
                del client.authz_req[session['state']]
            except KeyError:
                pass

            logout_url = client.end_session_endpoint
            try:
                # Specify to which URL the OP should return the user after
                # log out. That URL must be registered with the OP at client
                # registration.
                logout_url += "?" + urlencode({
                    "post_logout_redirect_uri":
                    client.registration_response["post_logout_redirect_uris"]
                    [0]
                })
            except KeyError:
                pass
            else:
                # If there is an ID token send it along as a id_token_hint
                _idtoken = get_id_token(client, session)
                if _idtoken:
                    logout_url += "&" + urlencode({
                        "id_token_hint":
                        id_token_as_signed_jwt(client, _idtoken, "HS256")
                    })
                # Also append the ACR values
                logout_url += "&" + urlencode({"acr_values": self.acr_values},
                                              True)

            session.delete()
            resp = SeeOther(str(logout_url))
            return resp(environ, start_response)
        elif path == "logout_success":  # post_logout_redirect_uri
            return Response("Logout successful!")(environ, start_response)
        elif path == "session_iframe":  # session management
            kwargs = session["session_management"]
            resp = Response(mako_template="rp_session_iframe.mako",
                            template_lookup=LOOKUP)
            return resp(environ,
                        start_response,
                        session_change_url="{}session_change".format(
                            self.conf["base_url"]),
                        **kwargs)
        elif path == "session_change":
            try:
                _iss = session['op']
            except KeyError:
                jlog.error({
                    'reason': 'No active session',
                    'remote_addr': environ['REMOTE_ADDR']
                })
                return opchoice(environ, start_response, self.clients)

            try:
                client = self.clients[_iss]
            except KeyError:
                return Response("No valid session.")(environ, start_response)

            kwargs = {"prompt": "none"}
            # If there is an ID token send it along as a id_token_hint
            idt = get_id_token(client, session)
            if idt:
                kwargs["id_token_hint"] = id_token_as_signed_jwt(
                    client, idt, "HS256")
            resp = client.create_authn_request(session, self.acr_values,
                                               **kwargs)
            return resp(environ, start_response)

        return opchoice(environ, start_response, self.clients)