class TestRPHandlerWithMockOP(object):
    @pytest.fixture(autouse=True)
    def rphandler_setup(self):
        self.rph = RPHandler(
            base_url=BASE_URL,
            client_configs=CLIENT_CONFIG,
            http_lib=MockOP(issuer='https://github.com/login/oauth/authorize'))

    def test_finalize(self):
        auth_query = self.rph.begin(issuer_id='github')
        #  The authorization query is sent and after successful authentication
        client = self.rph.get_client_from_session_key(
            state=auth_query['state'])
        _ = client.http(auth_query['url'])

        #  the user is redirected back to the RP with a positive response
        auth_response = AuthorizationResponse(code='access_code',
                                              state=auth_query['state'])

        # need session information and the client instance
        _session = self.rph.get_session_information(auth_response['state'])
        client = self.rph.get_client_from_session_key(
            state=auth_response['state'])

        # Faking
        self.rph.httplib.keyjar = client.service_context.keyjar

        # do the rest (= get access token and user info)
        # assume code flow
        resp = self.rph.finalize(_session['iss'], auth_response.to_dict())

        assert set(resp.keys()) == {'userinfo', 'state', 'token'}
Exemple #2
0
 def rphandler_setup(self):
     self.issuer = 'https://github.com/login/oauth/authorize'
     self.mock_op = MockOP(issuer=self.issuer)
     self.rph = RPHandler(BASE_URL,
                          client_configs=CLIENT_CONFIG,
                          http_lib=self.mock_op,
                          keyjar=KeyJar())
    def rphandler_setup(self, httpserver):
        self.rph = RPHandler(base_url=BASE_URL,
                             client_configs=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=_github_id), _github_id)

        idts = IdToken(**idval)
        _signed_jwt = idts.to_jwt(key=GITHUB_KEY.get_signing_key(
            'rsa', owner=_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)
        httpserver.serve_content(at.to_json(),
                                 headers={'Content-Type': 'application/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"}',
                                 headers={'Content-Type': 'application/json'})
        client.service['userinfo'].endpoint = httpserver.url

        self.rph.get_user_info(res['state'], client,
                               token_resp['access_token'])
        self.state = res['state']
Exemple #4
0
def init_oidc_rp_handler(app):
    _jwks_def = app.config.get('KEYS')
    _jwks_def['public_path'] = _jwks_def['public_path'].format(dir_path)
    _jwks_def['private_path'] = _jwks_def['private_path'].format(dir_path)
    _kj = init_key_jar(**_jwks_def)
    rph = RPHandler(base_url=app.config.get('BASE_URL'),
                    hash_seed="BabyHoldOn",
                    keyjar=_kj,
                    jwks_path=app.config.get('PUBLIC_JWKS_PATH'),
                    client_configs=app.config.get('CLIENTS'),
                    services=app.config.get('SERVICES'),
                    verify_ssl=app.config.get('VERIFY_SSL'))

    return rph
Exemple #5
0
def init_oidc_rp_handler(app):
    _rp_conf = app.rp_config

    if _rp_conf.rp_keys:
        _kj = init_key_jar(**_rp_conf.rp_keys)
        _path = _rp_conf.rp_keys['public_path']
        # removes ./ and / from the begin of the string
        _path = re.sub('^(.)/', '', _path)
    else:
        _kj = KeyJar()
        _path = ''
    _kj.httpc_params = _rp_conf.httpc_params

    rph = RPHandler(_rp_conf.base_url, _rp_conf.clients, services=_rp_conf.services,
                    hash_seed=_rp_conf.hash_seed, keyjar=_kj, jwks_path=_path,
                    httpc_params=_rp_conf.httpc_params)

    return rph
def init_oidc_rp_handler(app):
    oidc_keys_conf = app.config.get('OIDC_KEYS')
    verify_ssl = app.config.get('VERIFY_SSL')

    _kj = init_key_jar(**oidc_keys_conf)
    _kj.verify_ssl = verify_ssl

    _path = oidc_keys_conf['public_path']
    if _path.startswith('./'):
        _path = _path[2:]
    elif _path.startswith('/'):
        _path = _path[1:]

    rph = RPHandler(base_url=app.config.get('BASEURL'),
                    hash_seed="BabyHoldOn",
                    keyjar=_kj,
                    jwks_path=_path,
                    client_configs=app.config.get('CLIENTS'),
                    services=app.config.get('SERVICES'),
                    verify_ssl=verify_ssl)
    return rph
Exemple #7
0
class TestRPHandlerWithMockOP(object):
    @pytest.fixture(autouse=True)
    def rphandler_setup(self):
        self.issuer = 'https://github.com/login/oauth/authorize'
        self.mock_op = MockOP(issuer=self.issuer)
        self.rph = RPHandler(BASE_URL,
                             client_configs=CLIENT_CONFIG,
                             http_lib=self.mock_op,
                             keyjar=KeyJar())

    def test_finalize(self):
        auth_query = self.rph.begin(issuer_id='github')
        #  The authorization query is sent and after successful authentication
        client = self.rph.get_client_from_session_key(
            state=auth_query['state'])
        # register a response
        p = urlparse(
            CLIENT_CONFIG['github']['provider_info']['authorization_endpoint'])
        self.mock_op.register_get_response(p.path, 'Redirect', 302)

        _ = client.http(auth_query['url'])

        #  the user is redirected back to the RP with a positive response
        auth_response = AuthorizationResponse(code='access_code',
                                              state=auth_query['state'])

        # need session information and the client instance
        _session = self.rph.get_session_information(auth_response['state'])
        client = self.rph.get_client_from_session_key(
            state=auth_response['state'])

        # Faking
        resp = construct_access_token_response(
            _session['auth_request']['nonce'],
            issuer=self.issuer,
            client_id=CLIENT_CONFIG['github']['client_id'],
            key_jar=GITHUB_KEY)

        p = urlparse(
            CLIENT_CONFIG['github']['provider_info']['token_endpoint'])
        self.mock_op.register_post_response(
            p.path, resp.to_json(), 200, {'content-type': "application/json"})

        _info = OpenIDSchema(sub='EndUserSubject',
                             given_name='Diana',
                             family_name='Krall',
                             occupation='Jazz pianist')
        p = urlparse(
            CLIENT_CONFIG['github']['provider_info']['userinfo_endpoint'])
        self.mock_op.register_get_response(
            p.path, _info.to_json(), 200, {'content-type': "application/json"})

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

        # do the rest (= get access token and user info)
        # assume code flow
        resp = self.rph.finalize(_session['iss'], auth_response.to_dict())

        assert set(resp.keys()) == {'userinfo', 'state', 'token', 'id_token'}

    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
Exemple #8
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
Exemple #9
0
 def rphandler_setup(self):
     self.rph = RPHandler(BASE_URL,
                          client_configs=CLIENT_CONFIG,
                          keyjar=CLI_KEY,
                          module_dirs=['oidc'])
Exemple #10
0
class TestRPHandler(object):
    @pytest.fixture(autouse=True)
    def rphandler_setup(self):
        self.rph = RPHandler(BASE_URL,
                             client_configs=CLIENT_CONFIG,
                             keyjar=CLI_KEY,
                             module_dirs=['oidc'])

    def test_pick_config(self):
        cnf = self.rph.pick_config('facebook')
        assert cnf['issuer'] == "https://www.facebook.com/v2.11/dialog/oauth"

        cnf = self.rph.pick_config('linkedin')
        assert cnf['issuer'] == "https://www.linkedin.com/oauth/v2/"

        cnf = self.rph.pick_config('github')
        assert cnf['issuer'] == "https://github.com/login/oauth/authorize"

        cnf = self.rph.pick_config('')
        assert 'issuer' not in cnf

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

        _context = client.service_context

        assert _context.get('client_id') == 'eeeeeeeee'
        assert _context.get('client_secret') == 'aaaaaaaaaaaaaaaaaaaa'
        assert _context.get(
            'issuer') == "https://github.com/login/oauth/authorize"

        assert _context.get('provider_info') is not None
        assert set(_context.get('provider_info').keys()) == {
            'authorization_endpoint', 'token_endpoint', 'userinfo_endpoint'
        }

        assert _context.get('behaviour') == {
            "response_types": ["code"],
            "scope": ["user", "public_repo"],
            "token_endpoint_auth_method": '',
            'verify_args': {
                'allow_sign_alg_none': True
            }
        }

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

        # The key jar should only contain a symmetric key that is the clients
        # secret. 2 because one is marked for encryption and the other signing
        # usage.

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

        assert _context.base_url == BASE_URL

    def test_do_provider_info(self):
        client = self.rph.init_client('github')
        issuer = self.rph.do_provider_info(client)
        assert issuer == iss_id('github')

        # Make sure the service endpoints are set

        for service_type in ['authorization', 'accesstoken', 'userinfo']:
            _srv = client.service[service_type]
            _endp = client.service_context.get('provider_info')[
                _srv.endpoint_name]
            assert _srv.endpoint == _endp

    def test_do_client_registration(self):
        client = self.rph.init_client('github')
        issuer = self.rph.do_provider_info(client)
        self.rph.do_client_registration(client, 'github')

        # only 2 things should have happened

        assert self.rph.hash2issuer['github'] == issuer
        assert client.service_context.get('post_logout_redirect_uris') is None

    def test_do_client_setup(self):
        client = self.rph.client_setup('github')
        _github_id = iss_id('github')
        _context = client.service_context

        assert _context.get('client_id') == 'eeeeeeeee'
        assert _context.get('client_secret') == 'aaaaaaaaaaaaaaaaaaaa'
        assert _context.get('issuer') == _github_id

        _context.keyjar.import_jwks(
            GITHUB_KEY.export_jwks(issuer_id=_github_id), _github_id)

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

        for service_type in ['authorization', 'accesstoken', 'userinfo']:
            _srv = client.service[service_type]
            _endp = client.service_context.get('provider_info')[
                _srv.endpoint_name]
            assert _srv.endpoint == _endp

        assert self.rph.hash2issuer['github'] == _context.get('issuer')

    def test_create_callbacks(self):
        cb = self.rph.create_callbacks('https://op.example.com/')

        assert set(cb.keys()) == {'code', 'implicit', 'form_post', '__hex'}
        _hash = cb['__hex']

        assert cb['code'] == 'https://example.com/rp/authz_cb/{}'.format(_hash)
        assert cb[
            'implicit'] == 'https://example.com/rp/authz_im_cb/{}'.format(
                _hash)
        assert cb[
            'form_post'] == 'https://example.com/rp/authz_fp_cb/{}'.format(
                _hash)

        assert list(self.rph.hash2issuer.keys()) == [_hash]

        assert self.rph.hash2issuer[_hash] == 'https://op.example.com/'

    def test_begin(self):
        res = self.rph.begin(issuer_id='github')
        assert set(res.keys()) == {'url', 'state'}
        _github_id = iss_id('github')

        client = self.rph.issuer2rp[_github_id]

        assert client.service_context.get('issuer') == _github_id

        part = urlsplit(res['url'])
        assert part.scheme == 'https'
        assert part.netloc == 'github.com'
        assert part.path == '/login/oauth/authorize'
        query = parse_qs(part.query)

        assert set(query.keys()) == {
            'nonce', 'state', 'client_id', 'redirect_uri', 'response_type',
            'scope'
        }

        # nonce and state are created on the fly so can't check for those
        assert query['client_id'] == ['eeeeeeeee']
        assert query['redirect_uri'] == [
            'https://example.com/rp/authz_cb/github'
        ]
        assert query['response_type'] == ['code']
        assert query['scope'] == ['user public_repo openid']

    def test_get_session_information(self):
        res = self.rph.begin(issuer_id='github')
        _session = self.rph.get_session_information(res['state'])
        assert self.rph.client_configs['github']['issuer'] == _session['iss']

    def test_get_client_from_session_key(self):
        res = self.rph.begin(issuer_id='linkedin')
        cli1 = self.rph.get_client_from_session_key(state=res['state'])
        _session = self.rph.get_session_information(res['state'])
        cli2 = self.rph.issuer2rp[_session['iss']]
        assert cli1 == cli2
        # redo
        self.rph.do_provider_info(state=res['state'])
        # get new redirect_uris
        cli2.service_context.redirect_uris = []
        self.rph.do_client_registration(state=res['state'])

    def test_finalize_auth(self):
        res = self.rph.begin(issuer_id='linkedin')
        _session = self.rph.get_session_information(res['state'])
        client = self.rph.issuer2rp[_session['iss']]

        auth_response = AuthorizationResponse(code='access_code',
                                              state=res['state'])
        resp = self.rph.finalize_auth(client, _session['iss'],
                                      auth_response.to_dict())
        assert set(resp.keys()) == {'state', 'code'}
        aresp = client.service['authorization'].get_item(
            AuthorizationResponse, 'auth_response', res['state'])
        assert set(aresp.keys()) == {'state', 'code'}

    def test_get_client_authn_method(self):
        res = self.rph.begin(issuer_id='github')
        _session = self.rph.get_session_information(res['state'])
        client = self.rph.issuer2rp[_session['iss']]
        authn_method = self.rph.get_client_authn_method(
            client, 'token_endpoint')
        assert authn_method == ''

        res = self.rph.begin(issuer_id='linkedin')
        _session = self.rph.get_session_information(res['state'])
        client = self.rph.issuer2rp[_session['iss']]
        authn_method = self.rph.get_client_authn_method(
            client, 'token_endpoint')
        assert authn_method == 'client_secret_post'

    def test_get_access_token(self):
        res = self.rph.begin(issuer_id='github')
        _session = self.rph.get_session_information(res['state'])
        client = self.rph.issuer2rp[_session['iss']]

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

        _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=GITHUB_KEY.get_signing_key(issuer_id=_github_id),
            algorithm="RS256",
            lifetime=300)

        _info = {
            "access_token": "accessTok",
            "id_token": _signed_jwt,
            "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['accesstoken'].endpoint = _url

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

            resp = self.rph.get_access_token(res['state'], client)
            assert set(resp.keys()) == {
                'access_token', 'expires_in', 'id_token', 'token_type',
                '__verified_id_token', '__expires_at'
            }

            atresp = client.service['accesstoken'].get_item(
                AccessTokenResponse, 'token_response', res['state'])
            assert set(atresp.keys()) == {
                'access_token', 'expires_in', 'id_token', 'token_type',
                '__verified_id_token', '__expires_at'
            }

    def test_access_and_id_token(self):
        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
        }

        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())
            resp = self.rph.get_access_and_id_token(auth_response,
                                                    client=client)
            assert resp['access_token'] == 'accessTok'
            assert isinstance(resp['id_token'], IdToken)

    def test_access_and_id_token_by_reference(self):
        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
        }

        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'])
            _ = self.rph.finalize_auth(client, _session['iss'],
                                       _response.to_dict())
            resp = self.rph.get_access_and_id_token(state=res['state'])
            assert resp['access_token'] == 'accessTok'
            assert isinstance(resp['id_token'], IdToken)

    def test_get_user_info(self):
        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
        }

        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/user_info"
        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

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

    def test_userinfo_in_id_token(self):
        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,
            'given_name': 'Diana',
            'family_name': 'Krall',
            'occupation': 'Jazz pianist'
        }

        idts = IdToken(**idval)

        userinfo = self.rph.userinfo_in_id_token(idts)
        assert set(userinfo.keys()) == {
            'sub', 'family_name', 'given_name', 'occupation'
        }
