Пример #1
0
    def test_deserialize(self):
        msg = {
            "application_type":
            "web",
            "redirect_uris": [
                "https://client.example.org/callback",
                "https://client.example.org/callback2"
            ],
            "client_name":
            "My Example",
            "client_name#ja-Jpan-JP":
            "クライアント名",
            "logo_uri":
            "https://client.example.org/logo.png",
            "subject_type":
            "pairwise",
            "sector_identifier_uri":
            "https://other.example.net/file_of_redirect_uris.json",
            "token_endpoint_auth_method":
            "client_secret_basic",
            "jwks_uri":
            "https://client.example.org/my_public_keys.jwks",
            "userinfo_encrypted_response_alg":
            "RSA1_5",
            "userinfo_encrypted_response_enc":
            "A128CBC+HS256",
            "contacts": ["*****@*****.**", "*****@*****.**"],
            "request_uris": [
                "https://client.example.org/rf.txt"
                "#qpXaRLh_n93TTR9F252ValdatUQvQiJi5BDub2BeznA"
            ]
        }

        reg = RegistrationRequest().deserialize(json.dumps(msg), "json")
        assert _eq(list(msg.keys()) + ['response_types'], reg.keys())
Пример #2
0
    def test_registration_endpoint_openid4us(self):
        req = RegistrationRequest(
            **{'token_endpoint_auth_method': u'client_secret_post',
               'redirect_uris': [
                   u'https://connect.openid4.us:5443/phpRp/index.php/callback',
                   u'https://connect.openid4.us:5443/phpRp/authcheck.php/authcheckcb'],
               'jwks_uri': u'https://connect.openid4.us:5443/phpRp/rp/rp.jwk',
               'userinfo_encrypted_response_alg': u'RSA1_5',
               'contacts': [u'*****@*****.**'],
               'userinfo_encrypted_response_enc': u'A128CBC-HS256',
               'application_type': u'web',
               'client_name': u'ABRP-17',
               'grant_types': [u'authorization_code', u'implicit'],
               'post_logout_redirect_uris': [
                   u'https://connect.openid4.us:5443/phpRp/index.php/logoutcb'],
               'subject_type': u'public',
               'response_types': [u'code', u'token', u'id_token', u'code token',
                                  u'code id_token', u'id_token token',
                                  u'code id_token token'],
               'policy_uri': u'https://connect.openid4.us:5443/phpRp/index.php/policy',
               'logo_uri': u'https://connect.openid4.us:5443/phpRp/media/logo.png'})

        resp = self.provider.registration_endpoint(request=req.to_json())

        regresp = RegistrationResponse().deserialize(resp.message, "json")
        assert _eq(regresp.keys(), list(req.keys()) +
                   ['registration_client_uri',
                    'client_secret_expires_at',
                    'registration_access_token',
                    'client_id', 'client_secret',
                    'client_id_issued_at'])
Пример #3
0
    def create_registration_request(self, **kwargs):
        """
        Create a registration request

        :param kwargs: parameters to the registration request
        :return:
        """
        req = RegistrationRequest()

        for prop in req.parameters():
            try:
                req[prop] = kwargs[prop]
            except KeyError:
                try:
                    req[prop] = self.behaviour[prop]
                except KeyError:
                    pass

        if "post_logout_redirect_uris" not in req:
            try:
                req[
                    "post_logout_redirect_uris"] = self.post_logout_redirect_uris
            except AttributeError:
                pass

        if "redirect_uris" not in req:
            try:
                req["redirect_uris"] = self.redirect_uris
            except AttributeError:
                raise MissingRequiredAttribute("redirect_uris", req)

        return req
Пример #4
0
    def test_registration_endpoint(self):
        req = RegistrationRequest()

        req["application_type"] = "web"
        req["client_name"] = "My super service"
        req["redirect_uris"] = ["http://example.com/authz"]
        req["contacts"] = ["*****@*****.**"]
        req["response_types"] = ["code"]

        resp = self.provider.registration_endpoint(request=req.to_json())

        regresp = RegistrationResponse().deserialize(resp.message, "json")
        assert _eq(
            regresp.keys(),
            [
                "redirect_uris",
                "contacts",
                "application_type",
                "client_name",
                "registration_client_uri",
                "client_secret_expires_at",
                "registration_access_token",
                "client_id",
                "client_secret",
                "client_id_issued_at",
                "response_types",
            ],
        )
Пример #5
0
    def register(self, url, **kwargs):
        """
        Register the client at an OP

        :param url: The OPs registration endpoint
        :param kwargs: parameters to the registration request
        :return:
        """
        req = RegistrationRequest()

        for prop in req.parameters():
            try:
                req[prop] = kwargs[prop]
            except KeyError:
                try:
                    req[prop] = self.behaviour[prop]
                except KeyError:
                    pass

        if "redirect_uris" not in req:
            try:
                req["redirect_uris"] = self.redirect_uris
            except AttributeError:
                raise MissingRequiredAttribute("redirect_uris")

        headers = {"content-type": "application/json"}

        rsp = self.http_request(url, "POST", data=req.to_json(),
                                headers=headers)

        return self.handle_registration_info(rsp)
Пример #6
0
    def test_registration_request(self):
        req = RegistrationRequest(
            operation="register",
            default_max_age=10,
            require_auth_time=True,
            default_acr="foo",
            application_type="web",
            redirect_uris=["https://example.com/authz_cb"])
        js = req.to_json()
        js_obj = json.loads(js)
        expected_js_obj = {
            "redirect_uris": ["https://example.com/authz_cb"],
            "application_type": "web",
            "default_acr": "foo",
            "require_auth_time": True,
            "operation": "register",
            "default_max_age": 10,
            "response_types": ["code"]
        }
        assert js_obj == expected_js_obj

        flattened_list_dict = {
            k: v[0] if isinstance(v, list) else v
            for k, v in expected_js_obj.items()
        }
        assert query_string_compare(req.to_urlencoded(),
                                    urlencode(flattened_list_dict))
Пример #7
0
    def test_parse_registration_request(self):
        regreq = RegistrationRequest(
            contacts=["*****@*****.**"],
            redirect_uris=["http://example.org/jqauthz"],
            application_name="pacubar",
            client_id=CLIENT_ID,
            operation="register",
            application_type="web",
        )

        request = self.srv.parse_registration_request(data=regreq.to_urlencoded())
        assert isinstance(request, RegistrationRequest)
        assert _eq(
            request.keys(),
            [
                "redirect_uris",
                "contacts",
                "client_id",
                "application_name",
                "operation",
                "application_type",
                "response_types",
            ],
        )
        assert request["application_name"] == "pacubar"
        assert request["operation"] == "register"
