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
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
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')