예제 #1
0
def webfinger(environ, events):
    query = parse_qs(environ["QUERY_STRING"])
    _op = environ["oic.op"]

    try:
        if query["rel"] != [OIC_ISSUER]:
            events.store(
                EV_CONDITION,
                State('webfinger_parameters',
                      ERROR,
                      message='parameter rel wrong value: {}'.format(
                          query['rel'])))
            return BadRequest('Parameter value error')
        else:
            resource = query["resource"][0]
    except KeyError as err:
        events.store(
            EV_CONDITION,
            State('webfinger_parameters',
                  ERROR,
                  message='parameter {} missing'.format(err)))
        resp = BadRequest("Missing parameter in request")
    else:
        wf = WebFinger()
        resp = Response(wf.response(subject=resource, base=_op.baseurl))
    return resp
예제 #2
0
파일: FakeOp.py 프로젝트: borgand/SATOSA
 def setup_webfinger_endpoint(self):
     wf = WebFinger()
     resp = Response(wf.response(subject=self.op_base, base=self.op_base))
     responses.add(responses.GET,
                   self.op_base + ".well-known/webfinger",
                   body=resp.message,
                   status=200,
                   content_type='application/json')
예제 #3
0
파일: FakeOp.py 프로젝트: borgand/SATOSA
 def setup_webfinger_endpoint(self):
     wf = WebFinger()
     resp = Response(wf.response(subject=self.op_base, base=self.op_base))
     responses.add(responses.GET,
                   self.op_base + ".well-known/webfinger",
                   body=resp.message,
                   status=200,
                   content_type='application/json')
예제 #4
0
    def test_extra_member_response(self):
        wf = WebFinger()
        resp = wf.response('acct:local@domain', 'https://example.com',
                           dummy='foo')

        # resp should be a JSON document

        _resp = json.loads(resp)
        assert _resp['dummy'] == 'foo'
예제 #5
0
파일: server.py 프로젝트: ga4gh/server
def _webfinger(provider, request, **kwargs):
    """Handle webfinger requests."""
    params = urlparse.parse_qs(request)
    if params["rel"][0] == OIC_ISSUER:
        wf = WebFinger()
        return Response(wf.response(params["resource"][0], provider.baseurl),
                        headers=[("Content-Type", "application/jrd+json")])
    else:
        return BadRequest("Incorrect webfinger.")
예제 #6
0
def _webfinger(provider, request, **kwargs):
    """Handle webfinger requests."""
    params = urlparse.parse_qs(request)
    if params["rel"][0] == OIC_ISSUER:
        wf = WebFinger()
        return Response(wf.response(params["resource"][0], provider.baseurl),
                        headers=[("Content-Type", "application/jrd+json")])
    else:
        return BadRequest("Incorrect webfinger.")
예제 #7
0
    def get(self):
        params = self.request.query_arguments

        if params['rel'][0].decode('utf-8') == OIC_ISSUER:
            wf = WebFinger()
            self.write(
                wf.response(params["resource"][0].decode('utf-8'),
                            self.settings['oidc_provider'].baseurl))
        else:
            return self.send_error()
예제 #8
0
    def test_extra_member_response(self):
        wf = WebFinger()
        resp = wf.response("acct:local@domain",
                           "https://example.com",
                           dummy="foo")

        # resp should be a JSON document

        _resp = json.loads(resp)
        assert _resp["dummy"] == "foo"
예제 #9
0
파일: server.py 프로젝트: programDEV/pyoidc
def webfinger(environ, start_response, _):
    query = parse_qs(environ["QUERY_STRING"])
    try:
        assert query["rel"] == [OIC_ISSUER]
        resource = query["resource"][0]
    except KeyError:
        resp = BadRequest("Missing parameter in request")
    else:
        wf = WebFinger()
        resp = Response(wf.response(subject=resource, base=OAS.baseurl))
    return resp(environ, start_response)
예제 #10
0
파일: as.py 프로젝트: dv10den/pyuma
def webfinger(environ):
    query = parse_qs(environ["QUERY_STRING"])
    try:
        assert query["rel"] == [OIC_ISSUER]
        resource = query["resource"][0]
    except KeyError:
        resp = BadRequest("Missing parameter in request")
    else:
        wf = WebFinger()
        resp = Response(wf.response(subject=resource, base=AUTHZSRV.baseurl))
    return resp