Пример #8
0
    def test_full_flow(self, context, frontend_with_extra_scopes):
        redirect_uri = "https://client.example.com/redirect"
        response_type = "code id_token token"
        mock_callback = Mock()
        frontend_with_extra_scopes.auth_req_callback_func = mock_callback
        # discovery
        http_response = frontend_with_extra_scopes.provider_config(context)
        provider_config = ProviderConfigurationResponse().deserialize(http_response.message, "json")

        # client registration
        registration_request = RegistrationRequest(redirect_uris=[redirect_uri], response_types=[response_type])
        context.request = registration_request.to_dict()
        http_response = frontend_with_extra_scopes.client_registration(context)
        registration_response = RegistrationResponse().deserialize(http_response.message, "json")

        # authentication request
        authn_req = AuthorizationRequest(
            redirect_uri=redirect_uri,
            client_id=registration_response["client_id"],
            response_type=response_type,
            scope="openid email eduperson",
            state="state",
            nonce="nonce",
        )
        context.request = dict(parse_qsl(authn_req.to_urlencoded()))
        frontend_with_extra_scopes.handle_authn_request(context)
        assert mock_callback.call_count == 1

        # fake authentication response from backend
        internal_response = self.setup_for_authn_response(
            context, frontend_with_extra_scopes, authn_req
        )
        http_response = frontend_with_extra_scopes.handle_authn_response(
            context, internal_response
        )
        authn_resp = AuthorizationResponse().deserialize(urlparse(http_response.message).fragment, "urlencoded")
        assert "code" in authn_resp
        assert "access_token" in authn_resp
        assert "id_token" in authn_resp

        # token request
        context.request = AccessTokenRequest(redirect_uri=authn_req["redirect_uri"], code=authn_resp["code"]).to_dict()
        credentials = "{}:{}".format(registration_response["client_id"], registration_response["client_secret"])
        basic_auth = urlsafe_b64encode(credentials.encode("utf-8")).decode("utf-8")
        context.request_authorization = "Basic {}".format(basic_auth)

        http_response = frontend_with_extra_scopes.token_endpoint(context)
        parsed = AccessTokenResponse().deserialize(http_response.message, "json")
        assert "access_token" in parsed
        assert "id_token" in parsed

        # userinfo request
        context.request = {}
        context.request_authorization = "Bearer {}".format(parsed["access_token"])
        http_response = frontend_with_extra_scopes.userinfo_endpoint(context)
        parsed = OpenIDSchema().deserialize(http_response.message, "json")
        assert "email" in parsed
        assert "eduperson_principal_name" in parsed
        assert "eduperson_scoped_affiliation" in parsed
Пример #9
0
 def test_registration_request_with_coupled_encryption_params(self, enc_param):
     registration_params = {
         "redirect_uris": ["https://example.com/authz_cb"],
         enc_param: "RS25asdasd6",
     }
     registration_req = RegistrationRequest(**registration_params)
     with pytest.raises(AssertionError):
         registration_req.verify()
Пример #10
0
 def test_registration_request_with_coupled_encryption_params(self,
                                                              enc_param):
     registration_params = {
         "redirect_uris": ["https://example.com/authz_cb"],
         enc_param: "RS25asdasd6"}
     registration_req = RegistrationRequest(**registration_params)
     with pytest.raises(AssertionError):
         registration_req.verify()
Пример #11
0
 def test_register_client_with_wrong_response_type(self, context, frontend):
     redirect_uri = "https://client.example.com"
     registration_request = RegistrationRequest(redirect_uris=[redirect_uri], response_types=["id_token token"])
     context.request = registration_request.to_dict()
     registration_response = frontend.client_registration(context)
     assert registration_response.status == "400 Bad Request"
     error_response = ClientRegistrationErrorResponse().deserialize(registration_response.message, "json")
     assert error_response["error"] == "invalid_request"
     assert "response_type" in error_response["error_description"]
Пример #12
0
def test_registration_request():
    req = RegistrationRequest(type="client_associate", default_max_age=10,
                              require_auth_time=True, default_acr="foo")
    js = req.to_json()
    print js
    assert js == '{"require_auth_time": true, "default_acr": "foo", "type": "client_associate", "default_max_age": 10}'
    ue = req.to_urlencoded()
    print ue
    assert ue == 'default_acr=foo&type=client_associate&default_max_age=10&require_auth_time=True'
Пример #13
0
    def test_verify_redirect_uri_correct_without_query(self, uri):
        rr = RegistrationRequest(operation="register", redirect_uris=["http://example.org/cb"], response_types=["code"])
        registration_req = rr.to_json()
        resp = self.provider.registration_endpoint(request=registration_req)
        regresp = RegistrationResponse().from_json(resp.message)
        cid = regresp["client_id"]

        areq = AuthorizationRequest(redirect_uri=uri, client_id=cid, response_type="code", scope="openid")

        self.provider._verify_redirect_uri(areq)
Пример #14
0
def test_registration_request():
    req = RegistrationRequest(operation="register", default_max_age=10,
                              require_auth_time=True, default_acr="foo",
                              application_type="web",
                              redirect_uris=["https://example.com/authz_cb"])
    js = req.to_json()
    print js
    assert js == '{"redirect_uris": ["https://example.com/authz_cb"], "application_type": "web", "default_acr": "foo", "require_auth_time": true, "operation": "register", "default_max_age": 10}'
    ue = req.to_urlencoded()
    print ue
    assert ue == 'redirect_uris=https%3A%2F%2Fexample.com%2Fauthz_cb&application_type=web&default_acr=foo&require_auth_time=True&operation=register&default_max_age=10'
Пример #15
0
 def test_register_client_with_wrong_response_type(self, context, frontend):
     redirect_uri = "https://client.example.com"
     registration_request = RegistrationRequest(
         redirect_uris=[redirect_uri], response_types=["id_token token"])
     context.request = registration_request.to_dict()
     registration_response = frontend.client_registration(context)
     assert registration_response.status == "400 Bad Request"
     error_response = ClientRegistrationErrorResponse().deserialize(
         registration_response.message, "json")
     assert error_response["error"] == "invalid_request"
     assert "response_type" in error_response["error_description"]
