Пример #1
0
def test_link3():
    link = Link(rel="http://webfinger.net/rel/profile-page",
                href="http://www.example.com/~bob/")

    assert set(link.keys()) == {'rel', 'href'}
    assert link['rel'] == "http://webfinger.net/rel/profile-page"
    assert link['href'] == "http://www.example.com/~bob/"
Пример #2
0
def test_link1():
    link = Link(rel="http://webfinger.net/rel/avatar",
                type="image/jpeg",
                href="http://www.example.com/~bob/bob.jpg")

    assert set(link.keys()) == {'rel', 'type', 'href'}
    assert link['rel'] == "http://webfinger.net/rel/avatar"
    assert link['type'] == "image/jpeg"
    assert link['href'] == "http://www.example.com/~bob/bob.jpg"
Пример #3
0
def test_jrd():
    jrd = JRD(subject="acct:[email protected]",
              aliases=["http://www.example.com/~bob/"],
              properties={"http://example.com/ns/role/": "employee"},
              links=[
                  Link(rel="http://webfinger.net/rel/avatar",
                       type="image/jpeg",
                       href="http://www.example.com/~bob/bob.jpg"),
                  Link(rel="http://webfinger.net/rel/profile-page",
                       href="http://www.example.com/~bob/")
              ])

    assert set(jrd.keys()) == {'subject', 'aliases', 'properties', 'links'}
Пример #4
0
def test_link2():
    link = Link(rel="blog",
                type="text/html",
                href="http://blogs.example.com/bob/",
                titles={
                    "en-us": "The Magical World of Bob",
                    "fr": "Le monde magique de Bob"
                })

    assert set(link.keys()) == {'rel', 'type', 'href', 'titles'}
    assert link['rel'] == "blog"
    assert link['type'] == "text/html"
    assert link['href'] == "http://blogs.example.com/bob/"
    assert set(link['titles'].keys()) == {'en-us', 'fr'}
Пример #5
0
    def test_dynamic_setup(self):
        user_id = 'acct:[email protected]'
        _link = Link(rel="http://openid.net/specs/connect/1.0/issuer",
                     href="https://server.example.com")
        webfinger_response = JRD(subject=user_id, links=[_link])
        self.mock_op.register_get_response(
            '/.well-known/webfinger', webfinger_response.to_json(), 200,
            {'content-type': "application/json"})

        resp = {
            "authorization_endpoint":
            "https://server.example.com/connect/authorize",
            "issuer":
            "https://server.example.com",
            "subject_types_supported": ['public'],
            "token_endpoint":
            "https://server.example.com/connect/token",
            "token_endpoint_auth_methods_supported":
            ["client_secret_basic", "private_key_jwt"],
            "userinfo_endpoint":
            "https://server.example.com/connect/user",
            "check_id_endpoint":
            "https://server.example.com/connect/check_id",
            "refresh_session_endpoint":
            "https://server.example.com/connect/refresh_session",
            "end_session_endpoint":
            "https://server.example.com/connect/end_session",
            "jwks_uri":
            "https://server.example.com/jwk.json",
            "registration_endpoint":
            "https://server.example.com/connect/register",
            "scopes_supported":
            ["openid", "profile", "email", "address", "phone"],
            "response_types_supported":
            ["code", "code id_token", "token id_token"],
            "acrs_supported":
            ["1", "2", "http://id.incommon.org/assurance/bronze"],
            "user_id_types_supported": ["public", "pairwise"],
            "userinfo_algs_supported":
            ["HS256", "RS256", "A128CBC", "A128KW", "RSA1_5"],
            "id_token_signing_alg_values_supported":
            ["HS256", "RS256", "A128CBC", "A128KW", "RSA1_5"],
            "request_object_algs_supported":
            ["HS256", "RS256", "A128CBC", "A128KW", "RSA1_5"]
        }

        pcr = ProviderConfigurationResponse(**resp)
        self.mock_op.register_get_response(
            '/.well-known/openid-configuration', pcr.to_json(), 200,
            {'content-type': "application/json"})

        self.mock_op.register_post_response(
            '/connect/register', registration_callback, 200,
            {'content-type': "application/json"})

        auth_query = self.rph.begin(user_id=user_id)
        assert auth_query
Пример #6
0
    def do_response(self, response_args=None, request=None, **kwargs):
        """
        **Placeholder for the time being**

        :param response_args:
        :param request:
        :param kwargs: request arguments
        :return: Response information
        """

        links = [Link(href=h, rel=OIC_ISSUER) for h in kwargs["hrefs"]]

        _response = JRD(subject=kwargs["subject"], links=links)

        info = {
            "response": _response.to_json(),
            "http_headers": [("Content-type", "application/json")],
        }

        return info
