def create_account_linking(self, account_linking_config): self.account_linking = AccountLinking(account_linking_config, name="AccountLinking", base_url="https://satosa.example.com") self.account_linking.next = lambda ctx, data: data
class TestAccountLinking(): @pytest.fixture def internal_response(self): auth_info = AuthenticationInformation("auth_class_ref", "timestamp", "issuer") internal_response = InternalResponse(auth_info=auth_info) internal_response.user_id = "user1" return internal_response @pytest.fixture def account_linking_config(self, signing_key_path): return { "api_url": "http://account.example.com/api", "redirect_url": "http://account.example.com/redirect", "sign_key": signing_key_path, } @pytest.fixture(autouse=True) def create_account_linking(self, account_linking_config): self.account_linking = AccountLinking(account_linking_config, name="AccountLinking", base_url="https://satosa.example.com") self.account_linking.next = lambda ctx, data: data @responses.activate def test_existing_account_linking_with_known_known_uuid(self, account_linking_config, internal_response, context): uuid = "uuid" data = { "idp": internal_response.auth_info.issuer, "id": internal_response.user_id, "redirect_endpoint": self.account_linking.base_url + "/account_linking/handle_account_linking" } key = RSAKey(key=rsa_load(account_linking_config["sign_key"]), use="sig", alg="RS256") jws = JWS(json.dumps(data), alg=key.alg).sign_compact([key]) responses.add( responses.GET, "%s/get_id?jwt=%s" % (account_linking_config["api_url"], jws), status=200, body=uuid, content_type="text/html", match_querystring=True ) self.account_linking.process(context, internal_response) assert internal_response.user_id == uuid def test_full_flow(self, account_linking_config, internal_response, context): ticket = "ticket" with responses.RequestsMock() as rsps: rsps.add( responses.GET, "%s/get_id" % account_linking_config["api_url"], status=404, body=ticket, content_type="text/html" ) result = self.account_linking.process(context, internal_response) assert isinstance(result, Redirect) assert result.message.startswith(account_linking_config["redirect_url"]) data = { "idp": internal_response.auth_info.issuer, "id": internal_response.user_id, "redirect_endpoint": self.account_linking.base_url + "/account_linking/handle_account_linking" } key = RSAKey(key=rsa_load(account_linking_config["sign_key"]), use="sig", alg="RS256") jws = JWS(json.dumps(data), alg=key.alg).sign_compact([key]) uuid = "uuid" with responses.RequestsMock() as rsps: # account is linked, 200 OK rsps.add( responses.GET, "%s/get_id?jwt=%s" % (account_linking_config["api_url"], jws), status=200, body=uuid, content_type="text/html", match_querystring=True ) internal_response = self.account_linking._handle_al_response(context) assert internal_response.user_id == uuid @responses.activate def test_account_linking_failed(self, account_linking_config, internal_response, context): ticket = "ticket" responses.add( responses.GET, "%s/get_id" % account_linking_config["api_url"], status=404, body=ticket, content_type="text/html" ) result = self.account_linking.process(context, internal_response) assert isinstance(result, Redirect) assert result.message.startswith(account_linking_config["redirect_url"]) # account linking endpoint still does not return an id with pytest.raises(SATOSAAuthenticationError): self.account_linking._handle_al_response(context) @responses.activate def test_manage_al_handle_failed_connection(self, account_linking_config, internal_response, context): exception = requests.ConnectionError("No connection") responses.add(responses.GET, "%s/get_id" % account_linking_config["api_url"], body=exception) with pytest.raises(SATOSAAuthenticationError): self.account_linking.process(context, internal_response) @pytest.mark.parametrize("http_status", [ 400, 401, 500 ]) @responses.activate def test_manage_al_handle_bad_response_status(self, http_status, account_linking_config, internal_response, context): responses.add(responses.GET, "%s/get_id" % account_linking_config["api_url"], status=http_status) with pytest.raises(SATOSAAuthenticationError): self.account_linking.process(context, internal_response) def test_register_endpoints(self): url_map = self.account_linking.register_endpoints() assert len(url_map) == 1 regex, func = url_map[0] assert re.compile(regex).match("account_linking/handle_account_linking") assert func == self.account_linking._handle_al_response