Пример #16
0
    def test_registration_endpoint_with_non_https_redirect_uri_implicit_flow(
            self):
        params = {"application_type": "web",
                  "redirect_uris": ["http://example.com/authz"],
                  "response_types": ["id_token", "token"]}
        req = RegistrationRequest(**params)
        resp = self.provider.registration_endpoint(request=req.to_json())

        assert resp.status == "400 Bad Request"
        error = json.loads(resp.message)
        assert error["error"] == "invalid_redirect_uri"
Пример #17
0
    def test_register_client(self, context, frontend):
        redirect_uri = "https://client.example.com"
        registration_request = RegistrationRequest(redirect_uris=[redirect_uri], response_types=["id_token"])
        context.request = registration_request.to_dict()
        registration_response = frontend.client_registration(context)
        assert registration_response.status == "201 Created"

        reg_resp = RegistrationResponse().deserialize(registration_response.message, "json")
        assert "client_id" in reg_resp
        assert reg_resp["redirect_uris"] == [redirect_uri]
        assert reg_resp["response_types"] == ["id_token"]
Пример #18
0
    def test_full_flow(self, context, frontend):
        redirect_uri = "https://client.example.com/redirect"
        response_type = "code id_token token"
        mock_callback = Mock()
        frontend.auth_req_callback_func = mock_callback
        # discovery
        http_response = frontend.provider_config(context)
        provider_config = ProviderConfigurationResponse().deserialize(http_response.message, "json")

        # client registration
        registration_request = RegistrationRequest(redirect_uris=[redirect_uri], response_types=[response_type])
        context.request = registration_request.to_dict()
        http_response = frontend.client_registration(context)
        registration_response = RegistrationResponse().deserialize(http_response.message, "json")

        # authentication request
        authn_req = AuthorizationRequest(
            redirect_uri=redirect_uri,
            client_id=registration_response["client_id"],
            response_type=response_type,
            scope="openid email",
            state="state",
            nonce="nonce",
        )
        context.request = dict(parse_qsl(authn_req.to_urlencoded()))
        frontend.handle_authn_request(context)
        assert mock_callback.call_count == 1

        # fake authentication response from backend
        internal_response = self.setup_for_authn_response(context, frontend, authn_req)
        http_response = frontend.handle_authn_response(context, internal_response)
        authn_resp = AuthorizationResponse().deserialize(urlparse(http_response.message).fragment, "urlencoded")
        assert "code" in authn_resp
        assert "access_token" in authn_resp
        assert "id_token" in authn_resp

        # token request
        context.request = AccessTokenRequest(redirect_uri=authn_req["redirect_uri"], code=authn_resp["code"]).to_dict()
        credentials = "{}:{}".format(registration_response["client_id"], registration_response["client_secret"])
        basic_auth = urlsafe_b64encode(credentials.encode("utf-8")).decode("utf-8")
        context.request_authorization = "Basic {}".format(basic_auth)

        http_response = frontend.token_endpoint(context)
        parsed = AccessTokenResponse().deserialize(http_response.message, "json")
        assert "access_token" in parsed
        assert "id_token" in parsed

        # userinfo request
        context.request = {}
        context.request_authorization = "Bearer {}".format(parsed["access_token"])
        http_response = frontend.userinfo_endpoint(context)
        parsed = OpenIDSchema().deserialize(http_response.message, "json")
        assert "email" in parsed
Пример #19
0
    def registration_endpoint(self, environ, start_response, **kwargs):
        logger.debug("@registration_endpoint")
        try:
            query = kwargs["query"]
        except KeyError:
            try:
                query = get_or_post(environ)
            except UnsupportedMethod:
                resp = BadRequest("Unsupported method")
                return resp(environ, start_response)

        request = RegistrationRequest().deserialize(query, "urlencoded")
        logger.info("registration_request:%s" % request.to_dict())

        _keystore = self.server.keystore
        if request["type"] == "client_associate":
            # create new id och secret
            client_id = rndstr(12)
            while client_id in self.cdb:
                client_id = rndstr(12)

            client_secret = secret(self.seed, client_id)
            self.cdb[client_id] = {
                "client_secret":client_secret
            }
            _cinfo = self.cdb[client_id]

            if "redirect_uris" in request:
                for uri in request["redirect_uris"]:
                    if urlparse.urlparse(uri).fragment:
                        err = ClientRegistrationErrorResponse(
                                    error="invalid_configuration_parameter",
                            error_description="redirect_uri contains fragment")
                        resp = Response(err.to_json(),
                                        content="application/json",
                                        status="400 Bad Request")
                        return resp(environ, start_response)

            for key,val in request.items():
                _cinfo[key] = val

            try:
                self.keystore.load_keys(request, client_id)
            except Exception, err:
                logger.error("Failed to load client keys: %s" % request.to_dict())
                err = ClientRegistrationErrorResponse(
                        error="invalid_configuration_parameter",
                        error_description="%s" % err)
                resp = Response(err.to_json(), content="application/json",
                                status="400 Bad Request")
                return resp(environ, start_response)

            response = RegistrationResponseCARS(client_id=client_id)
Пример #20
0
    def test_register_client(self, context, frontend):
        redirect_uri = "https://client.example.com"
        registration_request = RegistrationRequest(redirect_uris=[redirect_uri],
                                                   response_types=["id_token"])
        context.request = registration_request.to_dict()
        registration_response = frontend.client_registration(context)
        assert registration_response.status == "201 Created"

        reg_resp = RegistrationResponse().deserialize(registration_response.message, "json")
        assert "client_id" in reg_resp
        assert reg_resp["redirect_uris"] == [redirect_uri]
        assert reg_resp["response_types"] == ["id_token"]
def test_registration_with_non_https(provider):
    redirect_uris = ["http://example.org"]
    registration_params = {
        "application_type": "web",
        "response_types": ["id_token", "token"],
        "redirect_uris": redirect_uris}
    req = RegistrationRequest(**registration_params)
    resp = provider.registration_endpoint(req.to_urlencoded())

    resp = RegistrationResponse().from_json(resp.message)
    assert resp["client_id"] is not None
    assert resp["client_secret"] is not None
    assert resp["redirect_uris"] == redirect_uris