예제 #11
0
 def _webfinger(self):
     query = request.args
     try:
         assert query["rel"] == OIC_ISSUER
         resource = query["resource"][0]
     except KeyError:
         resp = BadRequest("Missing parameter in request")
     else:
         wf = WebFinger()
         resp = Response(wf.response(subject=resource, base=self.provider.baseurl))
     return resp
예제 #12
0
 def webfinger(self, environ, start_response):
     query = parse_qs(environ["QUERY_STRING"])
     try:
         rel = query["rel"]
         resource = query["resource"][0]
     except KeyError:
         resp = BadRequest("Missing parameter in request")
     else:
         if rel != [OIC_ISSUER]:
             resp = BadRequest("Bad issuer in request")
         else:
             wf = WebFinger()
             resp = Response(
                 wf.response(subject=resource, base=self.oas.baseurl))
     return resp(environ, start_response)
예제 #13
0
파일: endpoints_n.py 프로젝트: rohe/otest
def webfinger(environ, start_response, session_info, trace, **kwargs):
    query = parse_qs(environ["QUERY_STRING"])

    # Find the identifier
    session_info["test_id"] = find_identifier(query["resource"][0])

    trace.info(HEADER % "WebFinger")
    trace.request(environ["QUERY_STRING"])
    trace.info("QUERY: %s" % (query,))

    try:
        assert query["rel"] == [OIC_ISSUER]
        resource = query["resource"][0]
    except AssertionError:
        errmsg = "Wrong 'rel' value: %s" % query["rel"][0]
        trace.error(errmsg)
        resp = BadRequest(errmsg)
    except KeyError:
        errmsg = "Missing 'rel' parameter in request"
        trace.error(errmsg)
        resp = BadRequest(errmsg)
    else:
        wf = WebFinger()
        p = urlparse(resource)

        if p.scheme == "acct":
            l, _ = p.path.split("@")
            path = pathmap.IDMAP[l.lower()]
        else:  # scheme == http/-s
            try:
                path = pathmap.IDMAP[p.path[1:].lower()]
            except KeyError:
                path = None

        if path:
            _url = os.path.join(kwargs["op_arg"]["baseurl"],
                                session_info["test_id"],
                                path[1:])
            resp = Response(wf.response(subject=resource, base=_url),
                            content="application/jrd+json")
        else:
            resp = BadRequest("Incorrect resource specification")

        trace.reply(resp.message)

    dump_log(session_info, trace)
    return resp(environ, start_response)
예제 #14
0
def webfinger(environ, start_response, session_info, trace, **kwargs):
    query = parse_qs(environ["QUERY_STRING"])

    # Find the identifier
    session_info["test_id"] = find_identifier(query["resource"][0])

    trace.info(HEADER % "WebFinger")
    trace.request(environ["QUERY_STRING"])
    trace.info("QUERY: %s" % (query, ))

    try:
        assert query["rel"] == [OIC_ISSUER]
        resource = query["resource"][0]
    except AssertionError:
        errmsg = "Wrong 'rel' value: %s" % query["rel"][0]
        trace.error(errmsg)
        resp = BadRequest(errmsg)
    except KeyError:
        errmsg = "Missing 'rel' parameter in request"
        trace.error(errmsg)
        resp = BadRequest(errmsg)
    else:
        wf = WebFinger()
        p = urlparse(resource)

        if p.scheme == "acct":
            l, _ = p.path.split("@")
            path = pathmap.IDMAP[l.lower()]
        else:  # scheme == http/-s
            try:
                path = pathmap.IDMAP[p.path[1:].lower()]
            except KeyError:
                path = None

        if path:
            _url = os.path.join(kwargs["op_arg"]["baseurl"],
                                session_info["test_id"], path[1:])
            resp = Response(wf.response(subject=resource, base=_url),
                            content="application/jrd+json")
        else:
            resp = BadRequest("Incorrect resource specification")

        trace.reply(resp.message)

    dump_log(session_info, trace)
    return resp(environ, start_response)
