示例#1
0
 def create_client_info_instance(self):
     config = {
         'client_id': 'client_id', 'issuer': 'issuer',
         'client_secret': 'client_secret', 'base_url': 'https://example.com',
         'requests_dir': 'requests'
     }
     self.ci = ClientInfo(config=config)
示例#2
0
def test_client_filename():
    config = {
        'client_id': 'client_id', 'issuer': 'issuer',
        'client_secret': 'client_secret', 'base_url': 'https://example.com',
        'requests_dir': 'requests'
    }
    ci = ClientInfo(config=config)
    fname = ci.filename_from_webname('https://example.com/rq12345')
    assert fname == 'rq12345'
示例#3
0
    def __init__(self, ca_certs=None, client_authn_method=None,
                 keyjar=None, verify_ssl=True, config=None, client_cert=None,
                 httplib=None, services=None, service_factory=None):
        """

        :param ca_certs: Certificates used to verify HTTPS certificates
        :param client_authn_method: Methods that this client can use to
            authenticate itself. It's a dictionary with method names as
            keys and method classes as values.
        :param verify_ssl: Whether the SSL certificate should be verified.
        :return: Client instance
        """

        self.http = httplib or HTTPLib(ca_certs=ca_certs,
                                       verify_ssl=verify_ssl,
                                       client_cert=client_cert,
                                       keyjar=keyjar)

        if not keyjar:
            keyjar = KeyJar()

        self.events = None
        self.client_info = ClientInfo(keyjar, config=config)
        if self.client_info.client_id:
            self.client_id = self.client_info.client_id
        _cam = client_authn_method or CLIENT_AUTHN_METHOD
        self.service_factory = service_factory or service.factory
        _srvs = services or DEFAULT_SERVICES

        self.service = build_services(_srvs, self.service_factory, self.http,
                                      keyjar, _cam)

        self.client_info.service = self.service

        self.verify_ssl = verify_ssl
示例#4
0
def test_add_code_challenge_default_values():
    config = {
        'client_id': 'client_id', 'issuer': 'issuer',
        'client_secret': 'client_secret', 'base_url': 'https://example.com',
        'requests_dir': 'requests',
    }
    ci = ClientInfo(config=config)
    ci.state_db['state'] = {}
    spec = add_code_challenge(ci, 'state')

    # default values are length:64 method:S256
    assert set(spec.keys()) == {'code_challenge', 'code_challenge_method'}
    assert spec['code_challenge_method'] == 'S256'

    code_verifier = get_code_verifier(ci, 'state')
    assert len(code_verifier) == 64
示例#5
0
def test_add_code_challenge_spec_values():
    config = {
        'client_id': 'client_id', 'issuer': 'issuer',
        'client_secret': 'client_secret', 'base_url': 'https://example.com',
        'requests_dir': 'requests',
        'code_challenge': {'length': 128, 'method': 'S384'}
    }
    ci = ClientInfo(config=config)
    ci.state_db['state'] = {}

    spec = add_code_challenge(ci, 'state')
    assert set(spec.keys()) == {'code_challenge', 'code_challenge_method'}
    assert spec['code_challenge_method'] == 'S384'

    code_verifier = get_code_verifier(ci, 'state')
    assert len(code_verifier) == 128
示例#6
0
def test_client_info_init():
    config = {
        'client_id': 'client_id', 'issuer': 'issuer',
        'client_secret': 'client_secret', 'base_url': 'https://example.com',
        'requests_dir': 'requests'
    }
    ci = ClientInfo(config=config)
    for attr in config.keys():
        val = getattr(ci, attr)
        assert val == config[attr]
示例#7
0
def test_request_object_encryption():
    msg = AuthorizationRequest(state='ABCDE',
                               redirect_uri='https://example.com/cb',
                               response_type='code')

    conf = {
        'redirect_uris': ['https://example.com/cli/authz_cb'],
        'client_id': 'client_1',
        'client_secret': 'abcdefghijklmnop',
    }
    client_info = ClientInfo(keyjar=keyjar, config=conf)
    client_info.behaviour["request_object_encryption_alg"] = 'RSA1_5'
    client_info.behaviour["request_object_encryption_enc"] = "A128CBC-HS256"

    _jwe = request_object_encryption(msg.to_json(),
                                     client_info,
                                     target=RECEIVER)
    assert _jwe

    _jw = factory(_jwe)

    assert _jw.jwt.headers['alg'] == 'RSA1_5'
    assert _jw.jwt.headers['enc'] == 'A128CBC-HS256'