Пример #22
0
def test_registration_request():
    req = RegistrationRequest(operation="register", default_max_age=10,
                              require_auth_time=True, default_acr="foo",
                              application_type="web",
                              redirect_uris=["https://example.com/authz_cb"])
    js = req.to_json()
    js_obj = json.loads(js)
    expected_js_obj = {"redirect_uris": ["https://example.com/authz_cb"], "application_type": "web", "default_acr": "foo", "require_auth_time": True, "operation": "register", "default_max_age": 10}
    assert js_obj == expected_js_obj
    ue = req.to_urlencoded()
    ue_splits = ue.split('&')
    expected_ue_splits = 'redirect_uris=https%3A%2F%2Fexample.com%2Fauthz_cb&application_type=web&default_acr=foo&require_auth_time=True&operation=register&default_max_age=10'.split('&')
    assert _eq(ue_splits, expected_ue_splits)
Пример #23
0
def test_registration_request():
    req = RegistrationRequest(operation="register", default_max_age=10,
                              require_auth_time=True, default_acr="foo",
                              application_type="web",
                              redirect_uris=["https://example.com/authz_cb"])
    js = req.to_json()
    js_obj = json.loads(js)
    expected_js_obj = {"redirect_uris": ["https://example.com/authz_cb"], "application_type": "web", "default_acr": "foo", "require_auth_time": True, "operation": "register", "default_max_age": 10}
    assert js_obj == expected_js_obj
    ue = req.to_urlencoded()
    ue_splits = ue.split('&')
    expected_ue_splits = 'redirect_uris=https%3A%2F%2Fexample.com%2Fauthz_cb&application_type=web&default_acr=foo&require_auth_time=True&operation=register&default_max_age=10'.split('&')
    assert _eq(ue_splits, expected_ue_splits)
Пример #24
0
    def test_read_registration(self):
        rr = RegistrationRequest(
            operation="register", redirect_uris=["http://example.org/new"], response_types=["code"]
        )
        registration_req = rr.to_json()
        resp = self.provider.registration_endpoint(request=registration_req)
        regresp = RegistrationResponse().from_json(resp.message)

        authn = " ".join(["Bearer", regresp["registration_access_token"]])
        query = "=".join(["client_id", regresp["client_id"]])
        resp = self.provider.read_registration(authn, query)

        assert json.loads(resp.message) == regresp.to_dict()
Пример #25
0
def test_registration_request():
    req = RegistrationRequest(operation="register",
                              default_max_age=10,
                              require_auth_time=True,
                              default_acr="foo",
                              application_type="web",
                              redirect_uris=["https://example.com/authz_cb"])
    js = req.to_json()
    print js
    assert js == '{"redirect_uris": ["https://example.com/authz_cb"], "application_type": "web", "default_acr": "foo", "require_auth_time": true, "operation": "register", "default_max_age": 10}'
    ue = req.to_urlencoded()
    print ue
    assert ue == 'redirect_uris=https%3A%2F%2Fexample.com%2Fauthz_cb&application_type=web&default_acr=foo&require_auth_time=True&operation=register&default_max_age=10'
Пример #26
0
    def test_read_registration(self):
        rr = RegistrationRequest(operation="register",
                                 redirect_uris=["http://example.org/new"],
                                 response_types=["code"])
        registration_req = rr.to_json()
        resp = self.provider.registration_endpoint(request=registration_req)
        regresp = RegistrationResponse().from_json(resp.message)

        authn = ' '.join(['Bearer', regresp['registration_access_token']])
        query = '='.join(['client_id', regresp['client_id']])
        resp = self.provider.read_registration(authn, query)

        assert json.loads(resp.message) == regresp.to_dict()
Пример #27
0
    def test_registered_redirect_uri_faulty_with_query_component(self, uri):
        rr = RegistrationRequest(
            operation="register", redirect_uris=["http://example.org/cb?foo=bar"], response_types=["code"]
        )

        registration_req = rr.to_json()
        resp = self.provider.registration_endpoint(request=registration_req)
        regresp = RegistrationResponse().from_json(resp.message)
        cid = regresp["client_id"]

        areq = AuthorizationRequest(redirect_uri=uri, client_id=cid, scope="openid", response_type="code")

        with pytest.raises(RedirectURIError):
            self.provider._verify_redirect_uri(areq)
def test_registration_with_non_https(provider):
    redirect_uris = ["http://example.org"]
    registration_params = {
        "application_type": "web",
        "response_types": ["id_token", "token"],
        "redirect_uris": redirect_uris
    }
    req = RegistrationRequest(**registration_params)
    resp = provider.registration_endpoint(req.to_urlencoded())

    resp = RegistrationResponse().from_json(resp.message)
    assert resp["client_id"] is not None
    assert resp["client_secret"] is not None
    assert resp["redirect_uris"] == redirect_uris
Пример #29
0
    def registration_endpoint(self, request, authn=None, **kwargs):
        try:
            reg_req = RegistrationRequest().deserialize(request, "json")
        except ValueError:
            reg_req = RegistrationRequest().deserialize(request)

        self.events.store(EV_PROTOCOL_REQUEST, reg_req)
        try:
            response_type_cmp(kwargs['test_cnf']['response_type'],
                              reg_req['response_types'])
        except KeyError:
            pass

        try:
            provider.Provider.verify_redirect_uris(reg_req)
        except InvalidRedirectURIError as err:
            return error(
                error="invalid_configuration_parameter",
                descr="Invalid redirect_uri: {}".format(err))

        # Do initial verification that all endpoints from the client uses
        #  https
        for endp in ["jwks_uri", "initiate_login_uri"]:
            try:
                uris = reg_req[endp]
            except KeyError:
                continue

            if not isinstance(uris, list):
                uris = [uris]
            for uri in uris:
                if not uri.startswith("https://"):
                    return error(
                        error="invalid_configuration_parameter",
                        descr="Non-HTTPS endpoint in '{}'".format(endp))

        _response = provider.Provider.registration_endpoint(self, request,
                                                            authn, **kwargs)
        self.events.store(EV_HTTP_RESPONSE, _response)
        self.init_keys = []
        if "jwks_uri" in reg_req:
            if _response.status == "200 OK":
                # find the client id
                req_resp = RegistrationResponse().from_json(
                    _response.message)
                for kb in self.keyjar[req_resp["client_id"]]:
                    if kb.imp_jwks:
                        self.events.store("Client JWKS", kb.imp_jwks)

        return _response