예제 #15
0
def webfinger(environ, start_response, session_info, events, jlog, **kwargs):
    _query = session_info['parameters']
    events.store(EV_REQUEST, Operation("WebFinger", _query))

    try:
        assert _query["rel"] == [OIC_ISSUER]
        resource = _query["resource"][0]
    except AssertionError:
        errmsg = "Wrong 'rel' value: %s" % _query["rel"][0]
        events.store(EV_FAULT, errmsg)
        resp = BadRequest(errmsg)
    except KeyError:
        errmsg = "Missing 'rel' parameter in request"
        events.store(EV_FAULT, errmsg)
        resp = BadRequest(errmsg)
    else:
        wf = WebFinger()

        _url = os.path.join(kwargs["op_arg"]["baseurl"],
                            session_info['oper_id'],
                            session_info["test_id"])

        _mesg = wf.response(subject=resource, base=_url)
        if session_info['test_id'] == 'rp-discovery-webfinger-http-href':
            _msg = json.loads(_mesg)
            _msg['links'][0]['href'] = _msg['links'][0]['href'].replace(
                'https', 'http')
            _mesg = json.dumps(_msg)
        elif session_info['test_id'] == 'rp-discovery-webfinger-unknown-member':
            _msg = json.loads(_mesg)
            _msg['dummy'] = 'foobar'
            _mesg = json.dumps(_msg)

        resp = Response(_mesg,
                        content="application/jrd+json")

        events.store(EV_RESPONSE, resp.message)

    jlog.info(resp2json(resp))

    dump_log(session_info, events)
    return resp(environ, start_response)
예제 #16
0
def webfinger(environ, start_response, session_info, events, jlog, **kwargs):
    _query = session_info['parameters']
    events.store(EV_REQUEST, Operation("WebFinger", _query))

    try:
        assert _query["rel"] == [OIC_ISSUER]
        resource = _query["resource"][0]
    except AssertionError:
        errmsg = "Wrong 'rel' value: %s" % _query["rel"][0]
        events.store(EV_FAULT, errmsg)
        resp = BadRequest(errmsg)
    except KeyError:
        errmsg = "Missing 'rel' parameter in request"
        events.store(EV_FAULT, errmsg)
        resp = BadRequest(errmsg)
    else:
        wf = WebFinger()

        _url = os.path.join(kwargs["op_arg"]["baseurl"],
                            session_info['oper_id'], session_info["test_id"])

        _mesg = wf.response(subject=resource, base=_url)
        if session_info['test_id'] == 'rp-discovery-webfinger-http-href':
            _msg = json.loads(_mesg)
            _msg['links'][0]['href'] = _msg['links'][0]['href'].replace(
                'https', 'http')
            _mesg = json.dumps(_msg)
        elif session_info[
                'test_id'] == 'rp-discovery-webfinger-unknown-member':
            _msg = json.loads(_mesg)
            _msg['dummy'] = 'foobar'
            _mesg = json.dumps(_msg)

        resp = Response(_mesg, content="application/jrd+json")

        events.store(EV_RESPONSE, resp.message)

    jlog.info(resp2json(resp))

    dump_log(session_info, events)
    return resp(environ, start_response)
예제 #17
0
파일: server.py 프로젝트: dv10den/oidctest
def webfinger(environ, start_response, session, trace):
    query = parse_qs(environ["QUERY_STRING"])

    # Find the identifier
    session["test_id"] = find_identifier(query["resource"][0])

    trace.info(HEADER % "WebFinger")
    trace.request(environ["QUERY_STRING"])
    trace.info("QUERY: %s" % (query,))

    try:
        assert query["rel"] == [OIC_ISSUER]
        resource = query["resource"][0]
    except AssertionError:
        errmsg = "Wrong 'rel' value: %s" % query["rel"][0]
        trace.error(errmsg)
        resp = BadRequest(errmsg)
    except KeyError:
        errmsg = "Missing 'rel' parameter in request"
        trace.error(errmsg)
        resp = BadRequest(errmsg)
    else:
        wf = WebFinger()
        p = urlparse(resource)
        if p.scheme == "acct":
            l, _ = p.path.split("@")
            path = pathmap.IDMAP[l]
        else:  # scheme == http/-s
            path = pathmap.IDMAP[p.path[1:]]

        _url = os.path.join(OP_ARG["baseurl"], session["test_id"], path[1:])
        resp = Response(wf.response(subject=resource, base=_url))

        trace.reply(resp.message)

    dump_log(session, trace)
    return resp(environ, start_response)
