Skip to content

Commit 9971053

Browse files
committed
get_accounts(username='CaseInsensitiveUserName')
1 parent 05d19b3 commit 9971053

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

msal/application.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -184,18 +184,29 @@ def acquire_token_by_authorization_code(
184184
data={"scope": decorate_scope(scopes, self.client_id)},
185185
)
186186

187-
def get_accounts(self):
188-
"""Returns a list of account objects that can later be used to find token.
187+
def get_accounts(self, username=None):
188+
"""Get a list of accounts which previously signed in, i.e. exists in cache.
189189
190-
Each account object is a dict containing a "username" field (among others)
191-
which can use to determine which account to use.
190+
An account can later be used in acquire_token_silent() to find its tokens.
191+
Each account is a dict. For now, we only document its "username" field.
192+
Your app can choose to display those information to end user,
193+
and allow them to choose one of them to proceed.
194+
195+
:param username:
196+
Filter accounts with this username only. Case insensitive.
192197
"""
193198
# The following implementation finds accounts only from saved accounts,
194199
# but does NOT correlate them with saved RTs. It probably won't matter,
195200
# because in MSAL universe, there are always Accounts and RTs together.
196-
return self.token_cache.find(
197-
self.token_cache.CredentialType.ACCOUNT,
198-
query={"environment": self.authority.instance})
201+
accounts = self.token_cache.find(
202+
self.token_cache.CredentialType.ACCOUNT,
203+
query={"environment": self.authority.instance})
204+
if username:
205+
# Federated account["username"] from AAD could contain mixed case
206+
lowercase_username = username.lower()
207+
accounts = [a for a in accounts
208+
if a["username"].lower() == lowercase_username]
209+
return accounts
199210

200211
def acquire_token_silent(
201212
self, scopes,

tests/test_application.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,21 @@ def assertLoosely(self, response, assertion=None,
3737

3838
def assertCacheWorks(self, result_from_wire):
3939
result = result_from_wire
40-
# Going to test acquire_token_silent(...) to locate an AT from cache
41-
# In practice, you may want to filter based on its "username" field
42-
accounts = self.app.get_accounts()
40+
# You can filter by predefined username, or let end user to choose one
41+
accounts = self.app.get_accounts(username=CONFIG.get("username"))
4342
self.assertNotEqual(0, len(accounts))
43+
account = accounts[0]
44+
# Going to test acquire_token_silent(...) to locate an AT from cache
4445
result_from_cache = self.app.acquire_token_silent(
45-
CONFIG["scope"], account=accounts[0])
46+
CONFIG["scope"], account=account)
4647
self.assertIsNotNone(result_from_cache)
4748
self.assertEqual(result['access_token'], result_from_cache['access_token'],
4849
"We should get a cached AT")
4950

5051
# Going to test acquire_token_silent(...) to obtain an AT by a RT from cache
5152
self.app.token_cache._cache["AccessToken"] = {} # A hacky way to clear ATs
5253
result_from_cache = self.app.acquire_token_silent(
53-
CONFIG["scope"], account=accounts[0])
54+
CONFIG["scope"], account=account)
5455
self.assertIsNotNone(result_from_cache,
5556
"We should get a result from acquire_token_silent(...) call")
5657
self.assertNotEqual(result['access_token'], result_from_cache['access_token'],

0 commit comments

Comments
 (0)