Пример #30
0
 def test_registration_request(self):
     req = RegistrationRequest(operation="register", default_max_age=10,
                               require_auth_time=True, default_acr="foo",
                               application_type="web",
                               redirect_uris=[
                                   "https://example.com/authz_cb"])
     js = req.to_json()
     js_obj = json.loads(js)
     expected_js_obj = {"redirect_uris": ["https://example.com/authz_cb"],
                        "application_type": "web", "default_acr": "foo",
                        "require_auth_time": True, "operation": "register",
                        "default_max_age": 10}
     assert js_obj == expected_js_obj
     assert query_string_compare(req.to_urlencoded(),
                                 "redirect_uris=https%3A%2F%2Fexample.com%2Fauthz_cb&application_type=web&default_acr=foo&require_auth_time=True&operation=register&default_max_age=10")
Пример #31
0
    def test_verify_redirect_uri_correct_without_query(self, uri):
        rr = RegistrationRequest(operation="register",
                                 redirect_uris=["http://example.org/cb"],
                                 response_types=["code"])
        registration_req = rr.to_json()
        resp = self.provider.registration_endpoint(request=registration_req)
        regresp = RegistrationResponse().from_json(resp.message)
        cid = regresp["client_id"]

        areq = AuthorizationRequest(redirect_uri=uri,
                                    client_id=cid,
                                    response_type="code",
                                    scope="openid")

        self.provider._verify_redirect_uri(areq)
Пример #32
0
    def test_registered_redirect_uri_with_query_component(self):
        provider2 = Provider("FOOP", {}, {}, None, None, None, None, "")

        rr = RegistrationRequest(operation="register",
                                 redirect_uris=["http://example.org/cb?foo=bar"],
                                 response_types=["code"])

        registration_req = rr.to_json()
        resp = provider2.registration_endpoint(request=registration_req)

        regresp = RegistrationResponse().from_json(resp.message)

        print regresp.to_dict()

        faulty = [
            "http://example.org/cb",
            "http://example.org/cb/foo",
            "http://example.org/cb?got=you",
            "http://example.org/cb?foo=you"
            "http://example.org/cb?foo=bar&got=you",
            "http://example.org/cb?foo=you&foo=bar"
        ]
        correct = [
            "http://example.org/cb?foo=bar",
        ]

        cid = regresp["client_id"]

        for ruri in faulty:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid,
                                        scope="openid",
                                        response_type="code")

            print areq
            try:
                provider2._verify_redirect_uri(areq)
            except RedirectURIError:
                pass

        for ruri in correct:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid, scope="openid",
                                        response_type="code")

            resp = provider2._verify_redirect_uri(areq)
            print resp
            assert resp is None
Пример #33
0
    def test_registered_redirect_uri_with_query_component(self):
        provider2 = Provider("FOOP", {}, {}, None, None, None, None, "")

        rr = RegistrationRequest(
            operation="register",
            redirect_uris=["http://example.org/cb?foo=bar"],
            response_types=["code"])

        registration_req = rr.to_json()
        resp = provider2.registration_endpoint(request=registration_req)

        regresp = RegistrationResponse().from_json(resp.message)

        print regresp.to_dict()

        faulty = [
            "http://example.org/cb", "http://example.org/cb/foo",
            "http://example.org/cb?got=you", "http://example.org/cb?foo=you"
            "http://example.org/cb?foo=bar&got=you",
            "http://example.org/cb?foo=you&foo=bar"
        ]
        correct = [
            "http://example.org/cb?foo=bar",
        ]

        cid = regresp["client_id"]

        for ruri in faulty:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid,
                                        scope="openid",
                                        response_type="code")

            print areq
            try:
                provider2._verify_redirect_uri(areq)
            except RedirectURIError:
                pass

        for ruri in correct:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid,
                                        scope="openid",
                                        response_type="code")

            resp = provider2._verify_redirect_uri(areq)
            print resp
            assert resp is None
Пример #34
0
def _create_client(provider_metadata, client_metadata, verify_ssl=True):
    """
    Create a pyoidc client instance.
    :param provider_metadata: provider configuration information
    :type provider_metadata: Mapping[str, Union[str, Sequence[str]]]
    :param client_metadata: client metadata
    :type client_metadata: Mapping[str, Union[str, Sequence[str]]]
    :return: client instance to use for communicating with the configured provider
    :rtype: oic.oic.Client
    """
    client = oic.Client(
        client_authn_method=CLIENT_AUTHN_METHOD, verify_ssl=verify_ssl
    )

    # Provider configuration information
    if "authorization_endpoint" in provider_metadata:
        # no dynamic discovery necessary
        client.handle_provider_config(ProviderConfigurationResponse(**provider_metadata),
                                      provider_metadata["issuer"])
    else:
        # do dynamic discovery
        client.provider_config(provider_metadata["issuer"])

    # Client information
    if "client_id" in client_metadata:
        # static client info provided
        client.store_registration_info(RegistrationRequest(**client_metadata))
    else:
        # do dynamic registration
        client.register(client.provider_info['registration_endpoint'],
                        **client_metadata)

    client.subject_type = (client.registration_response.get("subject_type") or
                           client.provider_info["subject_types_supported"][0])
    return client
Пример #35
0
    def handle_client_registration_request(self, request, http_headers=None):
        # type: (Optional[str], Optional[Mapping[str, str]]) -> oic.oic.message.RegistrationResponse
        """
        Handles a client registration request.
        :param request: JSON request from POST body
        :param http_headers: http headers
        """
        registration_req = RegistrationRequest().deserialize(request, 'json')

        for validator in self.registration_request_validators:
            validator(registration_req)
        logger.debug('parsed authentication_request: %s', registration_req)

        client_id, client_secret = self._issue_new_client()
        credentials = {
            'client_id': client_id,
            'client_id_issued_at': int(time.time()),
            'client_secret': client_secret,
            'client_secret_expires_at': 0  # never expires
        }

        response_params = self.match_client_preferences_with_provider_capabilities(
            registration_req)
        response_params.update(credentials)
        self.clients[client_id] = copy.deepcopy(response_params)

        registration_resp = RegistrationResponse(**response_params)
        logger.debug('registration_resp=%s from registration_req=%s',
                     registration_resp, registration_req)
        return registration_resp