예제 #18
0
def webfinger(environ, start_response, session, trace):
    query = parse_qs(environ["QUERY_STRING"])

    # Find the identifier
    session["test_id"] = find_identifier(query["resource"][0])

    trace.info(HEADER % "WebFinger")
    trace.request(environ["QUERY_STRING"])
    trace.info("QUERY: %s" % (query,))

    try:
        assert query["rel"] == [OIC_ISSUER]
        resource = query["resource"][0]
    except AssertionError:
        errmsg = "Wrong 'rel' value: %s" % query["rel"][0]
        trace.error(errmsg)
        resp = BadRequest(errmsg)
    except KeyError:
        errmsg = "Missing 'rel' parameter in request"
        trace.error(errmsg)
        resp = BadRequest(errmsg)
    else:
        wf = WebFinger()
        p = urlparse(resource)
        if p.scheme == "acct":
            l, _ = p.path.split("@")
            path = pathmap.IDMAP[l]
        else:  # scheme == http/-s
            path = pathmap.IDMAP[p.path[1:]]

        _url = os.path.join(OP_ARG["baseurl"], session["test_id"], path[1:])
        resp = Response(wf.response(subject=resource, base=_url))

        trace.reply(resp.message)

    dump_log(session, trace)
    return resp(environ, start_response)