示例#8
0
class TestClientInfo(object):
    @pytest.fixture(autouse=True)
    def create_client_info_instance(self):
        config = {
            'client_id': 'client_id', 'issuer': 'issuer',
            'client_secret': 'client_secret', 'base_url': 'https://example.com',
            'requests_dir': 'requests'
        }
        self.ci = ClientInfo(config=config)

    def test_registration_userinfo_sign_enc_algs(self):
        self.ci.registration_response = {
            "application_type": "web",
            "redirect_uris": ["https://client.example.org/callback",
                              "https://client.example.org/callback2"],
            "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",
        }

        res = self.ci.sign_enc_algs('userinfo')
        assert res == {'sign': 'RS256', 'alg': 'RSA1_5', 'enc': 'A128CBC-HS256'}

    def test_registration_request_object_sign_enc_algs(self):
        self.ci.registration_response = {
            "application_type": "web",
            "redirect_uris": ["https://client.example.org/callback",
                              "https://client.example.org/callback2"],
            "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",
            "request_object_signing_alg": "RS384"
        }

        res = self.ci.sign_enc_algs('userinfo')
        # 'sign':'RS256' is an added default
        assert res == {'sign': 'RS256', 'alg': 'RSA1_5', 'enc': 'A128CBC-HS256'}
        res = self.ci.sign_enc_algs('request')
        assert res == {'sign': 'RS384'}

    def test_registration_id_token_sign_enc_algs(self):
        self.ci.registration_response = {
            "application_type": "web",
            "redirect_uris": ["https://client.example.org/callback",
                              "https://client.example.org/callback2"],
            "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",
            "request_object_signing_alg": "RS384",
            'id_token_encrypted_response_alg': 'ECDH-ES',
            'id_token_encrypted_response_enc': "A128GCM",
            'id_token_signed_response_alg': "ES384",
        }

        res = self.ci.sign_enc_algs('userinfo')
        # 'sign':'RS256' is an added default
        assert res == {'sign': 'RS256', 'alg': 'RSA1_5', 'enc': 'A128CBC-HS256'}
        res = self.ci.sign_enc_algs('request')
        assert res == {'sign': 'RS384'}
        res = self.ci.sign_enc_algs('id_token')
        assert res == {'sign': 'ES384', 'alg': 'ECDH-ES', 'enc': 'A128GCM'}

    def test_verify_alg_support(self):
        self.ci.provider_info = {
            "version": "3.0",
            "issuer": "https://server.example.com",
            "authorization_endpoint":
                "https://server.example.com/connect/authorize",
            "token_endpoint": "https://server.example.com/connect/token",
            "token_endpoint_auth_methods_supported": ["client_secret_basic",
                                                      "private_key_jwt"],
            "token_endpoint_auth_signing_alg_values_supported": ["RS256",
                                                                 "ES256"],
            "userinfo_endpoint": "https://server.example.com/connect/userinfo",
            "check_session_iframe":
                "https://server.example.com/connect/check_session",
            "end_session_endpoint":
                "https://server.example.com/connect/end_session",
            "jwks_uri": "https://server.example.com/jwks.json",
            "registration_endpoint":
                "https://server.example.com/connect/register",
            "scopes_supported": ["openid", "profile", "email", "address",
                                 "phone", "offline_access"],
            "response_types_supported": ["code", "code id_token", "id_token",
                                         "token id_token"],
            "acr_values_supported": ["urn:mace:incommon:iap:silver",
                                     "urn:mace:incommon:iap:bronze"],
            "subject_types_supported": ["public", "pairwise"],
            "userinfo_signing_alg_values_supported": ["RS256", "ES256",
                                                      "HS256"],
            "userinfo_encryption_alg_values_supported": ["RSA1_5", "A128KW"],
            "userinfo_encryption_enc_values_supported": ["A128CBC+HS256",
                                                         "A128GCM"],
            "id_token_signing_alg_values_supported": ["RS256", "ES256",
                                                      "HS256"],
            "id_token_encryption_alg_values_supported": ["RSA1_5", "A128KW"],
            "id_token_encryption_enc_values_supported": ["A128CBC+HS256",
                                                         "A128GCM"],
            "request_object_signing_alg_values_supported": ["none", "RS256",
                                                            "ES256"],
            "display_values_supported": ["page", "popup"],
            "claim_types_supported": ["normal", "distributed"],
            "claims_supported": ["sub", "iss", "auth_time", "acr", "name",
                                 "given_name", "family_name", "nickname",
                                 "profile",
                                 "picture", "website", "email",
                                 "email_verified",
                                 "locale", "zoneinfo",
                                 "http://example.info/claims/groups"],
            "claims_parameter_supported": True,
            "service_documentation":
                "http://server.example.com/connect/service_documentation.html",
            "ui_locales_supported": ["en-US", "en-GB", "en-CA", "fr-FR",
                                     "fr-CA"]
        }

        assert self.ci.verify_alg_support('RS256', 'id_token', 'signing_alg')
        assert self.ci.verify_alg_support(
            'RS512', 'id_token', 'signing_alg') is False

        assert self.ci.verify_alg_support('RSA1_5', 'userinfo',
                                          'encryption_alg')

        # token_endpoint_auth_signing_alg_values_supported
        assert self.ci.verify_alg_support('ES256', 'token_endpoint_auth',
                                          'signing_alg')

    def test_verify_requests_uri(self):
        self.ci.provider_info['issuer'] = 'https://example.com/'
        url_list = self.ci.generate_request_uris('/leading')
        sp = urlsplit(url_list[0])
        p = sp.path.split('/')
        assert p[0] == ''
        assert p[1] == 'leading'
        assert len(p) == 3

        # different for different OPs
        self.ci.provider_info['issuer'] = 'https://op.example.org/'
        url_list = self.ci.generate_request_uris('/leading')
        sp = urlsplit(url_list[0])
        np = sp.path.split('/')
        assert np[0] == ''
        assert np[1] == 'leading'
        assert len(np) == 3

        assert np[2] != p[2]

    def test_import_keys(self):
        # Should only be two and that a symmetric key (client_secret) usable
        # for signing and encryption
        assert len(self.ci.keyjar.get_issuer_keys('')) == 2

        file_path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), 'salesforce.key'))

        keyspec = {'file': {'rsa': [file_path]}}
        self.ci.import_keys(keyspec)

        # Now there should be 3, the third a RSA key for signing
        assert len(self.ci.keyjar.get_issuer_keys('')) == 3
示例#9
0
def test_set_and_get_client_id():
    ci = ClientInfo()
    ci.client_id = 'myself'
    assert ci.client_id == 'myself'
    assert ci.state_db.client_id == 'myself'
示例#10
0
def test_set_and_get_client_secret():
    ci = ClientInfo()
    ci.client_secret = 'supersecret'
    assert ci.client_secret == 'supersecret'