Exemple #11
0
    if args.insecure:
        verify_ssl = False
    else:
        verify_ssl = True

    federation_entity = make_federation_entity(
        config.CLIENTS['']['federation'],
        httpcli=requests.request,
        verify_ssl=verify_ssl)

    rph = RPHandler(base_url=_base_url,
                    hash_seed="BabyDriver",
                    keyjar=_kj,
                    jwks_path=config.RP_CONFIG['jwks_url_path'],
                    client_configs=config.CLIENTS,
                    service_factory=factory,
                    client_cls=oidc.RP,
                    verify_ssl=verify_ssl,
                    federation_entity=federation_entity)

    cherrypy.tree.mount(cprp.Consumer(rph, 'html'), '/', provider_config)

    # If HTTPS
    if args.tls:
        cherrypy.server.ssl_certificate = config.SERVER_CERT
        cherrypy.server.ssl_private_key = config.SERVER_KEY
        if config.CA_BUNDLE:
            cherrypy.server.ssl_certificate_chain = config.CA_BUNDLE

    cherrypy.engine.start()
class TestRPHandler(object):
    @pytest.fixture(autouse=True)
    def rphandler_setup(self):
        self.rph = RPHandler(base_url=BASEURL, client_configs=CLIENT_CONFIG)

    def test_support_webfinger(self):
        assert self.rph.supports_webfinger()

    def test_pick_config(self):
        cnf = self.rph.pick_config('facebook')
        assert cnf['issuer'] == "https://www.facebook.com/v2.11/dialog/oauth"

        cnf = self.rph.pick_config('linkedin')
        assert cnf['issuer'] == "https://www.linkedin.com/oauth/v2/"

        cnf = self.rph.pick_config('github')
        assert cnf['issuer'] == "https://github.com/login/oauth/authorize"

        cnf = self.rph.pick_config('')
        assert 'issuer' not in cnf

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

        _context = client.service_context

        assert _context.client_id == 'eeeeeeeee'
        assert _context.client_secret == 'aaaaaaaaaaaaa'
        assert _context.issuer == "https://github.com/login/oauth/authorize"

        assert _context.provider_info
        assert set(_context.provider_info.keys()) == {
            'authorization_endpoint', 'token_endpoint', 'userinfo_endpoint'
        }

        assert _context.behaviour == {
            "response_types": ["code"],
            "scope": ["user", "public_repo"],
            "token_endpoint_auth_method": ''
        }

        # The key jar should only contain a symmetric key that is the clients
        # secret. 2 because one is marked for encryption and the other signing
        # usage.

        assert list(_context.keyjar.owners()) == ['']
        keys = _context.keyjar.get_issuer_keys('')
        assert len(keys) == 2
        for key in keys:
            assert key.kty == 'oct'
            assert key.key == b'aaaaaaaaaaaaa'

        assert _context.base_url == BASEURL

    def test_do_provider_info(self):
        client = self.rph.init_client('github')
        issuer = self.rph.do_provider_info(client)
        assert issuer == "https://github.com/login/oauth/authorize"

        # Make sure the service endpoints are set

        for service_type in ['authorization', 'accesstoken', 'userinfo']:
            _srv = client.service[service_type]
            _endp = client.service_context.provider_info[_srv.endpoint_name]
            assert _srv.endpoint == _endp

    def test_do_client_registration(self):
        client = self.rph.init_client('github')
        issuer = self.rph.do_provider_info(client)
        self.rph.do_client_registration(client, 'github')

        # only 2 things should have happened

        assert self.rph.hash2issuer['github'] == issuer
        assert client.service_context.post_logout_redirect_uris == [BASEURL]

    def test_do_client_setup(self):
        client = self.rph.client_setup('github')

        _context = client.service_context

        assert _context.client_id == 'eeeeeeeee'
        assert _context.client_secret == 'aaaaaaaaaaaaa'
        assert _context.issuer == "https://github.com/login/oauth/authorize"

        assert list(_context.keyjar.owners()) == ['']
        keys = _context.keyjar.get_issuer_keys('')
        assert len(keys) == 2
        for key in keys:
            assert key.kty == 'oct'
            assert key.key == b'aaaaaaaaaaaaa'

        for service_type in ['authorization', 'accesstoken', 'userinfo']:
            _srv = client.service[service_type]
            _endp = client.service_context.provider_info[_srv.endpoint_name]
            assert _srv.endpoint == _endp

        assert self.rph.hash2issuer['github'] == _context.issuer

    def test_create_callbacks(self):
        cb = self.rph.create_callbacks('https://op.example.com/')

        assert set(cb.keys()) == {'code', 'implicit', 'form_post', '__hex'}
        assert cb == {
            'code': 'https://example.com/rp/authz_cb'
                    '/7f729285244adafbf5412e06b097e0e1f92049bfc432fed0a13cbcb5661b137d',
            'implicit':
                'https://example.com/rp/authz_im_cb'
                '/7f729285244adafbf5412e06b097e0e1f92049bfc432fed0a13cbcb5661b137d',
            'form_post':
                'https://example.com/rp/authz_fp_cb'
                '/7f729285244adafbf5412e06b097e0e1f92049bfc432fed0a13cbcb5661b137d',
            '__hex':
                '7f729285244adafbf5412e06b097e0e1f92049bfc432fed0a13cbcb5661b137d'
        }

        assert list(self.rph.hash2issuer.keys()) == [
            '7f729285244adafbf5412e06b097e0e1f92049bfc432fed0a13cbcb5661b137d']

        assert self.rph.hash2issuer[
                   '7f729285244adafbf5412e06b097e0e1f92049bfc432fed0a13cbcb5661b137d'
               ] == 'https://op.example.com/'

    def test_begin(self):
        res = self.rph.begin(issuer_id='github')
        assert set(res.keys()) == {'url', 'state'}

        _session = self.rph.session_interface.get_state(res['state'])
        client = self.rph.issuer2rp[_session['iss']]

        assert client.service_context.issuer == \
               "https://github.com/login/oauth/authorize"

        part = urlsplit(res['url'])
        assert part.scheme == 'https'
        assert part.netloc == 'github.com'
        assert part.path == '/login/oauth/authorize'
        query = parse_qs(part.query)

        assert set(query.keys()) == {'nonce', 'state', 'client_id',
                                     'redirect_uri', 'response_type', 'scope'}

        # nonce and state are created on the fly so can't check for those
        assert query['client_id'] == ['eeeeeeeee']
        assert query['redirect_uri'] == [
            'https://example.com/rp/authz_cb/github']
        assert query['response_type'] == ['code']
        assert query['scope'] == ['user public_repo openid']

    def test_get_session_information(self):
        res = self.rph.begin(issuer_id='github')
        _session = self.rph.get_session_information(res['state'])
        assert self.rph.client_configs['github']['issuer'] == _session['iss']

    def test_finalize_auth(self):
        res = self.rph.begin(issuer_id='linkedin')
        _session = self.rph.get_session_information(res['state'])
        client = self.rph.issuer2rp[_session['iss']]

        auth_response = AuthorizationResponse(code='access_code',
                                              state=res['state'])
        resp = self.rph.finalize_auth(client, _session['iss'],
                                      auth_response.to_dict())
        assert set(resp.keys()) == {'state', 'code'}
        aresp = client.service['authorization'].get_item(AuthorizationResponse,
                                                         'auth_response',
                                                         res['state'])
        assert set(aresp.keys()) == {'state', 'code'}

    def test_get_client_authn_method(self):
        res = self.rph.begin(issuer_id='github')
        _session = self.rph.get_session_information(res['state'])
        client = self.rph.issuer2rp[_session['iss']]
        authn_method = self.rph.get_client_authn_method(client,
                                                        'token_endpoint')
        assert authn_method == ''

        res = self.rph.begin(issuer_id='linkedin')
        _session = self.rph.get_session_information(res['state'])
        client = self.rph.issuer2rp[_session['iss']]
        authn_method = self.rph.get_client_authn_method(client,
                                                        'token_endpoint')
        assert authn_method == 'client_secret_post'

    def test_get_access_token(self, httpserver):
        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}

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

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

        resp = self.rph.get_access_token(res['state'], client)
        assert set(resp.keys()) == {'access_token', 'expires_in', 'id_token',
                                    'token_type', '__verified_id_token',
                                    '__expires_at'}

        atresp = client.service['accesstoken'].get_item(AccessTokenResponse,
                                                        'token_response',
                                                        res['state'])
        assert set(atresp.keys()) == {'access_token', 'expires_in', 'id_token',
                                      'token_type', '__verified_id_token',
                                      '__expires_at'}

    def test_access_and_id_token(self, httpserver):
        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}

        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())
        resp = self.rph.get_access_and_id_token(auth_response, client=client)
        assert resp['access_token'] == 'accessTok'
        assert isinstance(resp['id_token'], IdToken)

    def test_access_and_id_token_by_reference(self, httpserver):
        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}

        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())
        resp = self.rph.get_access_and_id_token(state=res['state'])
        assert resp['access_token'] == 'accessTok'
        assert isinstance(resp['id_token'], IdToken)

    def test_get_user_info(self, httpserver):
        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}

        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

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

    def test_userinfo_in_id_token(self):
        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, 'given_name': 'Diana', 'family_name': 'Krall',
                 'occupation': 'Jazz pianist'}

        idts = IdToken(**idval)

        userinfo = self.rph.userinfo_in_id_token(idts)
        assert set(userinfo.keys()) == {'sub', 'family_name', 'given_name',
                                        'occupation'}
