class TestRPHandlerTier2(object):
    @pytest.fixture(autouse=True)
    def rphandler_setup(self, httpserver):
        self.rph = RPHandler(base_url=BASEURL, client_configs=CLIENT_CONFIG)
        res = self.rph.begin(issuer_id='github')
        _session = self.rph.get_session_information(res['state'])
        client = self.rph.issuer2rp[_session['iss']]
        _nonce = _session['auth_request']['nonce']
        _iss = _session['iss']
        _aud = client.client_id
        idval = {'nonce': _nonce, 'sub': 'EndUserSubject', 'iss': _iss,
                 'aud': _aud}

        idts = IdToken(**idval)
        _signed_jwt = idts.to_jwt(
            key=client.service_context.keyjar.get_signing_key('oct'),
            algorithm="HS256", lifetime=300)

        _info = {"access_token": "accessTok", "id_token": _signed_jwt,
                 "token_type": "Bearer", "expires_in": 3600,
                 'refresh_token': 'refreshing'}

        at = AccessTokenResponse(**_info)
        httpserver.serve_content(at.to_json())
        client.service['accesstoken'].endpoint = httpserver.url

        _response = AuthorizationResponse(code='access_code',
                                          state=res['state'])
        auth_response = self.rph.finalize_auth(client, _session['iss'],
                                               _response.to_dict())

        token_resp = self.rph.get_access_and_id_token(auth_response,
                                                      client=client)

        httpserver.serve_content('{"sub":"EndUserSubject"}')
        client.service['userinfo'].endpoint = httpserver.url

        self.rph.get_user_info(res['state'], client,
                               token_resp['access_token'])
        self.state = res['state']

    def test_init_authorization(self):
        _session = self.rph.get_session_information(self.state)
        client = self.rph.issuer2rp[_session['iss']]
        res = self.rph.init_authorization(
            client, req_args={'scope': ['openid', 'email']})
        part = urlsplit(res['url'])
        _qp = parse_qs(part.query)
        assert _qp['scope'] == ['openid email']

    def test_refresh_access_token(self, httpserver):
        _session = self.rph.get_session_information(self.state)
        client = self.rph.issuer2rp[_session['iss']]

        _info = {"access_token": "2nd_accessTok",
                 "token_type": "Bearer", "expires_in": 3600}
        at = AccessTokenResponse(**_info)
        httpserver.serve_content(at.to_json())
        client.service['refresh_token'].endpoint = httpserver.url

        res = self.rph.refresh_access_token(self.state, client,
                                            'openid email')
        assert res['access_token'] == '2nd_accessTok'

    def test_get_user_info(self, httpserver):
        _session = self.rph.get_session_information(self.state)
        client = self.rph.issuer2rp[_session['iss']]

        httpserver.serve_content(
            '{"sub":"EndUserSubject", "mail":"*****@*****.**"}')
        client.service['userinfo'].endpoint = httpserver.url

        resp = self.rph.get_user_info(self.state, client)
        assert set(resp.keys()) == {'sub', 'mail'}
        assert resp['mail'] == '*****@*****.**'

    def test_has_active_authentication(self):
        assert self.rph.has_active_authentication(self.state)

    def test_get_valid_access_token(self):
        (token, expires_at) = self.rph.get_valid_access_token(self.state)
        assert token == 'accessTok'
        assert expires_at > 0
