From cb4aa61f06787bf4b9f5bdf8464c64476e506efb Mon Sep 17 00:00:00 2001 From: Ray Luo Date: Mon, 19 Jun 2023 21:59:01 -0700 Subject: [PATCH 1/3] Switch from setup.py to setup.cfg --- setup.cfg | 67 +++++++++++++++++++++++++++++++++++ setup.py | 102 ++---------------------------------------------------- 2 files changed, 69 insertions(+), 100 deletions(-) diff --git a/setup.cfg b/setup.cfg index 3ec1c6ab..a69dbdd7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,9 +1,76 @@ +# Format https://setuptools.pypa.io/en/latest/userguide/declarative_config.html + [bdist_wheel] universal=1 [metadata] +name = msal +version = attr: msal.__version__ +description = + The Microsoft Authentication Library (MSAL) for Python library + enables your app to access the Microsoft Cloud + by supporting authentication of users with + Microsoft Azure Active Directory accounts (AAD) and Microsoft Accounts (MSA) + using industry standard OAuth2 and OpenID Connect. +long_description = file: README.md +long_description_content_type = text/markdown +license = MIT +author = Microsoft Corporation +author_email = nugetaad@microsoft.com +url = https://github.com/AzureAD/microsoft-authentication-library-for-python +classifiers = + Development Status :: 5 - Production/Stable + Programming Language :: Python + Programming Language :: Python :: 2 + Programming Language :: Python :: 2.7 + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + 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 + License :: OSI Approved :: MIT License + Operating System :: OS Independent + project_urls = Changelog = https://github.com/AzureAD/microsoft-authentication-library-for-python/releases Documentation = https://msal-python.readthedocs.io/ Questions = https://stackoverflow.com/questions/tagged/azure-ad-msal+python Feature/Bug Tracker = https://github.com/AzureAD/microsoft-authentication-library-for-python/issues + + +[options] +include_package_data = False # We used to ship LICENSE, but our __init__.py already mentions MIT +packages = find: +python_requires = >=2.7 +install_requires = + requests>=2.0.0,<3 + + # MSAL does not use jwt.decode(), + # therefore is insusceptible to CVE-2022-29217 so no need to bump to PyJWT 2.4+ + PyJWT[crypto]>=1.0.0,<3 + + # load_pem_private_key() is available since 0.6 + # https://github.com/pyca/cryptography/blob/master/CHANGELOG.rst#06---2014-09-29 + # + # And we will use the cryptography (X+3).0.0 as the upper bound, + # based on their latest deprecation policy + # https://cryptography.io/en/latest/api-stability/#deprecation + cryptography>=0.6,<44 + + mock; python_version<'3.3' + +[options.extras_require] +broker = + # The broker is defined as optional dependency, + # so that downstream apps can opt in. The opt-in is needed, partially because + # most existing MSAL Python apps do not have the redirect_uri needed by broker. + # MSAL Python uses a subset of API from PyMsalRuntime 0.11.2+, + # but we still bump the lower bound to 0.13.2+ for its important bugfix (https://github.com/AzureAD/microsoft-authentication-library-for-cpp/pull/3244) + pymsalruntime>=0.13.2,<0.14; python_version>='3.6' and platform_system=='Windows' + +[options.packages.find] +exclude = + tests diff --git a/setup.py b/setup.py index f7a2a4a1..1f21e1d5 100644 --- a/setup.py +++ b/setup.py @@ -1,101 +1,3 @@ -#!/usr/bin/env python -#------------------------------------------------------------------------------ -# -# Copyright (c) Microsoft Corporation. -# All rights reserved. -# -# This code is licensed under the MIT License. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files(the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions : -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# -#------------------------------------------------------------------------------ - -from setuptools import setup, find_packages -import re, io - -# setup.py shall not import main package -__version__ = re.search( - r'__version__\s*=\s*[\'"]([^\'"]*)[\'"]', # It excludes inline comment too - io.open('msal/application.py', encoding='utf_8_sig').read() - ).group(1) - -long_description = open('README.md').read() - -setup( - name='msal', - version=__version__, - description=' '.join( - """The Microsoft Authentication Library (MSAL) for Python library - enables your app to access the Microsoft Cloud - by supporting authentication of users with - Microsoft Azure Active Directory accounts (AAD) and Microsoft Accounts (MSA) - using industry standard OAuth2 and OpenID Connect.""".split()), - long_description=long_description, - long_description_content_type="text/markdown", - license='MIT', - author='Microsoft Corporation', - author_email='nugetaad@microsoft.com', - url='https://github.com/AzureAD/microsoft-authentication-library-for-python', - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - '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', - 'License :: OSI Approved :: MIT License', - 'Operating System :: OS Independent', - ], - packages=find_packages(exclude=["tests"]), - package_data={'': ['LICENSE']}, # Do not use data_files=[...], - # which would cause the LICENSE being copied to /usr/local, - # and tend to fail because of insufficient permission. - # See https://stackoverflow.com/a/14211600/728675 for more detail - install_requires=[ - 'requests>=2.0.0,<3', - 'PyJWT[crypto]>=1.0.0,<3', # MSAL does not use jwt.decode(), therefore is insusceptible to CVE-2022-29217 so no need to bump to PyJWT 2.4+ - - 'cryptography>=0.6,<44', - # load_pem_private_key() is available since 0.6 - # https://github.com/pyca/cryptography/blob/master/CHANGELOG.rst#06---2014-09-29 - # - # And we will use the cryptography (X+3).0.0 as the upper bound, - # based on their latest deprecation policy - # https://cryptography.io/en/latest/api-stability/#deprecation - - "mock;python_version<'3.3'", - ], - extras_require={ # It does not seem to work if being defined inside setup.cfg - "broker": [ - # The broker is defined as optional dependency, - # so that downstream apps can opt in. The opt-in is needed, partially because - # most existing MSAL Python apps do not have the redirect_uri needed by broker. - # MSAL Python uses a subset of API from PyMsalRuntime 0.11.2+, - # but we still bump the lower bound to 0.13.2+ for its important bugfix (https://github.com/AzureAD/microsoft-authentication-library-for-cpp/pull/3244) - "pymsalruntime>=0.13.2,<0.14;python_version>='3.6' and platform_system=='Windows'", - ], - }, -) +from setuptools import setup +setup() From 45a0aee6da46063454cf8c64edd42b4507d868f4 Mon Sep 17 00:00:00 2001 From: Ray Luo Date: Tue, 20 Jun 2023 21:59:25 -0700 Subject: [PATCH 2/3] Ship release- branch of a non-draft PR to TestPyPI --- .github/workflows/python-package.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 9d24904a..95f3d4cb 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -65,7 +65,12 @@ jobs: cd: needs: ci - if: github.event_name == 'push' && (startsWith(github.ref, 'refs/tags') || github.ref == 'refs/heads/main') + if: | + github.event_name == 'push' && + ( + startsWith(github.ref, 'refs/tags') || + startsWith(github.ref, 'refs/heads/release-') + ) runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 @@ -77,14 +82,16 @@ jobs: run: | python -m pip install build --user python -m build --sdist --wheel --outdir dist/ . - - name: Publish to TestPyPI + - name: | + Publish to TestPyPI when pushing to release-* branch. + You better test with a1, a2, b1, b2 releases first. uses: pypa/gh-action-pypi-publish@v1.4.2 - if: github.ref == 'refs/heads/main' + if: startsWith(github.ref, 'refs/heads/release-') with: user: __token__ password: ${{ secrets.TEST_PYPI_API_TOKEN }} repository_url: https://test.pypi.org/legacy/ - - name: Publish to PyPI + - name: Publish to PyPI when tagged if: startsWith(github.ref, 'refs/tags') uses: pypa/gh-action-pypi-publish@v1.4.2 with: From fea7ea94de7539649bc6603013653deada789de3 Mon Sep 17 00:00:00 2001 From: Ray Luo Date: Fri, 23 Jun 2023 02:15:40 -0700 Subject: [PATCH 3/3] Surface msal telemetry as a long opaque string Remove wam_telemetry, for now --- msal/application.py | 7 ++++++- msal/broker.py | 9 +++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/msal/application.py b/msal/application.py index 16fbac28..5a750598 100644 --- a/msal/application.py +++ b/msal/application.py @@ -73,6 +73,11 @@ def _pii_less_home_account_id(home_account_id): def _clean_up(result): if isinstance(result, dict): + if "_msalruntime_telemetry" in result or "_msal_python_telemetry" in result: + result["msal_telemetry"] = json.dumps({ # Telemetry as an opaque string + "msalruntime_telemetry": result.get("_msalruntime_telemetry"), + "msal_python_telemetry": result.get("_msal_python_telemetry"), + }, separators=(",", ":")) return { k: result[k] for k in result if k != "refresh_in" # MSAL handled refresh_in, customers need not @@ -966,7 +971,7 @@ def authorize(): # A controller in a web app self._validate_ssh_cert_input_data(kwargs.get("data", {})) telemetry_context = self._build_telemetry_context( self.ACQUIRE_TOKEN_BY_AUTHORIZATION_CODE_ID) - response =_clean_up(self.client.obtain_token_by_auth_code_flow( + response = _clean_up(self.client.obtain_token_by_auth_code_flow( auth_code_flow, auth_response, scope=self._decorate_scope(scopes) if scopes else None, diff --git a/msal/broker.py b/msal/broker.py index 8b997c61..ce7a9bde 100644 --- a/msal/broker.py +++ b/msal/broker.py @@ -23,8 +23,7 @@ except (ImportError, AttributeError): # AttributeError happens when a prior pymsalruntime uninstallation somehow leaved an empty folder behind # PyMsalRuntime currently supports these Windows versions, listed in this MSFT internal link # https://github.com/AzureAD/microsoft-authentication-library-for-cpp/pull/2406/files - raise ImportError( # TODO: Remove or adjust this line right before merging this PR - 'You need to install dependency by: pip install "msal[broker]>=1.20,<2"') + raise ImportError('You need to install dependency by: pip install "msal[broker]>=1.20,<2"') # It could throw RuntimeError when running on ancient versions of Windows @@ -84,9 +83,11 @@ def _read_account_by_id(account_id, correlation_id): def _convert_result(result, client_id, expected_token_type=None): # Mimic an on-the-wire response from AAD + telemetry = result.get_telemetry_data() + telemetry.pop("wam_telemetry", None) # In pymsalruntime 0.13, it contains PII "account_id" error = result.get_error() if error: - return _convert_error(error, client_id) + return dict(_convert_error(error, client_id), _msalruntime_telemetry=telemetry) id_token_claims = json.loads(result.get_id_token()) if result.get_id_token() else {} account = result.get_account() assert account, "Account is expected to be always available" @@ -107,7 +108,7 @@ def _convert_result(result, client_id, expected_token_type=None): # Mimic an on granted_scopes = result.get_granted_scopes() # New in pymsalruntime 0.3.x if granted_scopes: return_value["scope"] = " ".join(granted_scopes) # Mimic the on-the-wire data format - return return_value + return dict(return_value, _msalruntime_telemetry=telemetry) def _get_new_correlation_id():