예제 #19
0
파일: fakeoicsrv.py 프로젝트: HaToHo/pyoidc
class MyFakeOICServer(Server):
    def __init__(self, name=""):
        Server.__init__(self)
        self.sdb = SessionDB()
        self.name = name
        self.client = {}
        self.registration_expires_in = 3600
        self.host = ""
        self.webfinger = WebFinger()

    #noinspection PyUnusedLocal
    def http_request(self, path, method="GET", **kwargs):
        part = urlparse(path)
        path = part[2]
        query = part[4]
        self.host = "%s://%s" % (part.scheme, part.netloc)

        response = Response
        response.status_code = 500
        response.text = ""

        if path == ENDPOINT["authorization_endpoint"]:
            assert method == "GET"
            response = self.authorization_endpoint(query)
        elif path == ENDPOINT["token_endpoint"]:
            assert method == "POST"
            response = self.token_endpoint(kwargs["data"])
        elif path == ENDPOINT["user_info_endpoint"]:
            assert method == "POST"
            response = self.userinfo_endpoint(kwargs["data"])
        elif path == ENDPOINT["refresh_session_endpoint"]:
            assert method == "GET"
            response = self.refresh_session_endpoint(query)
        elif path == ENDPOINT["check_session_endpoint"]:
            assert method == "GET"
            response = self.check_session_endpoint(query)
        elif path == ENDPOINT["end_session_endpoint"]:
            assert method == "GET"
            response = self.end_session_endpoint(query)
        elif path == ENDPOINT["registration_endpoint"]:
            if method == "POST":
                response = self.registration_endpoint(kwargs["data"])
        elif path == "/.well-known/webfinger":
            assert method == "GET"
            qdict = parse_qs(query)
            response.status_code = 200
            response.text = self.webfinger.response(qdict["resource"][0],
                                                    "%s/" % self.name)
        elif path == "/.well-known/openid-configuration":
            assert method == "GET"
            response = self.openid_conf()

        return response

    def authorization_endpoint(self, query):
        req = self.parse_authorization_request(query=query)
        sid = self.sdb.create_authz_session(sub="user", areq=req)
        _info = self.sdb[sid]
        _info["sub"] = _info["local_sub"]

        if "code" in req["response_type"]:
            if "token" in req["response_type"]:
                grant = _info["code"]
                _dict = self.sdb.upgrade_to_token(grant)
                _dict["oauth_state"] = "authz",

                _dict = by_schema(AuthorizationResponse(), **_dict)
                resp = AuthorizationResponse(**_dict)
                #resp.code = grant
            else:
                resp = AuthorizationResponse(state=req["state"],
                                             code=_info["code"])

        else:  # "implicit" in req.response_type:
            grant = _info["code"]
            params = AccessTokenResponse.c_param.keys()

            _dict = dict([(k, v) for k, v in
                          self.sdb.upgrade_to_token(grant).items() if k in
                                                                     params])
            try:
                del _dict["refresh_token"]
            except KeyError:
                pass

            if "id_token" in req["response_type"]:
                _idt = self.make_id_token(_info, issuer=self.name,
                                          access_token=_dict["access_token"])
                alg = "RS256"
                ckey = self.keyjar.get_signing_key(alg2keytype(alg),
                                                   _info["client_id"])
                _dict["id_token"] = _idt.to_jwt(key=ckey, algorithm=alg)

            resp = AccessTokenResponse(**_dict)

        location = resp.request(req["redirect_uri"])
        response = Response()
        response.headers = {"location": location}
        response.status_code = 302
        response.text = ""
        return response

    def token_endpoint(self, data):
        if "grant_type=refresh_token" in data:
            req = self.parse_refresh_token_request(body=data)
            _info = self.sdb.refresh_token(req["refresh_token"])
        elif "grant_type=authorization_code":
            req = self.parse_token_request(body=data)
            _info = self.sdb.upgrade_to_token(req["code"])
        else:
            response = TokenErrorResponse(error="unsupported_grant_type")
            return response, ""

        resp = AccessTokenResponse(**by_schema(AccessTokenResponse, **_info))
        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()

        return response

    def userinfo_endpoint(self, data):

        _ = self.parse_user_info_request(data)
        _info = {
            "sub": "melgar",
            "name": "Melody Gardot",
            "nickname": "Mel",
            "email": "*****@*****.**",
            "verified": True,
        }

        resp = OpenIDSchema(**_info)
        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()

        return response

    def registration_endpoint(self, data):
        try:
            req = self.parse_registration_request(data, "json")
        except ValueError:
            req = self.parse_registration_request(data)

        client_secret = rndstr()
        expires = utc_time_sans_frac() + self.registration_expires_in
        kwargs = {}
        if "client_id" not in req:
            client_id = rndstr(10)
            registration_access_token = rndstr(20)
            _client_info = req.to_dict()
            kwargs.update(_client_info)
            _client_info.update({
                "client_secret": client_secret,
                "info": req.to_dict(),
                "expires": expires,
                "registration_access_token": registration_access_token,
                "registration_client_uri": "register_endpoint"
            })
            self.client[client_id] = _client_info
            kwargs["registration_access_token"] = registration_access_token
            kwargs["registration_client_uri"] = "register_endpoint"
            try:
                del kwargs["operation"]
            except KeyError:
                pass
        else:
            client_id = req.client_id
            _cinfo = self.client[req.client_id]
            _cinfo["info"].update(req.to_dict())
            _cinfo["client_secret"] = client_secret
            _cinfo["expires"] = expires

        resp = RegistrationResponse(client_id=client_id,
                                    client_secret=client_secret,
                                    client_secret_expires_at=expires,
                                    **kwargs)

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()

        return response

    def check_session_endpoint(self, query):
        try:
            idtoken = self.parse_check_session_request(query=query)
        except Exception:
            raise

        response = Response()
        response.text = idtoken.to_json()
        response.headers = {"content-type": "application/json"}
        return response

    #noinspection PyUnusedLocal
    def refresh_session_endpoint(self, query):
        try:
            req = self.parse_refresh_session_request(query=query)
        except Exception:
            raise

        resp = RegistrationResponse(client_id="anonymous",
                                    client_secret="hemligt")

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()
        return response

    def end_session_endpoint(self, query):
        try:
            req = self.parse_end_session_request(query=query)
        except Exception:
            raise

        # redirect back
        resp = EndSessionResponse(state=req["state"])

        url = resp.request(req["redirect_url"])

        response = Response()
        response.headers = {"location": url}
        response.status_code = 302  # redirect
        response.text = ""
        return response

    #noinspection PyUnusedLocal
    def add_credentials(self, user, passwd):
        return

    def openid_conf(self):
        endpoint = {}
        for point, path in ENDPOINT.items():
            endpoint[point] = "%s%s" % (self.host, path)

        signing_algs = jws.SIGNER_ALGS.keys()
        resp = ProviderConfigurationResponse(
            issuer=self.name,
            scopes_supported=["openid", "profile", "email", "address"],
            identifiers_supported=["public", "PPID"],
            flows_supported=["code", "token", "code token", "id_token",
                             "code id_token", "token id_token"],
            subject_types_supported=["pairwise", "public"],
            response_types_supported=["code", "token", "id_token",
                                      "code token", "code id_token",
                                      "token id_token", "code token id_token"],
            jwks_uri="http://example.com/oidc/jwks",
            id_token_signing_alg_values_supported=signing_algs,
            grant_types_supported=["authorization_code", "implicit"],
            **endpoint)

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()
        return response