Пример #2
0
class TestRPHandlerTier2(object):
    @pytest.fixture(autouse=True)
    def rphandler_setup(self):
        self.rph = RPHandler(BASE_URL, CLIENT_CONFIG, keyjar=CLI_KEY)
        res = self.rph.begin(issuer_id='github')
        _session = self.rph.get_session_information(res['state'])
        client = self.rph.issuer2rp[_session['iss']]
        _nonce = _session['auth_request']['nonce']
        _iss = _session['iss']
        _aud = client.client_id
        idval = {
            'nonce': _nonce,
            'sub': 'EndUserSubject',
            'iss': _iss,
            'aud': _aud
        }

        _github_id = iss_id('github')
        client.service_context.keyjar.import_jwks(
            GITHUB_KEY.export_jwks(issuer_id=_github_id), _github_id)

        idts = IdToken(**idval)
        _signed_jwt = idts.to_jwt(key=GITHUB_KEY.get_signing_key(
            'rsa', issuer_id=_github_id),
                                  algorithm="RS256",
                                  lifetime=300)

        _info = {
            "access_token": "accessTok",
            "id_token": _signed_jwt,
            "token_type": "Bearer",
            "expires_in": 3600,
            'refresh_token': 'refreshing'
        }

        at = AccessTokenResponse(**_info)
        _url = "https://github.com/token"
        with responses.RequestsMock() as rsps:
            rsps.add("POST",
                     _url,
                     body=at.to_json(),
                     adding_headers={"Content-Type": "application/json"},
                     status=200)

            client.service['accesstoken'].endpoint = _url

            _response = AuthorizationResponse(code='access_code',
                                              state=res['state'])
            auth_response = self.rph.finalize_auth(client, _session['iss'],
                                                   _response.to_dict())

            token_resp = self.rph.get_access_and_id_token(auth_response,
                                                          client=client)

        _url = "https://github.com/token"
        with responses.RequestsMock() as rsps:
            rsps.add("GET",
                     _url,
                     body='{"sub":"EndUserSubject"}',
                     adding_headers={"Content-Type": "application/json"},
                     status=200)

            client.service['userinfo'].endpoint = _url
            self.rph.get_user_info(res['state'], client,
                                   token_resp['access_token'])
            self.state = res['state']

    def test_init_authorization(self):
        _session = self.rph.get_session_information(self.state)
        client = self.rph.issuer2rp[_session['iss']]
        res = self.rph.init_authorization(
            client, req_args={'scope': ['openid', 'email']})
        part = urlsplit(res['url'])
        _qp = parse_qs(part.query)
        assert _qp['scope'] == ['openid email']

    def test_refresh_access_token(self):
        _session = self.rph.get_session_information(self.state)
        client = self.rph.issuer2rp[_session['iss']]

        _info = {
            "access_token": "2nd_accessTok",
            "token_type": "Bearer",
            "expires_in": 3600
        }
        at = AccessTokenResponse(**_info)
        _url = "https://github.com/token"
        with responses.RequestsMock() as rsps:
            rsps.add("POST",
                     _url,
                     body=at.to_json(),
                     adding_headers={"Content-Type": "application/json"},
                     status=200)

            client.service['refresh_token'].endpoint = _url
            res = self.rph.refresh_access_token(self.state, client,
                                                'openid email')
            assert res['access_token'] == '2nd_accessTok'

    def test_get_user_info(self):
        _session = self.rph.get_session_information(self.state)
        client = self.rph.issuer2rp[_session['iss']]

        _url = "https://github.com/userinfo"
        with responses.RequestsMock() as rsps:
            rsps.add("GET",
                     _url,
                     body='{"sub":"EndUserSubject", "mail":"*****@*****.**"}',
                     adding_headers={"Content-Type": "application/json"},
                     status=200)
            client.service['userinfo'].endpoint = _url

            resp = self.rph.get_user_info(self.state, client)
            assert set(resp.keys()) == {'sub', 'mail'}
            assert resp['mail'] == '*****@*****.**'

    def test_has_active_authentication(self):
        assert self.rph.has_active_authentication(self.state)

    def test_get_valid_access_token(self):
        (token, expires_at) = self.rph.get_valid_access_token(self.state)
        assert token == 'accessTok'
        assert expires_at > 0