Пример #7
0
    def do_response(self, response_args=None, request=None, **kwargs):
        """
        **Placeholder for the time being**

        :param endpoint_context:
            :py:class:`oidcendpoint.endpoint_context.EndpointContext` instance
        :param kwargs: request arguments
        :return: Response information
        """

        links = [Link(href=h, rel=OIC_ISSUER) for h in kwargs['hrefs']]

        _response = JRD(subject=kwargs['subject'], links=links)

        info = {
            'response': _response.to_json(),
            'http_headers': [('Content-type', 'application/json')]
        }

        return info
def test_conversation():
    service_context = ServiceContext(
        RP_KEYJAR, {
            "client_preferences": {
                "application_type": "web",
                "application_name": "rphandler",
                "contacts": ["*****@*****.**"],
                "response_types": ["code"],
                "scope": ["openid", "profile", "email", "address", "phone"],
                "token_endpoint_auth_method": "client_secret_basic",
            },
            "redirect_uris": ["{}/authz_cb".format(RP_BASEURL)],
            "jwks_uri": "{}/static/jwks.json".format(RP_BASEURL)
        })

    service_spec = DEFAULT_SERVICES.copy()
    service_spec['WebFinger'] = {'class': WebFinger}

    service = init_services(service_spec,
                            state_db=InMemoryStateDataBase(),
                            service_context=service_context)

    assert set(service.keys()) == {
        'accesstoken', 'authorization', 'webfinger', 'registration',
        'refresh_token', 'userinfo', 'provider_info'
    }

    service_context.service = service

    # ======================== WebFinger ========================

    info = service['webfinger'].get_request_parameters(
        request_args={'resource': '*****@*****.**'})

    assert info[
               'url'] == 'https://example.org/.well-known/webfinger?rel=http' \
                         '%3A%2F' \
                         '%2Fopenid.net%2Fspecs%2Fconnect%2F1.0%2Fissuer' \
                         '&resource' \
                         '=acct%3Afoobar%40example.org'

    webfinger_response = json.dumps({
        "subject":
        "acct:[email protected]",
        "links": [{
            "rel": "http://openid.net/specs/connect/1.0/issuer",
            "href": "https://example.org/op"
        }],
        "expires":
        "2018-02-04T11:08:41Z"
    })

    response = service['webfinger'].parse_response(webfinger_response)

    assert isinstance(response, JRD)
    assert set(response.keys()) == {'subject', 'links', 'expires'}
    assert response['links'] == [
        Link(rel='http://openid.net/specs/connect/1.0/issuer',
             href='https://example.org/op')
    ]

    service['webfinger'].update_service_context(resp=response)
    assert service_context.issuer == OP_BASEURL

    # =================== Provider info discovery ====================

    info = service['provider_info'].get_request_parameters()

    assert info[
               'url'] == 'https://example.org/op/.well-known/openid' \
                         '-configuration'

    provider_info_response = json.dumps({
        "version":
        "3.0",
        "token_endpoint_auth_methods_supported": [
            "client_secret_post", "client_secret_basic", "client_secret_jwt",
            "private_key_jwt"
        ],
        "claims_parameter_supported":
        True,
        "request_parameter_supported":
        True,
        "request_uri_parameter_supported":
        True,
        "require_request_uri_registration":
        True,
        "grant_types_supported": [
            "authorization_code", "implicit",
            "urn:ietf:params:oauth:grant-type:jwt-bearer", "refresh_token"
        ],
        "response_types_supported": [
            "code", "id_token", "id_token token", "code id_token",
            "code token", "code id_token token"
        ],
        "response_modes_supported": ["query", "fragment", "form_post"],
        "subject_types_supported": ["public", "pairwise"],
        "claim_types_supported": ["normal", "aggregated", "distributed"],
        "claims_supported": [
            "birthdate", "address", "nickname", "picture", "website", "email",
            "gender", "sub", "phone_number_verified", "given_name", "profile",
            "phone_number", "updated_at", "middle_name", "name", "locale",
            "email_verified", "preferred_username", "zoneinfo", "family_name"
        ],
        "scopes_supported": [
            "openid", "profile", "email", "address", "phone", "offline_access",
            "openid"
        ],
        "userinfo_signing_alg_values_supported": [
            "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "HS256",
            "HS384", "HS512", "PS256", "PS384", "PS512", "none"
        ],
        "id_token_signing_alg_values_supported": [
            "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "HS256",
            "HS384", "HS512", "PS256", "PS384", "PS512", "none"
        ],
        "request_object_signing_alg_values_supported": [
            "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "HS256",
            "HS384", "HS512", "PS256", "PS384", "PS512", "none"
        ],
        "token_endpoint_auth_signing_alg_values_supported": [
            "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "HS256",
            "HS384", "HS512", "PS256", "PS384", "PS512"
        ],
        "userinfo_encryption_alg_values_supported": [
            "RSA1_5", "RSA-OAEP", "RSA-OAEP-256", "A128KW", "A192KW", "A256KW",
            "ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"
        ],
        "id_token_encryption_alg_values_supported": [
            "RSA1_5", "RSA-OAEP", "RSA-OAEP-256", "A128KW", "A192KW", "A256KW",
            "ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"
        ],
        "request_object_encryption_alg_values_supported": [
            "RSA1_5", "RSA-OAEP", "RSA-OAEP-256", "A128KW", "A192KW", "A256KW",
            "ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"
        ],
        "userinfo_encryption_enc_values_supported": [
            "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM",
            "A192GCM", "A256GCM"
        ],
        "id_token_encryption_enc_values_supported": [
            "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM",
            "A192GCM", "A256GCM"
        ],
        "request_object_encryption_enc_values_supported": [
            "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM",
            "A192GCM", "A256GCM"
        ],
        "acr_values_supported": ["PASSWORD"],
        "issuer":
        OP_BASEURL,
        "jwks_uri":
        "{}/static/jwks_tE2iLbOAqXhe8bqh.json".format(OP_BASEURL),
        "authorization_endpoint":
        "{}/authorization".format(OP_BASEURL),
        "token_endpoint":
        "{}/token".format(OP_BASEURL),
        "userinfo_endpoint":
        "{}/userinfo".format(OP_BASEURL),
        "registration_endpoint":
        "{}/registration".format(OP_BASEURL),
        "end_session_endpoint":
        "{}/end_session".format(OP_BASEURL)
    })

    resp = service['provider_info'].parse_response(provider_info_response)

    assert isinstance(resp, ProviderConfigurationResponse)
    service['provider_info'].update_service_context(resp)

    assert service_context.provider_info['issuer'] == OP_BASEURL
    assert service_context.provider_info[
               'authorization_endpoint'] == \
           'https://example.org/op/authorization'
    assert service_context.provider_info[
        'registration_endpoint'] == 'https://example.org/op/registration'

    # =================== Client registration ====================

    info = service['registration'].get_request_parameters()

    assert info['url'] == 'https://example.org/op/registration'
    _body = json.loads(info['body'])
    assert _body == {
        "application_type": "web",
        "response_types": ["code"],
        "contacts": ["*****@*****.**"],
        "jwks_uri": "https://example.com/rp/static/jwks.json",
        "redirect_uris": ["{}/authz_cb".format(RP_BASEURL)],
        'token_endpoint_auth_method': 'client_secret_basic',
        "grant_types": ["authorization_code"]
    }
    assert info['headers'] == {'Content-Type': 'application/json'}

    now = int(time.time())

    op_client_registration_response = json.dumps({
        "client_id":
        "zls2qhN1jO6A",
        "client_secret":
        "c8434f28cf9375d9a7",
        "registration_access_token":
        "NdGrGR7LCuzNtixvBFnDphGXv7wRcONn",
        "registration_client_uri":
        "{}/registration?client_id=zls2qhN1jO6A".format(RP_BASEURL),
        "client_secret_expires_at":
        now + 3600,
        "client_id_issued_at":
        now,
        "application_type":
        "web",
        "response_types": ["code"],
        "contacts": ["*****@*****.**"],
        "redirect_uris": ["{}/authz_cb".format(RP_BASEURL)],
        "token_endpoint_auth_method":
        "client_secret_basic",
        "grant_types": ["authorization_code"]
    })

    response = service['registration'].parse_response(
        op_client_registration_response)

    service['registration'].update_service_context(response)
    assert service_context.client_id == 'zls2qhN1jO6A'
    assert service_context.client_secret == 'c8434f28cf9375d9a7'
    assert isinstance(service_context.registration_response,
                      RegistrationResponse)
    assert set(service_context.registration_response.keys()) == {
        'client_secret_expires_at', 'contacts', 'client_id',
        'token_endpoint_auth_method', 'redirect_uris', 'response_types',
        'client_id_issued_at', 'client_secret', 'application_type',
        'registration_client_uri', 'registration_access_token', 'grant_types'
    }

    # =================== Authorization ====================

    STATE = 'Oh3w3gKlvoM2ehFqlxI3HIK5'
    NONCE = 'UvudLKz287YByZdsY3AJoPAlEXQkJ0dK'

    info = service['authorization'].get_request_parameters(request_args={
        'state': STATE,
        'nonce': NONCE
    })

    p = urlparse(info['url'])
    _query = parse_qs(p.query)
    assert set(_query.keys()) == {
        'state', 'nonce', 'response_type', 'scope', 'client_id', 'redirect_uri'
    }
    assert _query['scope'] == ['openid']
    assert _query['nonce'] == [NONCE]
    assert _query['state'] == [STATE]

    op_authz_resp = {
        'state': STATE,
        'scope': 'openid',
        'code': 'Z0FBQUFBQmFkdFFjUVpFWE81SHU5N1N4N01',
        'iss': OP_BASEURL,
        'client_id': 'zls2qhN1jO6A'
    }

    _authz_rep = AuthorizationResponse(**op_authz_resp)

    _resp = service['authorization'].parse_response(_authz_rep.to_urlencoded())
    service['authorization'].update_service_context(_resp, key=STATE)
    _item = service['authorization'].get_item(AuthorizationResponse,
                                              'auth_response', STATE)
    assert _item['code'] == 'Z0FBQUFBQmFkdFFjUVpFWE81SHU5N1N4N01'

    # =================== Access token ====================

    request_args = {
        'state': STATE,
        'redirect_uri': service_context.redirect_uris[0]
    }

    info = service['accesstoken'].get_request_parameters(
        request_args=request_args)

    assert info['url'] == 'https://example.org/op/token'
    _qp = parse_qs(info['body'])
    assert _qp == {
        'grant_type': ['authorization_code'],
        'redirect_uri': ['https://example.com/rp/authz_cb'],
        'client_id': ['zls2qhN1jO6A'],
        'state': ['Oh3w3gKlvoM2ehFqlxI3HIK5'],
        'code': ['Z0FBQUFBQmFkdFFjUVpFWE81SHU5N1N4N01']
    }
    assert info['headers'] == {
        'Authorization': 'Basic '
        'emxzMnFoTjFqTzZBOmM4NDM0ZjI4Y2Y5Mzc1ZDlhNw==',
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    # create the IdToken
    _jwt = JWT(OP_KEYJAR,
               OP_BASEURL,
               lifetime=3600,
               sign=True,
               sign_alg='RS256')
    payload = {
        'sub': '1b2fc9341a16ae4e30082965d537',
        'acr': 'PASSWORD',
        'auth_time': 1517736988,
        'nonce': NONCE
    }
    _jws = _jwt.pack(payload=payload, recv='zls2qhN1jO6A')

    _resp = {
        "state": "Oh3w3gKlvoM2ehFqlxI3HIK5",
        "scope": "openid",
        "access_token": "Z0FBQUFBQmFkdFF",
        "token_type": "Bearer",
        'expires_in': 600,
        "id_token": _jws
    }

    service_context.issuer = OP_BASEURL
    _resp = service['accesstoken'].parse_response(json.dumps(_resp),
                                                  state=STATE)

    assert isinstance(_resp, AccessTokenResponse)
    assert set(_resp['__verified_id_token'].keys()) == {
        'iss', 'nonce', 'acr', 'auth_time', 'aud', 'iat', 'exp', 'sub'
    }

    service['accesstoken'].update_service_context(_resp, key=STATE)

    _item = service['authorization'].get_item(AccessTokenResponse,
                                              'token_response', STATE)

    assert set(_item.keys()) == {
        'state', 'scope', 'access_token', 'token_type', 'id_token',
        '__verified_id_token', 'expires_in', '__expires_at'
    }

    assert _item['token_type'] == 'Bearer'
    assert _item['access_token'] == 'Z0FBQUFBQmFkdFF'

    # =================== User info ====================

    info = service['userinfo'].get_request_parameters(state=STATE)

    assert info['url'] == 'https://example.org/op/userinfo'
    assert info['headers'] == {'Authorization': 'Bearer Z0FBQUFBQmFkdFF'}

    op_resp = {"sub": "1b2fc9341a16ae4e30082965d537"}

    _resp = service['userinfo'].parse_response(json.dumps(op_resp),
                                               state=STATE)
    service['userinfo'].update_service_context(_resp, key=STATE)

    assert isinstance(_resp, OpenIDSchema)
    assert _resp.to_dict() == {'sub': '1b2fc9341a16ae4e30082965d537'}

    _item = service['authorization'].get_item(OpenIDSchema, 'user_info', STATE)
    assert _item.to_dict() == {'sub': '1b2fc9341a16ae4e30082965d537'}