Пример #36
0
    def test_registration_request(self):
        req = RegistrationRequest(operation="register", default_max_age=10,
                                  require_auth_time=True, default_acr="foo",
                                  application_type="web",
                                  redirect_uris=[
                                      "https://example.com/authz_cb"])
        js = req.to_json()
        js_obj = json.loads(js)
        expected_js_obj = {"redirect_uris": ["https://example.com/authz_cb"],
                           "application_type": "web", "default_acr": "foo",
                           "require_auth_time": True, "operation": "register",
                           "default_max_age": 10, "response_types": ["code"]}
        assert js_obj == expected_js_obj

        flattened_list_dict = {k: v[0] if isinstance(v, list) else v for k, v in expected_js_obj.items()}
        assert query_string_compare(req.to_urlencoded(), urlencode(flattened_list_dict))
Пример #37
0
    def registration_endpoint(self, request, authn=None, **kwargs):
        logger.debug("@registration_endpoint: <<{}>>".format(
            sanitize(request)))

        if isinstance(request, dict):
            request = ClientMetadataStatement(**request)
        else:
            try:
                request = ClientMetadataStatement().deserialize(
                    request, "json")
            except ValueError:
                request = ClientMetadataStatement().deserialize(request)

        logger.info("registration_request:{}".format(
            sanitize(request.to_dict())))

        request_args = self.get_metadata_statement(request)
        request = RegistrationRequest(**request_args)

        result = self.client_registration_setup(request)
        if isinstance(result, Response):
            return result

        return Created(result.to_json(),
                       content="application/json",
                       headers=[("Cache-Control", "no-store")])
Пример #38
0
 def test_verify_redirect_uris_with_https_code_flow(self):
     params = {"application_type": "web",
               "redirect_uris": ["http://example.com/authz"],
               "response_types": ["code"]}
     request = RegistrationRequest(**params)
     verified_uris = self.provider._verify_redirect_uris(request)
     assert verified_uris == [("http://example.com/authz", None)]
Пример #39
0
    def test_registered_redirect_uri_without_query_component(self):
        provider = Provider("FOO", {}, {}, None, None, None, None, "")
        rr = RegistrationRequest(operation="register",
                                 redirect_uris=["http://example.org/cb"],
                                 response_types=["code"])

        registration_req = rr.to_json()

        provider.registration_endpoint(request=registration_req)

        correct = [
            "http://example.org/cb",
            "http://example.org/cb/foo",
        ]
        faulty = [
            "http://example.org/foo",
            "http://example.com/cb",
            "http://example.org/cb?got=you",
            "http://example.org/cb/foo?got=you"
        ]

        cid = self._client_id(provider.cdb)

        for ruri in faulty:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid,
                                        response_type="code",
                                        scope="openid")

            print areq
            try:
                provider._verify_redirect_uri(areq)
                assert False
            except RedirectURIError:
                pass

        for ruri in correct:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid,
                                        response_type="code", scope="openid")

            print areq
            try:
                provider._verify_redirect_uri(areq)
            except RedirectURIError, err:
                print err
                assert False
Пример #40
0
    def test_registered_redirect_uri_without_query_component(self):
        provider = Provider("FOO", {}, {}, None, None, None, None, "")
        rr = RegistrationRequest(operation="register",
                                 redirect_uris=["http://example.org/cb"],
                                 response_types=["code"])

        registration_req = rr.to_json()

        provider.registration_endpoint(request=registration_req)

        correct = [
            "http://example.org/cb",
            "http://example.org/cb/foo",
        ]
        faulty = [
            "http://example.org/foo", "http://example.com/cb",
            "http://example.org/cb?got=you",
            "http://example.org/cb/foo?got=you"
        ]

        cid = self._client_id(provider.cdb)

        for ruri in faulty:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid,
                                        response_type="code",
                                        scope="openid")

            print areq
            try:
                provider._verify_redirect_uri(areq)
                assert False
            except RedirectURIError:
                pass

        for ruri in correct:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid,
                                        response_type="code",
                                        scope="openid")

            print areq
            try:
                provider._verify_redirect_uri(areq)
            except RedirectURIError, err:
                print err
                assert False
Пример #41
0
    def test_register_client(self):
        redirect_uri = "https://client.example.com"
        registration_request = RegistrationRequest(redirect_uris=[redirect_uri],
                                                   response_types=["id_token"])
        context = Context()
        context.request = registration_request.to_dict()
        registration_response = self.instance._register_client(context)
        assert registration_response.status == "201 Created"

        reg_resp = RegistrationResponse().deserialize(registration_response.message, "json")
        assert "client_id" in reg_resp
        assert reg_resp["client_id"] in self.instance.provider.cdb
        # no need to issue client secret since to token endpoint is published
        assert "client_secret" not in reg_resp
        assert reg_resp["redirect_uris"] == [redirect_uri]
        assert reg_resp["response_types"] == ["id_token"]
        assert reg_resp["id_token_signed_response_alg"] == "RS256"
Пример #42
0
    def test_verify_redirect_uri_native_https(self):
        areq = RegistrationRequest(redirect_uris=["https://example.org/cb"],
                                   application_type='native')

        try:
            self.provider.verify_redirect_uris(areq)
        except InvalidRedirectURIError:
            assert True
    def test_parse_registration_request(self):
        regreq = RegistrationRequest(contacts=["*****@*****.**"],
                                     redirect_uris=[
                                         "http://example.org/jqauthz"],
                                     application_name="pacubar",
                                     client_id=CLIENT_ID,
                                     operation="register",
                                     application_type="web")

        request = self.srv.parse_registration_request(
                data=regreq.to_urlencoded())
        assert isinstance(request, RegistrationRequest)
        assert _eq(request.keys(), ['redirect_uris', 'contacts', 'client_id',
                                    'application_name', 'operation',
                                    'application_type', 'response_types'])
        assert request["application_name"] == "pacubar"
        assert request["operation"] == "register"
Пример #44
0
    def register(self, url, operation="register", application_type="web",
                 **kwargs):
        req = RegistrationRequest(operation=operation,
                                  application_type=application_type)

        if operation == "update":
            req["client_id"] = self.client_id
            req["client_secret"] = self.client_secret

        for prop in req.parameters():
            if prop in ["operation", "client_id", "client_secret"]:
                continue

            try:
                req[prop] = kwargs[prop]
            except KeyError:
                try:
                    req[prop] = self.behaviour[prop]
                except KeyError:
                    pass

        if "redirect_uris" not in req:
            try:
                req["redirect_uris"] = self.redirect_uris
            except AttributeError:
                raise MissingRequiredAttribute("redirect_uris")

        headers = {"content-type": "application/x-www-form-urlencoded"}

        if operation == "client_update":
            headers["Authorization"] = "Bearer %s" % self.registration_access_token

        rsp = self.http_request(url, "POST", data=req.to_urlencoded(),
                                headers=headers)

        if rsp.status_code == 200:
            resp = RegistrationResponse().deserialize(rsp.text, "json")
            self.client_secret = resp["client_secret"]
            self.client_id = resp["client_id"]
            self.registration_expires = resp["expires_at"]
            self.registration_access_token = resp["registration_access_token"]
        else:
            err = ErrorResponse().deserialize(rsp.text, "json")
            raise Exception("Registration failed: %s" % err.get_json())

        return resp