Пример #3
0
class TestRPHandler(object):
    @pytest.fixture(autouse=True)
    def rphandler_setup(self):
        self.rph = RPHandler(BASE_URL)

    def test_pick_config(self):
        cnf = self.rph.pick_config('')
        assert cnf

    def test_init_client(self):
        client = self.rph.init_client('')
        assert set(client.service.keys()) == {
            'registration', 'provider_info', 'webfinger', 'authorization',
            'accesstoken', 'userinfo', 'refresh_token'
        }

        _context = client.service_context

        assert _context.config['client_preferences'] == {
            'application_type':
            'web',
            'application_name':
            'rphandler',
            'response_types': [
                'code', 'id_token', 'id_token token', 'code id_token',
                'code id_token token', 'code token'
            ],
            'scope': ['openid'],
            'token_endpoint_auth_method':
            'client_secret_basic'
        }

        assert list(_context.keyjar.owners()) == ['', BASE_URL]
        keys = _context.keyjar.get_issuer_keys('')
        assert len(keys) == 2

        assert _context.base_url == BASE_URL

    def test_begin(self):
        ISS_ID = "https://op.example.org"
        OP_KEYS = build_keyjar(DEFAULT_KEY_DEFS)
        # The 4 steps of client_setup
        client = self.rph.init_client(ISS_ID)
        with responses.RequestsMock() as rsps:
            request_uri = '{}/.well-known/openid-configuration'.format(ISS_ID)
            _jws = ProviderConfigurationResponse(
                issuer=ISS_ID,
                authorization_endpoint='{}/authorization'.format(ISS_ID),
                jwks_uri='{}/jwks.json'.format(ISS_ID),
                response_types_supported=[
                    'code', 'id_token', 'id_token token'
                ],
                subject_types_supported=['public'],
                id_token_signing_alg_values_supported=["RS256", "ES256"],
                token_endpoint='{}/token'.format(ISS_ID),
                registration_endpoint='{}/register'.format(ISS_ID)).to_json()
            rsps.add("GET", request_uri, body=_jws, status=200)

            rsps.add("GET",
                     '{}/jwks.json'.format(ISS_ID),
                     body=OP_KEYS.export_jwks_as_json(),
                     status=200)

            issuer = self.rph.do_provider_info(client)

        # Calculating request so I can build a reasonable response
        self.rph.add_callbacks(client.service_context)
        _req = client.service['registration'].construct_request()

        with responses.RequestsMock() as rsps:
            request_uri = client.service_context.get(
                'provider_info')["registration_endpoint"]
            _jws = RegistrationResponse(
                client_id="client uno",
                client_secret="VerySecretAndLongEnough",
                **_req.to_dict()).to_json()
            rsps.add("POST", request_uri, body=_jws, status=200)
            self.rph.do_client_registration(client, ISS_ID)

        self.rph.issuer2rp[issuer] = client

        assert set(client.service_context.get('behaviour').keys()) == {
            'token_endpoint_auth_method', 'response_types', 'scope',
            'application_type', 'application_name'
        }
        assert client.service_context.get('client_id') == "client uno"
        assert client.service_context.get(
            'client_secret') == "VerySecretAndLongEnough"
        assert client.service_context.get('issuer') == ISS_ID

        res = self.rph.init_authorization(client)
        assert set(res.keys()) == {'url', 'state'}
        p = urlparse(res["url"])
        assert p.hostname == 'op.example.org'
        assert p.path == "/authorization"
        qs = parse_qs(p.query)
        assert qs['state'] == [res['state']]
        # PKCE stuff
        assert 'code_challenge' in qs
        assert qs["code_challenge_method"] == ["S256"]

    def test_begin_2(self):
        ISS_ID = "https://op.example.org"
        OP_KEYS = build_keyjar(DEFAULT_KEY_DEFS)
        # The 4 steps of client_setup
        client = self.rph.init_client(ISS_ID)
        with responses.RequestsMock() as rsps:
            request_uri = '{}/.well-known/openid-configuration'.format(ISS_ID)
            _jws = ProviderConfigurationResponse(
                issuer=ISS_ID,
                authorization_endpoint='{}/authorization'.format(ISS_ID),
                jwks_uri='{}/jwks.json'.format(ISS_ID),
                response_types_supported=[
                    'code', 'id_token', 'id_token token'
                ],
                subject_types_supported=['public'],
                id_token_signing_alg_values_supported=["RS256", "ES256"],
                token_endpoint='{}/token'.format(ISS_ID),
                registration_endpoint='{}/register'.format(ISS_ID)).to_json()
            rsps.add("GET", request_uri, body=_jws, status=200)

            rsps.add("GET",
                     '{}/jwks.json'.format(ISS_ID),
                     body=OP_KEYS.export_jwks_as_json(),
                     status=200)

            issuer = self.rph.do_provider_info(client)

        # Calculating request so I can build a reasonable response
        self.rph.add_callbacks(client.service_context)
        # Publishing a JWKS instead of a JWKS_URI
        client.service_context.jwks_uri = ''
        client.service_context.jwks = client.service_context.keyjar.export_jwks(
        )

        _req = client.service['registration'].construct_request()

        with responses.RequestsMock() as rsps:
            request_uri = client.service_context.get(
                'provider_info')["registration_endpoint"]
            _jws = RegistrationResponse(
                client_id="client uno",
                client_secret="VerySecretAndLongEnough",
                **_req.to_dict()).to_json()
            rsps.add("POST", request_uri, body=_jws, status=200)
            self.rph.do_client_registration(client, ISS_ID)

        assert 'jwks' in client.service_context.get('registration_response')