Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-msal-extensions for
openSUSE:Factory checked in at 2024-02-11 15:45:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-msal-extensions (Old)
and /work/SRC/openSUSE:Factory/.python-msal-extensions.new.1815 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-msal-extensions"
Sun Feb 11 15:45:58 2024 rev:7 rq:1145585 version:1.1.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-msal-extensions/python-msal-extensions.changes
2023-05-08 17:24:56.632929313 +0200
+++
/work/SRC/openSUSE:Factory/.python-msal-extensions.new.1815/python-msal-extensions.changes
2024-02-11 15:45:59.515576272 +0100
@@ -1,0 +2,7 @@
+Fri Feb 9 15:46:13 UTC 2024 - John Paul Adrian Glaubitz
<[email protected]>
+
+- Update to version 1.1.0
+ + Support Python 3.12 by removing dependency on distutils (#120, #123)
+ + Dropping Python 2.7 (#122)
+
+-------------------------------------------------------------------
Old:
----
msal-extensions-1.0.0.tar.gz
New:
----
msal-extensions-1.1.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-msal-extensions.spec ++++++
--- /var/tmp/diff_new_pack.GRW6q0/_old 2024-02-11 15:46:00.083596695 +0100
+++ /var/tmp/diff_new_pack.GRW6q0/_new 2024-02-11 15:46:00.087596838 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-msal-extensions
#
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -21,7 +21,7 @@
%define skip_python2 1
%endif
Name: python-msal-extensions
-Version: 1.0.0
+Version: 1.1.0
Release: 0
Summary: Microsoft Authentication Library (MSAL) for Python Extensions
License: MIT
++++++ msal-extensions-1.0.0.tar.gz -> msal-extensions-1.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/PKG-INFO
new/msal-extensions-1.1.0/PKG-INFO
--- old/msal-extensions-1.0.0/PKG-INFO 2022-02-15 00:45:41.537072200 +0100
+++ new/msal-extensions-1.1.0/PKG-INFO 2023-12-09 05:12:27.996491700 +0100
@@ -1,14 +1,26 @@
Metadata-Version: 2.1
Name: msal-extensions
-Version: 1.0.0
+Version: 1.1.0
Summary: Microsoft Authentication Library extensions (MSAL EX) provides a
persistence API that can save your data on disk, encrypted on Windows, macOS
and Linux. Concurrent data access will be coordinated by a file lock mechanism.
-License: MIT
+License: MIT License
Project-URL: Changelog,
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases
-Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
Classifier: Development Status :: 5 - Production/Stable
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
+Requires-Dist: msal<2.0.0,>=0.4.1
+Requires-Dist: portalocker<3,>=1.0; platform_system != "Windows"
+Requires-Dist: portalocker<3,>=1.6; platform_system == "Windows"
+Requires-Dist: packaging
# Microsoft Authentication Extensions for Python
@@ -101,6 +113,12 @@
assert json.loads(persistence.load()) == data
```
+## Python version support policy
+
+Python versions which are 6 months older than their
+[end-of-life cycle defined by Python Software Foundation
(PSF)](https://devguide.python.org/versions/#versions)
+will not receive new feature updates from this library.
+
## Community Help and Support
@@ -129,5 +147,3 @@
## We value and adhere to the Microsoft Open Source Code of Conduct
This project has adopted the [Microsoft Open Source Code of
Conduct](https://opensource.microsoft.com/codeofconduct/). For more information
see the [Code of Conduct
FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact
[[email protected]](mailto:[email protected]) with any additional
questions or comments.
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/README.md
new/msal-extensions-1.1.0/README.md
--- old/msal-extensions-1.0.0/README.md 2022-02-15 00:45:30.000000000 +0100
+++ new/msal-extensions-1.1.0/README.md 2023-12-09 05:12:20.000000000 +0100
@@ -89,6 +89,12 @@
assert json.loads(persistence.load()) == data
```
+## Python version support policy
+
+Python versions which are 6 months older than their
+[end-of-life cycle defined by Python Software Foundation
(PSF)](https://devguide.python.org/versions/#versions)
+will not receive new feature updates from this library.
+
## Community Help and Support
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/msal_extensions/__init__.py
new/msal-extensions-1.1.0/msal_extensions/__init__.py
--- old/msal-extensions-1.0.0/msal_extensions/__init__.py 2022-02-15
00:45:30.000000000 +0100
+++ new/msal-extensions-1.1.0/msal_extensions/__init__.py 2023-12-09
05:12:20.000000000 +0100
@@ -1,5 +1,5 @@
"""Provides auxiliary functionality to the `msal` package."""
-__version__ = "1.0.0"
+__version__ = "1.1.0"
from .persistence import (
FilePersistence,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/msal_extensions/cache_lock.py
new/msal-extensions-1.1.0/msal_extensions/cache_lock.py
--- old/msal-extensions-1.0.0/msal_extensions/cache_lock.py 2022-02-15
00:45:30.000000000 +0100
+++ new/msal-extensions-1.1.0/msal_extensions/cache_lock.py 2023-12-09
05:12:20.000000000 +0100
@@ -4,9 +4,9 @@
import errno
import time
import logging
-from distutils.version import LooseVersion
import portalocker
+from packaging.version import Version
logger = logging.getLogger(__name__)
@@ -21,7 +21,7 @@
self._lockpath = lockfile_path
# Support for passing through arguments to the open syscall was added
in v1.4.0
open_kwargs = ({'buffering': 0}
- if LooseVersion(portalocker.__version__) >= LooseVersion("1.4.0")
else {})
+ if Version(portalocker.__version__) >= Version("1.4.0") else {})
self._lock = portalocker.Lock(
lockfile_path,
mode='wb+',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/msal_extensions/persistence.py
new/msal-extensions-1.1.0/msal_extensions/persistence.py
--- old/msal-extensions-1.0.0/msal_extensions/persistence.py 2022-02-15
00:45:30.000000000 +0100
+++ new/msal-extensions-1.1.0/msal_extensions/persistence.py 2023-12-09
05:12:20.000000000 +0100
@@ -210,7 +210,7 @@
except OSError as exception:
raise PersistenceEncryptionError(
err_no=getattr(exception, "winerror", None), # Exists in
Python 3 on Windows
- message="Encryption failed: {}. Consider disable
encryption.".format(exception),
+ message="Encryption failed: {} Consider disable
encryption.".format(exception),
)
with os.fdopen(_open(self._location), 'wb+') as handle:
handle.write(data)
@@ -237,7 +237,7 @@
except OSError as exception:
raise PersistenceDecryptionError(
err_no=getattr(exception, "winerror", None), # Exists in
Python 3 on Windows
- message="Decryption failed: {}. "
+ message="Decryption failed: {} "
"App developer may consider this guidance: "
"https://github.com/AzureAD/microsoft-authentication-extensions-for-python/wiki/PersistenceDecryptionError"
# pylint: disable=line-too-long
.format(exception),
@@ -342,4 +342,3 @@
# with a FilePersistence to achieve
#
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/issues/12
# But this idea is not pursued at this time.
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/msal_extensions/windows.py
new/msal-extensions-1.1.0/msal_extensions/windows.py
--- old/msal-extensions-1.0.0/msal_extensions/windows.py 2022-02-15
00:45:30.000000000 +0100
+++ new/msal-extensions-1.1.0/msal_extensions/windows.py 2023-12-09
05:12:20.000000000 +0100
@@ -46,7 +46,7 @@
"The computer must be trusted for delegation and "
"the current user account must be configured to allow delegation. "
"See also
https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/enable-computer-and-user-accounts-to-be-trusted-for-delegation",
- 13: "The data is invalid",
+ 13: "The data is invalid.",
}
# This code is modeled from a StackOverflow question, which can be found here:
@@ -91,7 +91,7 @@
_LOCAL_FREE(result.pbData)
err_code = _GET_LAST_ERROR()
- raise OSError(None, _err_description.get(err_code), None, err_code)
+ raise OSError(None, _err_description.get(err_code, ''), None, err_code)
def unprotect(self, cipher_text):
# type: (bytes) -> str
@@ -120,4 +120,4 @@
finally:
_LOCAL_FREE(result.pbData)
err_code = _GET_LAST_ERROR()
- raise OSError(None, _err_description.get(err_code), None, err_code)
+ raise OSError(None, _err_description.get(err_code, ''), None, err_code)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/msal-extensions-1.0.0/msal_extensions.egg-info/PKG-INFO
new/msal-extensions-1.1.0/msal_extensions.egg-info/PKG-INFO
--- old/msal-extensions-1.0.0/msal_extensions.egg-info/PKG-INFO 2022-02-15
00:45:41.000000000 +0100
+++ new/msal-extensions-1.1.0/msal_extensions.egg-info/PKG-INFO 2023-12-09
05:12:27.000000000 +0100
@@ -1,14 +1,26 @@
Metadata-Version: 2.1
Name: msal-extensions
-Version: 1.0.0
+Version: 1.1.0
Summary: Microsoft Authentication Library extensions (MSAL EX) provides a
persistence API that can save your data on disk, encrypted on Windows, macOS
and Linux. Concurrent data access will be coordinated by a file lock mechanism.
-License: MIT
+License: MIT License
Project-URL: Changelog,
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases
-Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
Classifier: Development Status :: 5 - Production/Stable
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
+Requires-Dist: msal<2.0.0,>=0.4.1
+Requires-Dist: portalocker<3,>=1.0; platform_system != "Windows"
+Requires-Dist: portalocker<3,>=1.6; platform_system == "Windows"
+Requires-Dist: packaging
# Microsoft Authentication Extensions for Python
@@ -101,6 +113,12 @@
assert json.loads(persistence.load()) == data
```
+## Python version support policy
+
+Python versions which are 6 months older than their
+[end-of-life cycle defined by Python Software Foundation
(PSF)](https://devguide.python.org/versions/#versions)
+will not receive new feature updates from this library.
+
## Community Help and Support
@@ -129,5 +147,3 @@
## We value and adhere to the Microsoft Open Source Code of Conduct
This project has adopted the [Microsoft Open Source Code of
Conduct](https://opensource.microsoft.com/codeofconduct/). For more information
see the [Code of Conduct
FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact
[[email protected]](mailto:[email protected]) with any additional
questions or comments.
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/msal-extensions-1.0.0/msal_extensions.egg-info/SOURCES.txt
new/msal-extensions-1.1.0/msal_extensions.egg-info/SOURCES.txt
--- old/msal-extensions-1.0.0/msal_extensions.egg-info/SOURCES.txt
2022-02-15 00:45:41.000000000 +0100
+++ new/msal-extensions-1.1.0/msal_extensions.egg-info/SOURCES.txt
2023-12-09 05:12:27.000000000 +0100
@@ -13,4 +13,10 @@
msal_extensions.egg-info/SOURCES.txt
msal_extensions.egg-info/dependency_links.txt
msal_extensions.egg-info/requires.txt
-msal_extensions.egg-info/top_level.txt
\ No newline at end of file
+msal_extensions.egg-info/top_level.txt
+tests/test_agnostic_backend.py
+tests/test_cache_lock_file_perf.py
+tests/test_crossplatlock.py
+tests/test_macos_backend.py
+tests/test_persistence.py
+tests/test_windows_backend.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/msal-extensions-1.0.0/msal_extensions.egg-info/requires.txt
new/msal-extensions-1.1.0/msal_extensions.egg-info/requires.txt
--- old/msal-extensions-1.0.0/msal_extensions.egg-info/requires.txt
2022-02-15 00:45:41.000000000 +0100
+++ new/msal-extensions-1.1.0/msal_extensions.egg-info/requires.txt
2023-12-09 05:12:27.000000000 +0100
@@ -1,16 +1,8 @@
msal<2.0.0,>=0.4.1
+packaging
-[:python_version < "3.0"]
-pathlib2
-
-[:python_version == "2.7" and platform_system != "Windows"]
-portalocker<2,>=1.0
-
-[:python_version == "2.7" and platform_system == "Windows"]
-portalocker<2,>=1.6
-
-[:python_version >= "3.5" and platform_system != "Windows"]
+[:platform_system != "Windows"]
portalocker<3,>=1.0
-[:python_version >= "3.5" and platform_system == "Windows"]
+[:platform_system == "Windows"]
portalocker<3,>=1.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/setup.cfg
new/msal-extensions-1.1.0/setup.cfg
--- old/msal-extensions-1.0.0/setup.cfg 2022-02-15 00:45:41.537072200 +0100
+++ new/msal-extensions-1.1.0/setup.cfg 2023-12-09 05:12:28.000491600 +0100
@@ -1,12 +1,20 @@
[bdist_wheel]
-universal = 1
+universal = 0
[metadata]
-license = MIT
+license = MIT License
project_urls = Changelog =
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases
classifiers =
License :: OSI Approved :: MIT License
Development Status :: 5 - Production/Stable
+ Programming Language :: Python :: 3 :: Only
+ Programming Language :: Python :: 3
+ Programming Language :: Python :: 3.7
+ Programming Language :: Python :: 3.8
+ Programming Language :: Python :: 3.9
+ Programming Language :: Python :: 3.10
+ Programming Language :: Python :: 3.11
+ Programming Language :: Python :: 3.12
description = Microsoft Authentication Library extensions (MSAL EX) provides a
persistence API that can save your data on disk, encrypted on Windows, macOS
and Linux. Concurrent data access will be coordinated by a file lock mechanism.
[egg_info]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/setup.py
new/msal-extensions-1.1.0/setup.py
--- old/msal-extensions-1.0.0/setup.py 2022-02-15 00:45:30.000000000 +0100
+++ new/msal-extensions-1.1.0/setup.py 2023-12-09 05:12:20.000000000 +0100
@@ -20,22 +20,20 @@
long_description=long_description,
long_description_content_type="text/markdown",
package_data={'': ['LICENSE']},
+ python_requires=">=3.7",
install_requires=[
'msal>=0.4.1,<2.0.0',
- # In order to implement these requirements:
- # Lowerbound = (1.6 if playform_system == 'Windows' else 1.0)
- # Upperbound < (3 if python_version >= '3.5' else 2)
- # The following 4 lines use the `and` syntax defined here:
- # https://www.python.org/dev/peps/pep-0508/#grammar
- "portalocker<3,>=1.0;python_version>='3.5' and
platform_system!='Windows'",
- "portalocker<2,>=1.0;python_version=='2.7' and
platform_system!='Windows'",
- "portalocker<3,>=1.6;python_version>='3.5' and
platform_system=='Windows'",
- "portalocker<2,>=1.6;python_version=='2.7' and
platform_system=='Windows'",
+ "portalocker<3,>=1.0;platform_system!='Windows'",
+ "portalocker<3,>=1.6;platform_system=='Windows'",
- "pathlib2;python_version<'3.0'",
## We choose to NOT define a hard dependency on this.
# "pygobject>=3,<4;platform_system=='Linux'",
+
+ # Packaging package uses YY.N versioning so we have no upperbound to
pin.
+ # Neither do we need lowerbound because its `Version` API existed
since its first release
+ # https://github.com/pypa/packaging/blame/14.0/packaging/version.py
+ 'packaging',
],
tests_require=['pytest'],
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/tests/test_agnostic_backend.py
new/msal-extensions-1.1.0/tests/test_agnostic_backend.py
--- old/msal-extensions-1.0.0/tests/test_agnostic_backend.py 1970-01-01
01:00:00.000000000 +0100
+++ new/msal-extensions-1.1.0/tests/test_agnostic_backend.py 2023-12-09
05:12:20.000000000 +0100
@@ -0,0 +1,49 @@
+import os
+import shutil
+import tempfile
+import sys
+
+import msal
+import pytest
+
+from msal_extensions import *
+
+
[email protected]
+def temp_location():
+ test_folder = tempfile.mkdtemp(prefix="test_token_cache_roundtrip")
+ yield os.path.join(test_folder, 'token_cache.bin')
+ shutil.rmtree(test_folder, ignore_errors=True)
+
+
+def _test_token_cache_roundtrip(cache):
+ 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)))
+
+def test_file_not_found_error_is_not_raised():
+ persistence = FilePersistence('non_existing_file')
+ cache = PersistedTokenCache(persistence)
+ # An exception raised here will fail the test case as it is supposed to be
a NO-OP
+ cache.find('')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/msal-extensions-1.0.0/tests/test_cache_lock_file_perf.py
new/msal-extensions-1.1.0/tests/test_cache_lock_file_perf.py
--- old/msal-extensions-1.0.0/tests/test_cache_lock_file_perf.py
1970-01-01 01:00:00.000000000 +0100
+++ new/msal-extensions-1.1.0/tests/test_cache_lock_file_perf.py
2023-12-09 05:12:20.000000000 +0100
@@ -0,0 +1,75 @@
+import multiprocessing
+import os
+import shutil
+import tempfile
+
+import pytest
+
+from cache_file_generator import _acquire_lock_and_write_to_cache
+
+
[email protected]
+def temp_location():
+ test_folder = tempfile.mkdtemp(prefix="test_persistence_roundtrip")
+ yield os.path.join(test_folder, 'persistence.bin')
+ shutil.rmtree(test_folder, ignore_errors=True)
+
+
+def _validate_result_in_cache(cache_location):
+ with open(cache_location) as handle:
+ data = handle.read()
+ prev_process_id = None
+ count = 0
+ for line in data.split("\n"):
+ if line:
+ count += 1
+ tag, process_id = line.split(" ")
+ if prev_process_id is not None:
+ assert process_id == prev_process_id, "Process overlap found"
+ assert tag == '>', "Process overlap_found"
+ prev_process_id = None
+ else:
+ assert tag == '<', "Opening bracket not found"
+ prev_process_id = process_id
+ return count
+
+
+def _run_multiple_processes(no_of_processes, cache_location, sleep_interval):
+ open(cache_location, "w+")
+ processes = []
+ for i in range(no_of_processes):
+ process = multiprocessing.Process(
+ target=_acquire_lock_and_write_to_cache,
+ args=(cache_location, sleep_interval))
+ processes.append(process)
+
+ for process in processes:
+ process.start()
+
+ for process in processes:
+ process.join()
+
+
+def test_lock_for_normal_workload(temp_location):
+ num_of_processes = 4
+ sleep_interval = 0.1
+ _run_multiple_processes(num_of_processes, temp_location, sleep_interval)
+ count = _validate_result_in_cache(temp_location)
+ assert count == num_of_processes * 2, "Should not observe starvation"
+
+
+def test_lock_for_high_workload(temp_location):
+ num_of_processes = 80
+ sleep_interval = 0
+ _run_multiple_processes(num_of_processes, temp_location, sleep_interval)
+ count = _validate_result_in_cache(temp_location)
+ assert count <= num_of_processes * 2, "Starvation or not, we should not
observe garbled payload"
+
+
+def test_lock_for_timeout(temp_location):
+ num_of_processes = 30
+ sleep_interval = 1
+ _run_multiple_processes(num_of_processes, temp_location, sleep_interval)
+ count = _validate_result_in_cache(temp_location)
+ assert count < num_of_processes * 2, "Should observe starvation"
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/tests/test_crossplatlock.py
new/msal-extensions-1.1.0/tests/test_crossplatlock.py
--- old/msal-extensions-1.0.0/tests/test_crossplatlock.py 1970-01-01
01:00:00.000000000 +0100
+++ new/msal-extensions-1.1.0/tests/test_crossplatlock.py 2023-12-09
05:12:20.000000000 +0100
@@ -0,0 +1,18 @@
+import pytest
+from msal_extensions.cache_lock import CrossPlatLock
+
+
+def test_ensure_file_deleted():
+ lockfile = './test_lock_1.txt'
+
+ try:
+ FileNotFoundError
+ except NameError:
+ FileNotFoundError = IOError
+
+ with CrossPlatLock(lockfile):
+ pass
+
+ with pytest.raises(FileNotFoundError):
+ with open(lockfile):
+ pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/tests/test_macos_backend.py
new/msal-extensions-1.1.0/tests/test_macos_backend.py
--- old/msal-extensions-1.0.0/tests/test_macos_backend.py 1970-01-01
01:00:00.000000000 +0100
+++ new/msal-extensions-1.1.0/tests/test_macos_backend.py 2023-12-09
05:12:20.000000000 +0100
@@ -0,0 +1,46 @@
+import sys
+import os
+import shutil
+import tempfile
+import pytest
+import uuid
+import msal
+
+if not sys.platform.startswith('darwin'):
+ pytest.skip('skipping MacOS-only tests', allow_module_level=True)
+else:
+ from msal_extensions.osx import Keychain
+ from msal_extensions.token_cache import PersistedTokenCache
+ from msal_extensions.persistence import KeychainPersistence
+
+
+def test_keychain_roundtrip():
+ with Keychain() as subject:
+ location, account = "msal_extension_test1", "test_account1"
+ want = uuid.uuid4().hex
+ subject.set_generic_password(location, account, want)
+ got = subject.get_generic_password(location, account)
+ assert got == want
+
+
+def test_osx_token_cache_roundtrip():
+ 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 PersistedTokenCache
round-trip with.')
+
+ test_folder =
tempfile.mkdtemp(prefix="msal_extension_test_osx_token_cache_roundtrip")
+ cache_file = os.path.join(test_folder, 'msal.cache')
+ try:
+ subject = PersistedTokenCache(KeychainPersistence(cache_file))
+ app = msal.ConfidentialClientApplication(
+ client_id=client_id,
+ client_credential=client_secret,
+ token_cache=subject)
+ desired_scopes = ['https://graph.microsoft.com/.default']
+ token1 = app.acquire_token_for_client(scopes=desired_scopes)
+ 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']
+ finally:
+ shutil.rmtree(test_folder, ignore_errors=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/tests/test_persistence.py
new/msal-extensions-1.1.0/tests/test_persistence.py
--- old/msal-extensions-1.0.0/tests/test_persistence.py 1970-01-01
01:00:00.000000000 +0100
+++ new/msal-extensions-1.1.0/tests/test_persistence.py 2023-12-09
05:12:20.000000000 +0100
@@ -0,0 +1,96 @@
+import os
+import sys
+import shutil
+import tempfile
+import logging
+
+import pytest
+
+from msal_extensions.persistence import *
+
+
+def _is_env_var_defined(env_var):
+ return bool( # (WTF) What-The-Finding:
+ # The bool(...) is necessary, otherwise skipif(...) would treat "true" as
+ # string conditions and then raise an undefined "true" exception.
+ # https://docs.pytest.org/en/latest/historical-notes.html#string-conditions
+ os.getenv(env_var))
+
+
+# Note: If you use tox, remember to pass them through via tox.ini
+#
https://tox.wiki/en/latest/example/basic.html#passing-down-environment-variables
+is_running_on_travis_ci = _is_env_var_defined("TRAVIS")
+is_running_on_github_ci = _is_env_var_defined("GITHUB_ACTIONS")
+
[email protected]
+def temp_location():
+ test_folder = tempfile.mkdtemp(prefix="test_persistence_roundtrip")
+ yield os.path.join(test_folder, 'persistence.bin')
+ shutil.rmtree(test_folder, ignore_errors=True)
+
+def _test_persistence_roundtrip(persistence):
+ payload = 'arbitrary content'
+ persistence.save(payload)
+ assert persistence.load() == payload
+
+def _test_nonexistent_persistence(persistence):
+ with pytest.raises(PersistenceNotFound):
+ persistence.load()
+ with pytest.raises(PersistenceNotFound):
+ persistence.time_last_modified()
+
+def test_file_persistence(temp_location):
+ _test_persistence_roundtrip(FilePersistence(temp_location))
+
+def test_nonexistent_file_persistence(temp_location):
+ _test_nonexistent_persistence(FilePersistence(temp_location))
+
[email protected](
+ is_running_on_travis_ci or not sys.platform.startswith('win'),
+ reason="Requires Windows Desktop")
+def test_file_persistence_with_data_protection(temp_location):
+ try:
+
_test_persistence_roundtrip(FilePersistenceWithDataProtection(temp_location))
+ except PersistenceDecryptionError:
+ if is_running_on_github_ci or is_running_on_travis_ci:
+ logging.warning("DPAPI tends to fail on Windows VM. Run this on
your desktop to double check.")
+ else:
+ raise
+
[email protected](
+ is_running_on_travis_ci or not sys.platform.startswith('win'),
+ reason="Requires Windows Desktop")
+def test_nonexistent_file_persistence_with_data_protection(temp_location):
+
_test_nonexistent_persistence(FilePersistenceWithDataProtection(temp_location))
+
[email protected](
+ not sys.platform.startswith('darwin'),
+ reason="Requires OSX. Whether running on TRAVIS CI does not seem to
matter.")
+def test_keychain_persistence(temp_location):
+ _test_persistence_roundtrip(KeychainPersistence(temp_location))
+
[email protected](
+ not sys.platform.startswith('darwin'),
+ reason="Requires OSX. Whether running on TRAVIS CI does not seem to
matter.")
+def test_nonexistent_keychain_persistence(temp_location):
+ random_service_name = random_account_name = str(id(temp_location))
+ _test_nonexistent_persistence(
+ KeychainPersistence(temp_location, random_service_name,
random_account_name))
+
[email protected](
+ is_running_on_travis_ci or not sys.platform.startswith('linux'),
+ reason="Requires Linux Desktop. Headless or SSH session won't work.")
+def test_libsecret_persistence(temp_location):
+ _test_persistence_roundtrip(LibsecretPersistence(temp_location))
+
[email protected](
+ is_running_on_travis_ci or not sys.platform.startswith('linux'),
+ reason="Requires Linux Desktop. Headless or SSH session won't work.")
+def test_nonexistent_libsecret_persistence(temp_location):
+ random_schema_name = random_value = str(id(temp_location))
+ _test_nonexistent_persistence(LibsecretPersistence(
+ temp_location,
+ random_schema_name,
+ {"my_attr_1": random_value, "my_attr_2": random_value},
+ ))
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-1.0.0/tests/test_windows_backend.py
new/msal-extensions-1.1.0/tests/test_windows_backend.py
--- old/msal-extensions-1.0.0/tests/test_windows_backend.py 1970-01-01
01:00:00.000000000 +0100
+++ new/msal-extensions-1.1.0/tests/test_windows_backend.py 2023-12-09
05:12:20.000000000 +0100
@@ -0,0 +1,106 @@
+import sys
+import os
+import errno
+import shutil
+import tempfile
+import pytest
+import uuid
+import msal
+
+if not sys.platform.startswith('win'):
+ pytest.skip('skipping windows-only tests', allow_module_level=True)
+else:
+ from msal_extensions.windows import WindowsDataProtectionAgent
+ from msal_extensions.token_cache import PersistedTokenCache
+ from msal_extensions.persistence import FilePersistenceWithDataProtection
+
+
+def test_dpapi_roundtrip_with_entropy():
+ subject_without_entropy = WindowsDataProtectionAgent()
+ subject_with_entropy = WindowsDataProtectionAgent(entropy=uuid.uuid4().hex)
+
+ test_cases = [
+ '',
+ 'lorem ipsum',
+ 'lorem-ipsum',
+ '<Python>',
+ uuid.uuid4().hex,
+ ]
+
+ try:
+ for tc in test_cases:
+ ciphered = subject_with_entropy.protect(tc)
+ assert ciphered != tc
+
+ got = subject_with_entropy.unprotect(ciphered)
+ assert got == tc
+
+ ciphered = subject_without_entropy.protect(tc)
+ assert ciphered != tc
+
+ got = subject_without_entropy.unprotect(ciphered)
+ assert got == tc
+ except OSError as exp:
+ if exp.errno == errno.EIO and os.getenv('TRAVIS_REPO_SLUG'):
+ pytest.skip('DPAPI tests are known to fail in TravisCI. This
effort tracked by '
+
'https://github.com/AzureAD/microsoft-authentication-extentions-for-python'
+ '/issues/21')
+
+
+def test_read_msal_cache_direct():
+ """
+ This loads and unprotects an MSAL cache directly, only using the
DataProtectionAgent.
+ """
+ localappdata_location = os.getenv('LOCALAPPDATA', os.path.expanduser('~'))
+ cache_locations = [
+ os.path.join(localappdata_location, '.IdentityService', 'msal.cache'),
# this is where it's supposed to be
+ os.path.join(localappdata_location, '.IdentityServices',
'msal.cache'), # There was a miscommunications about whether this was plural or
not.
+ os.path.join(localappdata_location, 'msal.cache'), # The earliest most
naive builds used this locations.
+ ]
+
+ found = False
+ for loc in cache_locations:
+ try:
+ with open(loc, mode='rb') as fh:
+ contents = fh.read()
+ found = True
+
+ break
+ except IOError as exp:
+ if exp.errno != errno.ENOENT:
+ raise exp
+
+ if not found:
+ pytest.skip('could not find the msal.cache file (try logging in
using MSAL)')
+
+ subject = WindowsDataProtectionAgent()
+ raw = subject.unprotect(contents)
+ assert raw != ""
+
+ cache = msal.SerializableTokenCache()
+ cache.deserialize(raw)
+ access_tokens = cache.find(msal.TokenCache.CredentialType.ACCESS_TOKEN)
+ assert len(access_tokens) > 0
+
+
+def test_windows_token_cache_roundtrip():
+ 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 PersistedTokenCache
round-trip with.')
+
+ test_folder =
tempfile.mkdtemp(prefix="msal_extension_test_windows_token_cache_roundtrip")
+ cache_file = os.path.join(test_folder, 'msal.cache')
+ try:
+ subject =
PersistedTokenCache(FilePersistenceWithDataProtection(cache_file))
+ app = msal.ConfidentialClientApplication(
+ client_id=client_id,
+ client_credential=client_secret,
+ token_cache=subject)
+ desired_scopes = ['https://graph.microsoft.com/.default']
+ token1 = app.acquire_token_for_client(scopes=desired_scopes)
+ 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']
+ finally:
+ shutil.rmtree(test_folder, ignore_errors=True)