Пример #45
0
    def test_registration_endpoint(self):
        req = RegistrationRequest()

        req["application_type"] = "web"
        req["client_name"] = "My super service"
        req["redirect_uris"] = ["http://example.com/authz"]
        req["contacts"] = ["*****@*****.**"]
        req["response_types"] = ["code"]

        resp = self.provider.registration_endpoint(request=req.to_json())

        regresp = RegistrationResponse().deserialize(resp.message, "json")
        assert _eq(regresp.keys(), [
            'redirect_uris', 'contacts', 'application_type', 'client_name',
            'registration_client_uri', 'client_secret_expires_at',
            'registration_access_token', 'client_id', 'client_secret',
            'client_id_issued_at', 'response_types'
        ])
Пример #46
0
    def test_registered_redirect_uri_faulty_with_query_component(self, uri):
        rr = RegistrationRequest(operation="register",
                                 redirect_uris=[
                                     "http://example.org/cb?foo=bar"],
                                 response_types=["code"])

        registration_req = rr.to_json()
        resp = self.provider.registration_endpoint(request=registration_req)
        regresp = RegistrationResponse().from_json(resp.message)
        cid = regresp["client_id"]

        areq = AuthorizationRequest(redirect_uri=uri,
                                    client_id=cid,
                                    scope="openid",
                                    response_type="code")

        with pytest.raises(RedirectURIError):
            self.provider._verify_redirect_uri(areq)
Пример #47
0
    def test_verify_sector_identifier_nonreachable(self):
        rr = RegistrationRequest(operation="register", sector_identifier_uri="https://example.com")
        with responses.RequestsMock() as rsps, LogCapture(level=logging.DEBUG) as logcap:
            rsps.add(rsps.GET, "https://example.com", status=404)
            message = "Couldn't open sector_identifier_uri"
            with pytest.raises(InvalidSectorIdentifier, message=message):
                self.provider._verify_sector_identifier(rr)

        assert len(logcap.records) == 0
Пример #48
0
def test_registration_endpoint():
    server = provider_init

    req = RegistrationRequest(operation="register")

    req["application_type"] = "web"
    req["client_name"] = "My super service"
    req["redirect_uris"] = ["http://example.com/authz"]
    req["contacts"] = ["*****@*****.**"]

    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = req.to_urlencoded()

    resp = server.registration_endpoint(environ, start_response)

    print resp
    regresp = RegistrationResponse().deserialize(resp[0], "json")
    print regresp.keys()
    assert _eq(regresp.keys(), ['redirect_uris', 'application_type',
                                'expires_at', 'registration_access_token',
                                'client_id', 'client_secret', 'client_name',
                                "contacts"])

    # --- UPDATE ----

    req = RegistrationRequest(operation="client_update")
    req["application_type"] = "web"
    req["client_name"] = "My super duper service"
    req["redirect_uris"] = ["http://example.com/authz"]
    req["contacts"] = ["*****@*****.**"]

    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = req.to_urlencoded()
    environ["HTTP_AUTHORIZATION"] = "Bearer %s" % regresp["registration_access_token"]

    resp = server.registration_endpoint(environ, start_response)

    print resp
    update = RegistrationResponse().deserialize(resp[0], "json")
    print update.keys()
    assert _eq(update.keys(), ['redirect_uris', 'application_type',
                               'expires_at', 'registration_access_token',
                               'client_id', 'client_secret', 'client_name',
                               'contacts'])
Пример #49
0
def test_registered_redirect_uri_with_query_component():
    provider2 = Provider("FOOP", {}, {}, None, None)
    environ = {}

    rr = RegistrationRequest(operation="register",
                             redirect_uris=["http://example.org/cb?foo=bar"])

    registration_req = rr.to_urlencoded()
    resp = provider2.registration_endpoint(environ, start_response,
                                    query=registration_req)

    regresp = RegistrationResponse().from_json(resp[0])

    print regresp.to_dict()

    faulty = [
        "http://example.org/cb",
        "http://example.org/cb/foo",
        "http://example.org/cb?got=you",
        "http://example.org/cb?foo=you"
    ]
    correct = [
        "http://example.org/cb?foo=bar",
        "http://example.org/cb?foo=bar&got=you",
        "http://example.org/cb?foo=bar&foo=you"
    ]

    for ruri in faulty:
        areq = AuthorizationRequest(redirect_uri=ruri,
                                    client_id=regresp["client_id"],
                                    scope="openid",
                                    response_type="code")

        print areq
        assert provider2._verify_redirect_uri(areq) != None


    for ruri in correct:
        areq = AuthorizationRequest(redirect_uri= ruri,
                                    client_id=regresp["client_id"])

        resp = provider2._verify_redirect_uri(areq)
        print resp
        assert resp == None
Пример #50
0
    def test_verify_redirect_uris_with_non_https_redirect_uri_implicit_flow(self):
        params = {"application_type": "web",
                  "redirect_uris": ["http://example.com/authz"],
                  "response_types": ["id_token", "token"]}
        request = RegistrationRequest(**params)

        with pytest.raises(InvalidRedirectURIError) as exc_info:
            self.provider._verify_redirect_uris(request)

        assert str(exc_info.value) == "None https redirect_uri not allowed"