Exemple #13
0
 def rphandler_setup(self):
     self.rph = RPHandler(BASE_URL)
Exemple #14
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')
 def rphandler_setup(self):
     self.rph = RPHandler(
         base_url=BASE_URL,
         client_configs=CLIENT_CONFIG,
         http_lib=MockOP(issuer='https://github.com/login/oauth/authorize'))
    _base_url = config.BASEURL

    _kj = get_jwks(config.PRIVATE_JWKS_PATH, config.KEYDEFS,
                   config.PUBLIC_JWKS_PATH)

    if args.insecure:
        _kj.verify_ssl = False
        _verify_ssl = False
    else:
        _verify_ssl = True

    rph = RPHandler(base_url=_base_url,
                    hash_seed="BabyHoldOn",
                    keyjar=_kj,
                    jwks_path=config.PUBLIC_JWKS_PATH,
                    client_configs=config.CLIENTS,
                    services=config.SERVICES,
                    verify_ssl=_verify_ssl)

    cherrypy.tree.mount(cprp.Consumer(rph, 'html'), '/', provider_config)

    # If HTTPS
    if args.tls:
        cherrypy.server.ssl_certificate = config.SERVER_CERT
        cherrypy.server.ssl_private_key = config.SERVER_KEY
        if config.CA_BUNDLE:
            cherrypy.server.ssl_certificate_chain = config.CA_BUNDLE

    cherrypy.engine.start()
    cherrypy.engine.block()
 def rphandler_setup(self):
     self.rph = RPHandler(base_url=BASEURL, client_configs=CLIENT_CONFIG)
Exemple #18
0
        _base_url = "{}:{}".format(config.BASEURL, args.port)
    else:
        _base_url = config.BASEURL

    _kj = init_key_jar(private_path=config.PRIVATE_JWKS_PATH,
                       key_defs=config.KEYDEFS,
                       public_path=config.PUBLIC_JWKS_PATH)

    if args.insecure:
        verify_ssl = False
    else:
        verify_ssl = True

    rph = RPHandler(base_url=_base_url, hash_seed="BabyDriver", keyjar=_kj,
                    jwks_path=config.PUBLIC_JWKS_PATH,
                    client_configs=config.CLIENTS, service_factory=factory,
                    services=config.SERVICES, client_cls=oidc.RP,
                    verify_ssl=verify_ssl)

    cherrypy.tree.mount(cprp.Consumer(rph, 'html'), '/', provider_config)

    # If HTTPS
    if args.tls:
        cherrypy.server.ssl_certificate = config.SERVER_CERT
        cherrypy.server.ssl_private_key = config.SERVER_KEY
        if config.CA_BUNDLE:
            cherrypy.server.ssl_certificate_chain = config.CA_BUNDLE

    cherrypy.engine.start()
    cherrypy.engine.block()
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