예제 #20
0
class MyFakeOICServer(Server):
    def __init__(self, name=""):
        Server.__init__(self)
        self.sdb = SessionDB(name)
        self.name = name
        self.client = {}
        self.registration_expires_in = 3600
        self.host = ""
        self.webfinger = WebFinger()
        self.userinfo_signed_response_alg = ""

    def http_request(self, path, method="GET", **kwargs):
        part = urlparse(path)
        path = part[2]
        query = part[4]
        self.host = "%s://%s" % (part.scheme, part.netloc)

        response = Response
        response.status_code = 500
        response.text = ""

        if path == ENDPOINT["authorization_endpoint"]:
            assert method == "GET"
            response = self.authorization_endpoint(query)
        elif path == ENDPOINT["token_endpoint"]:
            assert method == "POST"
            response = self.token_endpoint(kwargs["data"])
        elif path == ENDPOINT["user_info_endpoint"]:
            assert method == "POST"
            response = self.userinfo_endpoint(kwargs["data"])
        elif path == ENDPOINT["refresh_session_endpoint"]:
            assert method == "GET"
            response = self.refresh_session_endpoint(query)
        elif path == ENDPOINT["check_session_endpoint"]:
            assert method == "GET"
            response = self.check_session_endpoint(query)
        elif path == ENDPOINT["end_session_endpoint"]:
            assert method == "GET"
            response = self.end_session_endpoint(query)
        elif path == ENDPOINT["registration_endpoint"]:
            if method == "POST":
                response = self.registration_endpoint(kwargs["data"])
        elif path == "/.well-known/webfinger":
            assert method == "GET"
            qdict = parse_qs(query)
            response.status_code = 200
            response.text = self.webfinger.response(qdict["resource"][0],
                                                    "%s/" % self.name)
        elif path == "/.well-known/openid-configuration":
            assert method == "GET"
            response = self.openid_conf()

        return response

    def authorization_endpoint(self, query):
        req = self.parse_authorization_request(query=query)
        aevent = AuthnEvent("user", "salt", authn_info="acr")
        sid = self.sdb.create_authz_session(aevent, areq=req)
        self.sdb.do_sub(sid, "client_salt")
        _info = self.sdb[sid]

        if "code" in req["response_type"]:
            if "token" in req["response_type"]:
                grant = _info["code"]
                if 'offline_access' in _info['scope']:
                    _dict = self.sdb.upgrade_to_token(grant,
                                                      issue_refresh=True)
                else:
                    _dict = self.sdb.upgrade_to_token(grant)
                _dict["oauth_state"] = "authz",

                _dict = by_schema(AuthorizationResponse(), **_dict)
                resp = AuthorizationResponse(**_dict)
                # resp.code = grant
            else:
                _state = req["state"]
                resp = AuthorizationResponse(state=_state, code=_info["code"])

        else:  # "implicit" in req.response_type:
            grant = _info["code"]
            params = AccessTokenResponse.c_param.keys()

            _dict = dict([(k, v)
                          for k, v in self.sdb.upgrade_to_token(grant).items()
                          if k in params])
            try:
                del _dict["refresh_token"]
            except KeyError:
                pass

            if "id_token" in req["response_type"]:
                _idt = self.make_id_token(_info,
                                          issuer=self.name,
                                          access_token=_dict["access_token"])
                alg = "RS256"
                ckey = self.keyjar.get_signing_key(alg2keytype(alg),
                                                   _info["client_id"])
                _dict["id_token"] = _idt.to_jwt(key=ckey, algorithm=alg)

            resp = AccessTokenResponse(**_dict)

        location = resp.request(req["redirect_uri"])
        response = Response()
        response.headers = {"location": location}
        response.status_code = 302
        response.text = ""
        return response

    def token_endpoint(self, data):
        if "grant_type=refresh_token" in data:
            req = self.parse_refresh_token_request(body=data)
            _info = self.sdb.refresh_token(req["refresh_token"],
                                           req['client_id'])
        elif "grant_type=authorization_code" in data:
            req = self.parse_token_request(body=data)
            if 'offline_access' in self.sdb[req['code']]['scope']:
                _info = self.sdb.upgrade_to_token(req["code"],
                                                  issue_refresh=True)
            else:
                _info = self.sdb.upgrade_to_token(req["code"])
        else:
            response = TokenErrorResponse(error="unsupported_grant_type")
            return response, ""

        resp = AccessTokenResponse(**by_schema(AccessTokenResponse, **_info))
        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()

        return response

    def userinfo_endpoint(self, data):

        self.parse_user_info_request(data)
        _info = {
            "sub": "melgar",
            "name": "Melody Gardot",
            "nickname": "Mel",
            "email": "*****@*****.**",
            "verified": True,
        }

        resp = OpenIDSchema(**_info)
        response = Response()

        if self.userinfo_signed_response_alg:
            alg = self.userinfo_signed_response_alg
            response.headers = {"content-type": "application/jwt"}
            key = self.keyjar.get_signing_key(alg2keytype(alg), "", alg=alg)
            response.text = resp.to_jwt(key, alg)
        else:
            response.headers = {"content-type": "application/json"}
            response.text = resp.to_json()

        return response

    def registration_endpoint(self, data):
        try:
            req = self.parse_registration_request(data, "json")
        except ValueError:
            req = self.parse_registration_request(data)

        client_secret = rndstr()
        expires = utc_time_sans_frac() + self.registration_expires_in
        kwargs = {}
        if "client_id" not in req:
            client_id = rndstr(10)
            registration_access_token = rndstr(20)
            _client_info = req.to_dict()
            kwargs.update(_client_info)
            _client_info.update({
                "client_secret": client_secret,
                "info": req.to_dict(),
                "expires": expires,
                "registration_access_token": registration_access_token,
                "registration_client_uri": "register_endpoint"
            })
            self.client[client_id] = _client_info
            kwargs["registration_access_token"] = registration_access_token
            kwargs["registration_client_uri"] = "register_endpoint"
            try:
                del kwargs["operation"]
            except KeyError:
                pass
        else:
            client_id = req.client_id
            _cinfo = self.client[req.client_id]
            _cinfo["info"].update(req.to_dict())
            _cinfo["client_secret"] = client_secret
            _cinfo["expires"] = expires

        resp = RegistrationResponse(client_id=client_id,
                                    client_secret=client_secret,
                                    client_secret_expires_at=expires,
                                    **kwargs)

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()

        return response

    def check_session_endpoint(self, query):
        try:
            idtoken = self.parse_check_session_request(query=query)
        except Exception:
            raise

        response = Response()
        response.text = idtoken.to_json()
        response.headers = {"content-type": "application/json"}
        return response

    def refresh_session_endpoint(self, query):
        self.parse_refresh_session_request(query=query)

        resp = RegistrationResponse(client_id="anonymous",
                                    client_secret="hemligt")

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()
        return response

    def end_session_endpoint(self, query):
        try:
            req = self.parse_end_session_request(query=query)
        except Exception:
            raise

        # redirect back
        resp = EndSessionResponse(state=req["state"])

        url = resp.request(req["redirect_url"])

        response = Response()
        response.headers = {"location": url}
        response.status_code = 302  # redirect
        response.text = ""
        return response

    @staticmethod
    def add_credentials(user, passwd):
        pass

    def openid_conf(self):
        endpoint = {}
        for point, path in ENDPOINT.items():
            endpoint[point] = "%s%s" % (self.host, path)

        signing_algs = list(jws.SIGNER_ALGS.keys())
        resp = ProviderConfigurationResponse(
            issuer=self.name,
            scopes_supported=["openid", "profile", "email", "address"],
            identifiers_supported=["public", "PPID"],
            flows_supported=[
                "code", "token", "code token", "id_token", "code id_token",
                "token id_token"
            ],
            subject_types_supported=["pairwise", "public"],
            response_types_supported=[
                "code", "token", "id_token", "code token", "code id_token",
                "token id_token", "code token id_token"
            ],
            jwks_uri="http://example.com/oidc/jwks",
            id_token_signing_alg_values_supported=signing_algs,
            grant_types_supported=["authorization_code", "implicit"],
            **endpoint)

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()
        return response