Пример #51
0
    def register(self, server, type="client_associate", **kwargs):
        req = RegistrationRequest(type=type)

        if type == "client_update" or type == "rotate_secret":
            req["client_id"] = self.client_id
            req["client_secret"] = self.client_secret

        for prop in req.parameters():
            if prop in ["type", "client_id", "client_secret"]:
                continue

            try:
                val = getattr(self, prop)
                if val:
                    req[prop] = val
            except Exception:
                val = None

            if not val:
                try:
                    req[prop] = kwargs[prop]
                except KeyError:
                    pass

        headers = {"content-type": "application/x-www-form-urlencoded"}
        rsp = self.http_request(server, "POST", data=req.to_urlencoded(),
                                headers=headers)

        if rsp.status_code == 200:
            if type == "client_associate" or type == "rotate_secret":
                rr = RegistrationResponseCARS()
            else:
                rr = RegistrationResponseCU()

            resp = rr.deserialize(rsp.text, "json")
            self.client_secret = resp["client_secret"]
            self.client_id = resp["client_id"]
            self.registration_expires = resp["expires_at"]
        else:
            err = ErrorResponse().deserialize(rsp.text, "json")
            raise Exception("Registration failed: %s" % err.get_json())

        return resp
Пример #52
0
def init_oidc_client(app):
    oidc_client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
    oidc_client.store_registration_info(RegistrationRequest(**app.config['CLIENT_REGISTRATION_INFO']))
    provider = app.config['PROVIDER_CONFIGURATION_INFO']['issuer']
    try:
        oidc_client.provider_config(provider)
    except ConnectionError as e:
        app.logger.critical('No connection to provider {!s}. Can not start without provider configuration.'.format(
            provider))
        raise e
    return oidc_client
Пример #53
0
    def test_verify_sector_identifier_error(self):
        rr = RegistrationRequest(operation="register", sector_identifier_uri="https://example.com")
        error = ConnectionError('broken connection')
        with responses.RequestsMock() as rsps, LogCapture(level=logging.DEBUG) as logcap:
            rsps.add(rsps.GET, "https://example.com", body=error)
            with pytest.raises(InvalidSectorIdentifier, message="Couldn't open sector_identifier_uri"):
                self.provider._verify_sector_identifier(rr)

        assert len(logcap.records) == 2
        # First log record is from server...
        assert logcap.records[1].msg == error
Пример #54
0
    def l_registration_endpoint(self, request, authn=None, **kwargs):
        _log_debug = logger.debug
        _log_info = logger.info

        _log_debug("@registration_endpoint")

        request = RegistrationRequest().deserialize(request, "json")

        _log_info("registration_request:%s" % request.to_dict())
        resp_keys = request.keys()

        try:
            request.verify()
        except MessageException, err:
            if "type" not in request:
                return self._error(error="invalid_type", 
                                   descr="%s" % err)
            else:
                return self._error(error="invalid_configuration_parameter",
                                   descr="%s" % err)
Пример #55
0
    def test_verify_sector_identifier_malformed(self):
        rr = RegistrationRequest(operation="register", sector_identifier_uri="https://example.com")
        body = "This is not the JSON you are looking for"
        with responses.RequestsMock() as rsps, LogCapture(level=logging.DEBUG) as logcap:
            rsps.add(rsps.GET, "https://example.com", body=body)
            with pytest.raises(InvalidSectorIdentifier, message="Error deserializing sector_identifier_uri content"):
                self.provider._verify_sector_identifier(rr)

        assert len(logcap.records) == 1
        assert logcap.records[0].msg == "sector_identifier_uri => %s"
        assert logcap.records[0].args == (body,)
def test_dynamic_client(provider_info, browser):
    redirect_uri = "http://localhost"
    # Dynamic registration
    reg_req = RegistrationRequest(**{"redirect_uris": [redirect_uri], "response_types": ["id_token"]})
    resp = requests.post(reg_req.request(provider_info["registration_endpoint"]))
    reg_resp = RegistrationResponse().from_json(resp.text)

    # Authentication
    auth_req = AuthorizationRequest(
        **{"client_id": reg_resp["client_id"], "scope": "openid", "response_type": "id_token",
           "redirect_uri": redirect_uri, "state": "state0", "nonce": "nonce0"})
    browser.get(auth_req.request(provider_info["authorization_endpoint"]))
    fill_login_details(browser)

    # Authentication response
    urlencoded_resp = urlparse(browser.current_url).fragment
    auth_resp = AuthorizationResponse().from_urlencoded(urlencoded_resp)
    idt = IdToken().from_jwt(auth_resp["id_token"], verify=False)
    assert browser.current_url.startswith(redirect_uri)
    assert auth_resp["state"] == "state0"
    assert idt["nonce"] == "nonce0"
Пример #57
0
    def test_registration_endpoint(self):
        req = RegistrationRequest()

        req["application_type"] = "web"
        req["client_name"] = "My super service"
        req["redirect_uris"] = ["http://example.com/authz"]
        req["contacts"] = ["*****@*****.**"]
        req["response_types"] = ["code"]

        print req.to_dict()

        resp = self.server.registration_endpoint(request=req.to_json())

        print resp.message
        regresp = RegistrationResponse().deserialize(resp.message, "json")
        print regresp.keys()
        assert _eq(regresp.keys(), ['redirect_uris', 'contacts', 'application_type',
                                    'client_name', 'registration_client_uri',
                                    'client_secret_expires_at',
                                    'registration_access_token',
                                    'client_id', 'client_secret',
                                    'client_id_issued_at', 'response_types'])
Пример #58
0
    def registration_endpoint(self, request, authn=None, **kwargs):
        """

        :param request:
        :param authn:
        :param kwargs:
        :return:
        """
        logger.debug("@registration_endpoint: <<{}>>".format(sanitize(request)))

        if isinstance(request, dict):
            request = ClientMetadataStatement(**request)
        else:
            try:
                request = ClientMetadataStatement().deserialize(request, "json")
            except ValueError:
                request = ClientMetadataStatement().deserialize(request)

        try:
            request.verify()
        except Exception as err:
            return error('Invalid request')

        logger.info(
            "registration_request:{}".format(sanitize(request.to_dict())))

        ms_list = self.federation_entity.get_metadata_statement(request,
                                                                'registration')

        if ms_list:
            ms = self.federation_entity.pick_by_priority(ms_list)
            self.federation = ms.fo
        else:  # Nothing I can use
            return error(error='invalid_request',
                         descr='No signed metadata statement I could use')

        request = RegistrationRequest(**ms.le)
        result = self.client_registration_setup(request)

        if isinstance(result, Response):
            return result

        # TODO This is where the OP should sign the response
        if ms.fo:
            _fo = ms.fo
            sms = self.signer.create_signed_metadata_statement(
                result, 'response', [_fo], single=True)
            self.federation_entity.extend_with_ms(result, {_fo: sms})

        return Created(result.to_json(), content="application/json",
                       headers=[("Cache-Control", "no-store")])