Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to MSAL 1.27+'s TokenCache._find() #128

Merged
merged 1 commit into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.0b1" # Note: During/after release, copy this number to Dockerfile

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,<1.29', # MSAL Python 1.29+ may not have TokenCache._find()
'portalocker<3,>=1.4',

## We choose to NOT define a hard dependency on this.
Expand Down
36 changes: 16 additions & 20 deletions tests/test_agnostic_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,28 @@ 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)))
apps = [ # Multiple apps sharing same persistence
msal.ConfidentialClientApplication(
client_id, client_credential=client_secret,
token_cache=PersistedTokenCache(persistence)) for i in range(2)]
token1 = apps[0].acquire_token_for_client(scopes=desired_scopes)
assert token1["token_source"] == "identity_provider", "Initial token should come from IdP"
token2 = apps[1].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
Loading