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 2022-04-26 20:15:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-msal-extensions (Old)
and /work/SRC/openSUSE:Factory/.python-msal-extensions.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-msal-extensions"
Tue Apr 26 20:15:48 2022 rev:5 rq:972847 version:1.0.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-msal-extensions/python-msal-extensions.changes
2022-01-04 19:37:55.977964862 +0100
+++
/work/SRC/openSUSE:Factory/.python-msal-extensions.new.1538/python-msal-extensions.changes
2022-04-26 20:17:45.336759745 +0200
@@ -1,0 +2,12 @@
+Tue Apr 26 10:44:50 UTC 2022 - John Paul Adrian Glaubitz
<[email protected]>
+
+- Update to version 1.0.0
+ + New: Add a new platform-independent build_encrypted_persistence() API.
(#87, #110)
+ + Remove: Old TokenCache API which has been deprecated for 2 years. (#110)
+ + Enhancement: Make all platform-dependent parameters optional (#103)
+ + Enhancement: Provide PersistenceEncryptError and PersistenceDecryptError,
+ currently raised when encryption on Windows fails. (#108)
+ + Enhancement: The data file will be created with 600 permission when
+ running in Unix-like systems. (#107)
+
+-------------------------------------------------------------------
Old:
----
msal-extensions-0.3.1.tar.gz
New:
----
msal-extensions-1.0.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-msal-extensions.spec ++++++
--- /var/tmp/diff_new_pack.thAajI/_old 2022-04-26 20:17:45.756760253 +0200
+++ /var/tmp/diff_new_pack.thAajI/_new 2022-04-26 20:17:45.760760258 +0200
@@ -21,7 +21,7 @@
%define skip_python2 1
%endif
Name: python-msal-extensions
-Version: 0.3.1
+Version: 1.0.0
Release: 0
Summary: Microsoft Authentication Library (MSAL) for Python Extensions
License: MIT
++++++ msal-extensions-0.3.1.tar.gz -> msal-extensions-1.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-0.3.1/PKG-INFO
new/msal-extensions-1.0.0/PKG-INFO
--- old/msal-extensions-0.3.1/PKG-INFO 2021-12-13 05:46:55.792970000 +0100
+++ new/msal-extensions-1.0.0/PKG-INFO 2022-02-15 00:45:41.537072200 +0100
@@ -1,24 +1,23 @@
Metadata-Version: 2.1
Name: msal-extensions
-Version: 0.3.1
-Summary: UNKNOWN
-Home-page: UNKNOWN
+Version: 1.0.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
Project-URL: Changelog,
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases
Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
Description-Content-Type: text/markdown
License-File: LICENSE
# Microsoft Authentication Extensions for Python
-The Microsoft Authentication Extensions for Python offers secure mechanisms
for client applications to perform cross-platform token cache serialization and
persistence. It gives additional support to the [Microsoft Authentication
Library for Python
(MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-python).
+The Microsoft Authentication Extensions for Python offers secure mechanisms
for client applications to perform cross-platform token cache serialization and
persistence. It gives additional support to the [Microsoft Authentication
Library for Python
(MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-python).
MSAL Python supports an in-memory cache by default and provides the
[SerializableTokenCache](https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache)
to perform cache serialization. You can read more about this in the MSAL
Python
[documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-python-token-cache-serialization).
Developers are required to implement their own cache persistance across
multiple platforms and Microsoft Authentication Extensions makes this simpler.
-The supported platforms are Windows, Mac and Linux.
+The supported platforms are Windows, Mac and Linux.
- Windows -
[DPAPI](https://docs.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection)
is used for encryption.
- MAC - The MAC KeyChain is used.
- Linux - [LibSecret](https://wiki.gnome.org/Projects/Libsecret) is used for
encryption.
@@ -41,7 +40,9 @@
## Usage
-The Microsoft Authentication Extensions library provides the
`PersistedTokenCache` which accepts a platform-dependent persistence instance.
This token cache can then be used to instantiate the `PublicClientApplication`
in MSAL Python.
+### Creating an encrypted token cache file to be used by MSAL
+
+The Microsoft Authentication Extensions library provides the
`PersistedTokenCache` which accepts a platform-dependent persistence instance.
This token cache can then be used to instantiate the `PublicClientApplication`
in MSAL Python.
The token cache includes a file lock, and auto-reload behavior under the hood.
@@ -52,24 +53,16 @@
```python
def build_persistence(location, fallback_to_plaintext=False):
"""Build a suitable persistence instance based your current OS"""
- if sys.platform.startswith('win'):
- return FilePersistenceWithDataProtection(location)
- if sys.platform.startswith('darwin'):
- return KeychainPersistence(location, "my_service_name",
"my_account_name")
- if sys.platform.startswith('linux'):
- try:
- return LibsecretPersistence(
- location,
- schema_name="my_schema_name",
- attributes={"my_attr1": "foo", "my_attr2": "bar"},
- )
- except: # pylint: disable=bare-except
- if not fallback_to_plaintext:
- raise
- logging.exception("Encryption unavailable. Opting in to plain
text.")
- return FilePersistence(location)
+ try:
+ return build_encrypted_persistence(location)
+ except:
+ if not fallback_to_plaintext:
+ raise
+ logging.warning("Encryption unavailable. Opting in to plain text.")
+ return FilePersistence(location)
persistence = build_persistence("token_cache.bin")
+print("Type of persistence: {}".format(persistence.__class__.__name__))
print("Is this persistence encrypted?", persistence.is_encrypted)
cache = PersistedTokenCache(persistence)
@@ -79,6 +72,36 @@
app = msal.PublicClientApplication("my_client_id", token_cache=cache)
```
+### Creating an encrypted persistence file to store your own data
+
+Here is an example of this pattern for multiple platforms (taken from the
complete [sample
here](https://github.com/AzureAD/microsoft-authentication-extensions-for-python/blob/dev/sample/persistence_sample.py)):
+
+```python
+def build_persistence(location, fallback_to_plaintext=False):
+ """Build a suitable persistence instance based your current OS"""
+ try:
+ return build_encrypted_persistence(location)
+ except: # pylint: disable=bare-except
+ if not fallback_to_plaintext:
+ raise
+ logging.warning("Encryption unavailable. Opting in to plain text.")
+ return FilePersistence(location)
+
+persistence = build_persistence("storage.bin", fallback_to_plaintext=False)
+print("Type of persistence: {}".format(persistence.__class__.__name__))
+print("Is this persistence encrypted?", persistence.is_encrypted)
+
+data = { # It can be anything, here we demonstrate an arbitrary json object
+ "foo": "hello world",
+ "bar": "",
+ "service_principle_1": "blah blah...",
+ }
+
+persistence.save(json.dumps(data))
+assert json.loads(persistence.load()) == data
+```
+
+
## Community Help and Support
We leverage Stack Overflow to work with the community on supporting Azure
Active Directory and its SDKs, including this one!
@@ -107,3 +130,4 @@
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-0.3.1/README.md
new/msal-extensions-1.0.0/README.md
--- old/msal-extensions-0.3.1/README.md 2021-12-13 05:46:45.000000000 +0100
+++ new/msal-extensions-1.0.0/README.md 2022-02-15 00:45:30.000000000 +0100
@@ -1,11 +1,11 @@
# Microsoft Authentication Extensions for Python
-The Microsoft Authentication Extensions for Python offers secure mechanisms
for client applications to perform cross-platform token cache serialization and
persistence. It gives additional support to the [Microsoft Authentication
Library for Python
(MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-python).
+The Microsoft Authentication Extensions for Python offers secure mechanisms
for client applications to perform cross-platform token cache serialization and
persistence. It gives additional support to the [Microsoft Authentication
Library for Python
(MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-python).
MSAL Python supports an in-memory cache by default and provides the
[SerializableTokenCache](https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache)
to perform cache serialization. You can read more about this in the MSAL
Python
[documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-python-token-cache-serialization).
Developers are required to implement their own cache persistance across
multiple platforms and Microsoft Authentication Extensions makes this simpler.
-The supported platforms are Windows, Mac and Linux.
+The supported platforms are Windows, Mac and Linux.
- Windows -
[DPAPI](https://docs.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection)
is used for encryption.
- MAC - The MAC KeyChain is used.
- Linux - [LibSecret](https://wiki.gnome.org/Projects/Libsecret) is used for
encryption.
@@ -28,7 +28,9 @@
## Usage
-The Microsoft Authentication Extensions library provides the
`PersistedTokenCache` which accepts a platform-dependent persistence instance.
This token cache can then be used to instantiate the `PublicClientApplication`
in MSAL Python.
+### Creating an encrypted token cache file to be used by MSAL
+
+The Microsoft Authentication Extensions library provides the
`PersistedTokenCache` which accepts a platform-dependent persistence instance.
This token cache can then be used to instantiate the `PublicClientApplication`
in MSAL Python.
The token cache includes a file lock, and auto-reload behavior under the hood.
@@ -39,24 +41,16 @@
```python
def build_persistence(location, fallback_to_plaintext=False):
"""Build a suitable persistence instance based your current OS"""
- if sys.platform.startswith('win'):
- return FilePersistenceWithDataProtection(location)
- if sys.platform.startswith('darwin'):
- return KeychainPersistence(location, "my_service_name",
"my_account_name")
- if sys.platform.startswith('linux'):
- try:
- return LibsecretPersistence(
- location,
- schema_name="my_schema_name",
- attributes={"my_attr1": "foo", "my_attr2": "bar"},
- )
- except: # pylint: disable=bare-except
- if not fallback_to_plaintext:
- raise
- logging.exception("Encryption unavailable. Opting in to plain
text.")
- return FilePersistence(location)
+ try:
+ return build_encrypted_persistence(location)
+ except:
+ if not fallback_to_plaintext:
+ raise
+ logging.warning("Encryption unavailable. Opting in to plain text.")
+ return FilePersistence(location)
persistence = build_persistence("token_cache.bin")
+print("Type of persistence: {}".format(persistence.__class__.__name__))
print("Is this persistence encrypted?", persistence.is_encrypted)
cache = PersistedTokenCache(persistence)
@@ -66,6 +60,36 @@
app = msal.PublicClientApplication("my_client_id", token_cache=cache)
```
+### Creating an encrypted persistence file to store your own data
+
+Here is an example of this pattern for multiple platforms (taken from the
complete [sample
here](https://github.com/AzureAD/microsoft-authentication-extensions-for-python/blob/dev/sample/persistence_sample.py)):
+
+```python
+def build_persistence(location, fallback_to_plaintext=False):
+ """Build a suitable persistence instance based your current OS"""
+ try:
+ return build_encrypted_persistence(location)
+ except: # pylint: disable=bare-except
+ if not fallback_to_plaintext:
+ raise
+ logging.warning("Encryption unavailable. Opting in to plain text.")
+ return FilePersistence(location)
+
+persistence = build_persistence("storage.bin", fallback_to_plaintext=False)
+print("Type of persistence: {}".format(persistence.__class__.__name__))
+print("Is this persistence encrypted?", persistence.is_encrypted)
+
+data = { # It can be anything, here we demonstrate an arbitrary json object
+ "foo": "hello world",
+ "bar": "",
+ "service_principle_1": "blah blah...",
+ }
+
+persistence.save(json.dumps(data))
+assert json.loads(persistence.load()) == data
+```
+
+
## Community Help and Support
We leverage Stack Overflow to work with the community on supporting Azure
Active Directory and its SDKs, including this one!
@@ -92,4 +116,4 @@
## 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.
\ No newline at end of file
+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-0.3.1/msal_extensions/__init__.py
new/msal-extensions-1.0.0/msal_extensions/__init__.py
--- old/msal-extensions-0.3.1/msal_extensions/__init__.py 2021-12-13
05:46:45.000000000 +0100
+++ new/msal-extensions-1.0.0/msal_extensions/__init__.py 2022-02-15
00:45:30.000000000 +0100
@@ -1,10 +1,9 @@
"""Provides auxiliary functionality to the `msal` package."""
-__version__ = "0.3.1"
-
-import sys
+__version__ = "1.0.0"
from .persistence import (
FilePersistence,
+ build_encrypted_persistence,
FilePersistenceWithDataProtection,
KeychainPersistence,
LibsecretPersistence,
@@ -12,9 +11,3 @@
from .cache_lock import CrossPlatLock
from .token_cache import PersistedTokenCache
-if sys.platform.startswith('win'):
- from .token_cache import WindowsTokenCache as TokenCache
-elif sys.platform.startswith('darwin'):
- from .token_cache import OSXTokenCache as TokenCache
-else:
- from .token_cache import FileTokenCache as TokenCache
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-0.3.1/msal_extensions/persistence.py
new/msal-extensions-1.0.0/msal_extensions/persistence.py
--- old/msal-extensions-0.3.1/msal_extensions/persistence.py 2021-12-13
05:46:45.000000000 +0100
+++ new/msal-extensions-1.0.0/msal_extensions/persistence.py 2022-02-15
00:45:30.000000000 +0100
@@ -9,6 +9,7 @@
import abc
import os
import errno
+import hashlib
import logging
import sys
try:
@@ -50,21 +51,52 @@
else:
raise
+def _auto_hash(input_string):
+ return hashlib.sha256(input_string.encode('utf-8')).hexdigest()
+
# We do not aim to wrap every os-specific exception.
-# Here we define only the most common one,
-# otherwise caller would need to catch os-specific persistence exceptions.
-class PersistenceNotFound(IOError): # Use IOError rather than OSError as base,
+# Here we standardize only the most common ones,
+# otherwise caller would need to catch os-specific underlying exceptions.
+class PersistenceError(IOError): # Use IOError rather than OSError as base,
+ """The base exception for persistence."""
# because historically an IOError was bubbled up and expected.
#
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/blob/0.2.2/msal_extensions/token_cache.py#L38
# Now we want to maintain backward compatibility even when using
Python 2.x
# It makes no difference in Python 3.3+ where IOError is an alias of
OSError.
+ def __init__(self, err_no=None, message=None, location=None): # pylint:
disable=useless-super-delegation
+ super(PersistenceError, self).__init__(err_no, message, location)
+
+
+class PersistenceNotFound(PersistenceError):
"""This happens when attempting BasePersistence.load() on a non-existent
persistence instance"""
def __init__(self, err_no=None, message=None, location=None):
super(PersistenceNotFound, self).__init__(
- err_no or errno.ENOENT,
- message or "Persistence not found",
- location)
+ err_no=errno.ENOENT,
+ message=message or "Persistence not found",
+ location=location)
+
+class PersistenceEncryptionError(PersistenceError):
+ """This could be raised by persistence.save()"""
+
+class PersistenceDecryptionError(PersistenceError):
+ """This could be raised by persistence.load()"""
+
+
+def build_encrypted_persistence(location):
+ """Build a suitable encrypted persistence instance based your current OS.
+
+ If you do not need encryption, then simply use ``FilePersistence``
constructor.
+ """
+ # Does not (yet?) support fallback_to_plaintext flag,
+ # because the persistence on Windows and macOS do not support built-in
trial_run().
+ if sys.platform.startswith('win'):
+ return FilePersistenceWithDataProtection(location)
+ if sys.platform.startswith('darwin'):
+ return KeychainPersistence(location)
+ if sys.platform.startswith('linux'):
+ return LibsecretPersistence(location)
+ raise RuntimeError("Unsupported platform: {}".format(sys.platform)) #
pylint: disable=consider-using-f-string
class BasePersistence(ABC):
@@ -101,6 +133,11 @@
raise NotImplementedError
+def _open(location):
+ return os.open(location, os.O_RDWR | os.O_CREAT | os.O_TRUNC, 0o600)
+ # The 600 seems no-op on NTFS/Windows, and that is fine
+
+
class FilePersistence(BasePersistence):
"""A generic persistence, storing data in a plain-text file"""
@@ -113,7 +150,7 @@
def save(self, content):
# type: (str) -> None
"""Save the content into this persistence"""
- with open(self._location, 'w+') as handle: # pylint:
disable=unspecified-encoding
+ with os.fdopen(_open(self._location), 'w+') as handle:
handle.write(content)
def load(self):
@@ -168,8 +205,14 @@
def save(self, content):
# type: (str) -> None
- data = self._dp_agent.protect(content)
- with open(self._location, 'wb+') as handle:
+ try:
+ data = self._dp_agent.protect(content)
+ 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),
+ )
+ with os.fdopen(_open(self._location), 'wb+') as handle:
handle.write(data)
def load(self):
@@ -177,7 +220,6 @@
try:
with open(self._location, 'rb') as handle:
data = handle.read()
- return self._dp_agent.unprotect(data)
except EnvironmentError as exp: # EnvironmentError in Py 2.7 works
across platform
if exp.errno == errno.ENOENT:
raise PersistenceNotFound(
@@ -190,6 +232,17 @@
"DPAPI error likely caused by file content not previously
encrypted. "
"App developer should migrate by calling save(plaintext)
first.")
raise
+ try:
+ return self._dp_agent.unprotect(data)
+ except OSError as exception:
+ raise PersistenceDecryptionError(
+ err_no=getattr(exception, "winerror", None), # Exists in
Python 3 on Windows
+ 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),
+ location=self._location,
+ )
class KeychainPersistence(BasePersistence):
@@ -197,19 +250,18 @@
and protected by native Keychain libraries on OSX"""
is_encrypted = True
- def __init__(self, signal_location, service_name, account_name):
+ def __init__(self, signal_location, service_name=None, account_name=None):
"""Initialization could fail due to unsatisfied dependency.
:param signal_location: See
:func:`persistence.LibsecretPersistence.__init__`
"""
- if not (service_name and account_name): # It would hang on OSX
- raise ValueError("service_name and account_name are required")
from .osx import Keychain, KeychainError # pylint:
disable=import-outside-toplevel
self._file_persistence = FilePersistence(signal_location) # Favor
composition
self._Keychain = Keychain # pylint: disable=invalid-name
self._KeychainError = KeychainError # pylint: disable=invalid-name
- self._service_name = service_name
- self._account_name = account_name
+ default_service_name = "msal-extensions" # This is also our package
name
+ self._service_name = service_name or default_service_name
+ self._account_name = account_name or _auto_hash(signal_location)
def save(self, content):
with self._Keychain() as locker:
@@ -247,7 +299,7 @@
and protected by native libsecret libraries on Linux"""
is_encrypted = True
- def __init__(self, signal_location, schema_name, attributes, **kwargs):
+ def __init__(self, signal_location, schema_name=None, attributes=None,
**kwargs):
"""Initialization could fail due to unsatisfied dependency.
:param string signal_location:
@@ -262,7 +314,8 @@
from .libsecret import ( # This uncertain import is deferred till
runtime
LibSecretAgent, trial_run)
trial_run()
- self._agent = LibSecretAgent(schema_name, attributes, **kwargs)
+ self._agent = LibSecretAgent(
+ schema_name or _auto_hash(signal_location), attributes or {},
**kwargs)
self._file_persistence = FilePersistence(signal_location) # Favor
composition
def save(self, content):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-0.3.1/msal_extensions/token_cache.py
new/msal-extensions-1.0.0/msal_extensions/token_cache.py
--- old/msal-extensions-0.3.1/msal_extensions/token_cache.py 2021-12-13
05:46:45.000000000 +0100
+++ new/msal-extensions-1.0.0/msal_extensions/token_cache.py 2022-02-15
00:45:30.000000000 +0100
@@ -1,15 +1,12 @@
"""Generic functions and types for working with a TokenCache that is not
platform specific."""
import os
-import warnings
import time
import logging
import msal
from .cache_lock import CrossPlatLock
-from .persistence import (
- _mkdir_p, PersistenceNotFound, FilePersistence,
- FilePersistenceWithDataProtection, KeychainPersistence)
+from .persistence import _mkdir_p, PersistenceNotFound
logger = logging.getLogger(__name__)
@@ -89,35 +86,3 @@
return super(PersistedTokenCache, self).find(credential_type,
**kwargs)
return [] # Not really reachable here. Just to keep pylint happy.
-
-class FileTokenCache(PersistedTokenCache):
- """A token cache which uses plain text file to store your tokens."""
- def __init__(self, cache_location, **ignored): # pylint:
disable=unused-argument
- warnings.warn("You are using an unprotected token cache",
RuntimeWarning)
- warnings.warn("Use PersistedTokenCache(...) instead",
DeprecationWarning)
- super(FileTokenCache, self).__init__(FilePersistence(cache_location))
-
-UnencryptedTokenCache = FileTokenCache # For backward compatibility
-
-
-class WindowsTokenCache(PersistedTokenCache):
- """A token cache which uses Windows DPAPI to encrypt your tokens."""
- def __init__(
- self, cache_location, entropy='',
- **ignored): # pylint: disable=unused-argument
- warnings.warn("Use PersistedTokenCache(...) instead",
DeprecationWarning)
- super(WindowsTokenCache, self).__init__(
- FilePersistenceWithDataProtection(cache_location, entropy=entropy))
-
-
-class OSXTokenCache(PersistedTokenCache):
- """A token cache which uses native Keychain libraries to encrypt your
tokens."""
- def __init__(self,
- cache_location,
- service_name='Microsoft.Developer.IdentityService',
- account_name='MSALCache',
- **ignored): # pylint: disable=unused-argument
- warnings.warn("Use PersistedTokenCache(...) instead",
DeprecationWarning)
- super(OSXTokenCache, self).__init__(
- KeychainPersistence(cache_location, service_name, account_name))
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal-extensions-0.3.1/msal_extensions/windows.py
new/msal-extensions-1.0.0/msal_extensions/windows.py
--- old/msal-extensions-0.3.1/msal_extensions/windows.py 2021-12-13
05:46:45.000000000 +0100
+++ new/msal-extensions-1.0.0/msal_extensions/windows.py 2022-02-15
00:45:30.000000000 +0100
@@ -39,6 +39,15 @@
_MEMCPY(blob_buffer, pb_data, cb_data)
return blob_buffer.raw
+_err_description = {
+ # Keys came from real world observation, values came from winerror.h
(http://errors (Microsoft internal))
+ -2146893813: "Key not valid for use in specified state.",
+ -2146892987: "The requested operation cannot be completed. "
+ "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",
+ }
# This code is modeled from a StackOverflow question, which can be found here:
# https://stackoverflow.com/questions/463832/using-dpapi-with-python
@@ -82,7 +91,7 @@
_LOCAL_FREE(result.pbData)
err_code = _GET_LAST_ERROR()
- raise OSError(256, '', '', err_code)
+ raise OSError(None, _err_description.get(err_code), None, err_code)
def unprotect(self, cipher_text):
# type: (bytes) -> str
@@ -111,4 +120,4 @@
finally:
_LOCAL_FREE(result.pbData)
err_code = _GET_LAST_ERROR()
- raise OSError(256, '', '', 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-0.3.1/msal_extensions.egg-info/PKG-INFO
new/msal-extensions-1.0.0/msal_extensions.egg-info/PKG-INFO
--- old/msal-extensions-0.3.1/msal_extensions.egg-info/PKG-INFO 2021-12-13
05:46:55.000000000 +0100
+++ new/msal-extensions-1.0.0/msal_extensions.egg-info/PKG-INFO 2022-02-15
00:45:41.000000000 +0100
@@ -1,24 +1,23 @@
Metadata-Version: 2.1
Name: msal-extensions
-Version: 0.3.1
-Summary: UNKNOWN
-Home-page: UNKNOWN
+Version: 1.0.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
Project-URL: Changelog,
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases
Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
Description-Content-Type: text/markdown
License-File: LICENSE
# Microsoft Authentication Extensions for Python
-The Microsoft Authentication Extensions for Python offers secure mechanisms
for client applications to perform cross-platform token cache serialization and
persistence. It gives additional support to the [Microsoft Authentication
Library for Python
(MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-python).
+The Microsoft Authentication Extensions for Python offers secure mechanisms
for client applications to perform cross-platform token cache serialization and
persistence. It gives additional support to the [Microsoft Authentication
Library for Python
(MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-python).
MSAL Python supports an in-memory cache by default and provides the
[SerializableTokenCache](https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache)
to perform cache serialization. You can read more about this in the MSAL
Python
[documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-python-token-cache-serialization).
Developers are required to implement their own cache persistance across
multiple platforms and Microsoft Authentication Extensions makes this simpler.
-The supported platforms are Windows, Mac and Linux.
+The supported platforms are Windows, Mac and Linux.
- Windows -
[DPAPI](https://docs.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection)
is used for encryption.
- MAC - The MAC KeyChain is used.
- Linux - [LibSecret](https://wiki.gnome.org/Projects/Libsecret) is used for
encryption.
@@ -41,7 +40,9 @@
## Usage
-The Microsoft Authentication Extensions library provides the
`PersistedTokenCache` which accepts a platform-dependent persistence instance.
This token cache can then be used to instantiate the `PublicClientApplication`
in MSAL Python.
+### Creating an encrypted token cache file to be used by MSAL
+
+The Microsoft Authentication Extensions library provides the
`PersistedTokenCache` which accepts a platform-dependent persistence instance.
This token cache can then be used to instantiate the `PublicClientApplication`
in MSAL Python.
The token cache includes a file lock, and auto-reload behavior under the hood.
@@ -52,24 +53,16 @@
```python
def build_persistence(location, fallback_to_plaintext=False):
"""Build a suitable persistence instance based your current OS"""
- if sys.platform.startswith('win'):
- return FilePersistenceWithDataProtection(location)
- if sys.platform.startswith('darwin'):
- return KeychainPersistence(location, "my_service_name",
"my_account_name")
- if sys.platform.startswith('linux'):
- try:
- return LibsecretPersistence(
- location,
- schema_name="my_schema_name",
- attributes={"my_attr1": "foo", "my_attr2": "bar"},
- )
- except: # pylint: disable=bare-except
- if not fallback_to_plaintext:
- raise
- logging.exception("Encryption unavailable. Opting in to plain
text.")
- return FilePersistence(location)
+ try:
+ return build_encrypted_persistence(location)
+ except:
+ if not fallback_to_plaintext:
+ raise
+ logging.warning("Encryption unavailable. Opting in to plain text.")
+ return FilePersistence(location)
persistence = build_persistence("token_cache.bin")
+print("Type of persistence: {}".format(persistence.__class__.__name__))
print("Is this persistence encrypted?", persistence.is_encrypted)
cache = PersistedTokenCache(persistence)
@@ -79,6 +72,36 @@
app = msal.PublicClientApplication("my_client_id", token_cache=cache)
```
+### Creating an encrypted persistence file to store your own data
+
+Here is an example of this pattern for multiple platforms (taken from the
complete [sample
here](https://github.com/AzureAD/microsoft-authentication-extensions-for-python/blob/dev/sample/persistence_sample.py)):
+
+```python
+def build_persistence(location, fallback_to_plaintext=False):
+ """Build a suitable persistence instance based your current OS"""
+ try:
+ return build_encrypted_persistence(location)
+ except: # pylint: disable=bare-except
+ if not fallback_to_plaintext:
+ raise
+ logging.warning("Encryption unavailable. Opting in to plain text.")
+ return FilePersistence(location)
+
+persistence = build_persistence("storage.bin", fallback_to_plaintext=False)
+print("Type of persistence: {}".format(persistence.__class__.__name__))
+print("Is this persistence encrypted?", persistence.is_encrypted)
+
+data = { # It can be anything, here we demonstrate an arbitrary json object
+ "foo": "hello world",
+ "bar": "",
+ "service_principle_1": "blah blah...",
+ }
+
+persistence.save(json.dumps(data))
+assert json.loads(persistence.load()) == data
+```
+
+
## Community Help and Support
We leverage Stack Overflow to work with the community on supporting Azure
Active Directory and its SDKs, including this one!
@@ -107,3 +130,4 @@
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-0.3.1/setup.cfg
new/msal-extensions-1.0.0/setup.cfg
--- old/msal-extensions-0.3.1/setup.cfg 2021-12-13 05:46:55.792970000 +0100
+++ new/msal-extensions-1.0.0/setup.cfg 2022-02-15 00:45:41.537072200 +0100
@@ -6,7 +6,8 @@
project_urls = Changelog =
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases
classifiers =
License :: OSI Approved :: MIT License
- Development Status :: 4 - Beta
+ Development Status :: 5 - Production/Stable
+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]
tag_build =