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 
<adrian.glaub...@suse.com>
+
+- 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 
[openc...@microsoft.com](mailto:openc...@microsoft.com) 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 
[openc...@microsoft.com](mailto:openc...@microsoft.com) 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 
[openc...@microsoft.com](mailto:openc...@microsoft.com) 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 
[openc...@microsoft.com](mailto:openc...@microsoft.com) 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 = 

Reply via email to