diff --git a/msal/application.py b/msal/application.py index a17d3594..66d9b430 100644 --- a/msal/application.py +++ b/msal/application.py @@ -633,8 +633,9 @@ def _acquire_token_silent_by_finding_rt_belongs_to_me_or_my_family( **kwargs) if at and "error" not in at: return at + last_resp = None if app_metadata.get("family_id"): # Meaning this app belongs to this family - at = self._acquire_token_silent_by_finding_specific_refresh_token( + last_resp = at = self._acquire_token_silent_by_finding_specific_refresh_token( authority, scopes, dict(query, family_id=app_metadata["family_id"]), **kwargs) if at and "error" not in at: @@ -642,7 +643,8 @@ def _acquire_token_silent_by_finding_rt_belongs_to_me_or_my_family( # Either this app is an orphan, so we will naturally use its own RT; # or all attempts above have failed, so we fall back to non-foci behavior. return self._acquire_token_silent_by_finding_specific_refresh_token( - authority, scopes, dict(query, client_id=self.client_id), **kwargs) + authority, scopes, dict(query, client_id=self.client_id), + **kwargs) or last_resp def _get_app_metadata(self, environment): apps = self.token_cache.find( # Use find(), rather than token_cache.get(...) diff --git a/tests/test_application.py b/tests/test_application.py index 39becd5a..65b36b34 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -176,6 +176,19 @@ def tester(url, data=None, **kwargs): # Will not test scenario of app leaving family. Per specs, it won't happen. + def test_preexisting_family_app_will_attempt_frt_and_return_error(self): + error_response = '{"error": "invalid_grant", "error_description": "xyz"}' + def tester(url, data=None, **kwargs): + self.assertEqual( + self.frt, data.get("refresh_token"), "Should attempt the FRT") + return MinimalResponse(status_code=400, text=error_response) + app = ClientApplication( + "preexisting_family_app", authority=self.authority_url, token_cache=self.cache) + resp = app._acquire_token_silent_by_finding_rt_belongs_to_me_or_my_family( + self.authority, self.scopes, self.account, post=tester) + logger.debug("%s.cache = %s", self.id(), self.cache.serialize()) + self.assertEqual(json.loads(error_response), resp, "Error raised will be returned") + def test_family_app_remove_account(self): logger.debug("%s.cache = %s", self.id(), self.cache.serialize()) app = ClientApplication(