Skip to content

Commit

Permalink
Switch to MSAL 1.27+'s TokenCache._find()
Browse files Browse the repository at this point in the history
  • Loading branch information
rayluo committed Apr 11, 2024
1 parent a10d092 commit 6928c16
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 25 deletions.
4 changes: 3 additions & 1 deletion docker_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ docker build -t $IMAGE_NAME - < Dockerfile
echo "==== Integration Test for Persistence on Linux (libsecret) ===="
echo "After seeing the bash prompt, run the following to test encryption on Linux:"
echo " pip install -e ."
echo " pytest"
echo " pytest -s tests/chosen_test_file.py"
echo "Note that you probably need to set up ENV VAR for the test cases to run"
docker run --rm -it \
--privileged \
--env-file .env \
-w /home -v $PWD:/home \
$IMAGE_NAME \
$1
Expand Down
2 changes: 1 addition & 1 deletion msal_extensions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Provides auxiliary functionality to the `msal` package."""
__version__ = "1.1.0"
__version__ = "1.2.0a1"

from .persistence import (
FilePersistence,
Expand Down
4 changes: 2 additions & 2 deletions msal_extensions/token_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def modify(self, credential_type, old_entry, new_key_value_pairs=None):
self._persistence.save(self.serialize())
self._last_sync = time.time()

def find(self, credential_type, **kwargs): # pylint: disable=arguments-differ
def _find(self, credential_type, **kwargs): # pylint: disable=arguments-differ
# Use optimistic locking rather than CrossPlatLock(self._lock_location)
retry = 3
for attempt in range(1, retry + 1):
Expand All @@ -83,6 +83,6 @@ def find(self, credential_type, **kwargs): # pylint: disable=arguments-differ
else:
raise # End of retry. Re-raise the exception as-is.
else: # If reload encountered no error, the data is considered intact
return super(PersistedTokenCache, self).find(credential_type, **kwargs)
return super(PersistedTokenCache, self)._find(credential_type, **kwargs)
return [] # Not really reachable here. Just to keep pylint happy.

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
package_data={'': ['LICENSE']},
python_requires=">=3.7",
install_requires=[
'msal>=0.4.1,<2.0.0',
'msal>=1.27,<2.0.0',
'portalocker<3,>=1.4',

## We choose to NOT define a hard dependency on this.
Expand Down
39 changes: 19 additions & 20 deletions tests/test_agnostic_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,31 @@ def temp_location():
yield os.path.join(test_folder, 'token_cache.bin')
shutil.rmtree(test_folder, ignore_errors=True)


def _test_token_cache_roundtrip(cache):
def _test_token_cache_roundtrip(persistence):
client_id = os.getenv('AZURE_CLIENT_ID')
client_secret = os.getenv('AZURE_CLIENT_SECRET')
if not (client_id and client_secret):
pytest.skip('no credentials present to test TokenCache round-trip with.')

app = msal.ConfidentialClientApplication(
client_id=client_id,
client_credential=client_secret,
token_cache=cache)
desired_scopes = ['https://graph.microsoft.com/.default']
token1 = app.acquire_token_for_client(scopes=desired_scopes)
os.utime( # Mock having another process update the cache
cache._persistence.get_location(), None)
token2 = app.acquire_token_silent(scopes=desired_scopes, account=None)
assert token1['access_token'] == token2['access_token']

def test_file_token_cache_roundtrip(temp_location):
_test_token_cache_roundtrip(PersistedTokenCache(FilePersistence(temp_location)))

def test_current_platform_cache_roundtrip_with_persistence_builder(temp_location):
_test_token_cache_roundtrip(PersistedTokenCache(build_encrypted_persistence(temp_location)))

def test_persisted_token_cache(temp_location):
_test_token_cache_roundtrip(PersistedTokenCache(FilePersistence(temp_location)))
# Two apps served by same persistence
app1 = msal.ConfidentialClientApplication(
client_id, client_credential=client_secret,
token_cache=PersistedTokenCache(persistence))
app2 = msal.ConfidentialClientApplication(
client_id, client_credential=client_secret,
token_cache=PersistedTokenCache(persistence))
token1 = app1.acquire_token_for_client(scopes=desired_scopes)
assert token1["token_source"] == "identity_provider", "Initial token should come from IdP"
token2 = app2.acquire_token_for_client(scopes=desired_scopes) # Hit token cache in MSAL 1.23+
assert token2["token_source"] == "cache", "App2 should hit cache written by app1"
assert token1['access_token'] == token2['access_token'], "Cache should hit"

def test_token_cache_roundtrip_with_persistence_biulder(temp_location):
_test_token_cache_roundtrip(build_encrypted_persistence(temp_location))

def test_token_cache_roundtrip_with_file_persistence(temp_location):
_test_token_cache_roundtrip(FilePersistence(temp_location))

def test_file_not_found_error_is_not_raised():
persistence = FilePersistence('non_existing_file')
Expand Down
1 change: 1 addition & 0 deletions tests/test_macos_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def test_osx_token_cache_roundtrip():
token_cache=subject)
desired_scopes = ['https://graph.microsoft.com/.default']
token1 = app.acquire_token_for_client(scopes=desired_scopes)
# TODO: Modify this to same approach in test_agnostic_backend.py
os.utime(cache_file, None) # Mock having another process update the cache.
token2 = app.acquire_token_silent(scopes=desired_scopes, account=None)
assert token1['access_token'] == token2['access_token']
Expand Down
1 change: 1 addition & 0 deletions tests/test_windows_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def test_windows_token_cache_roundtrip():
token_cache=subject)
desired_scopes = ['https://graph.microsoft.com/.default']
token1 = app.acquire_token_for_client(scopes=desired_scopes)
# TODO: Modify this to same approach in test_agnostic_backend.py
os.utime(cache_file, None) # Mock having another process update the cache.
token2 = app.acquire_token_silent(scopes=desired_scopes, account=None)
assert token1['access_token'] == token2['access_token']
Expand Down

0 comments on commit 6928c16

Please sign in to comment.