Hello community, here is the log from the commit of package python-adal for openSUSE:Factory checked in at 2018-09-26 16:12:23 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-adal (Old) and /work/SRC/openSUSE:Factory/.python-adal.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-adal" Wed Sep 26 16:12:23 2018 rev:4 rq:637915 version:1.0.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-adal/python-adal.changes 2018-02-14 09:27:39.420100850 +0100 +++ /work/SRC/openSUSE:Factory/.python-adal.new/python-adal.changes 2018-09-26 16:12:23.323389833 +0200 @@ -1,0 +2,9 @@ +Mon Sep 3 08:39:56 UTC 2018 - John Paul Adrian Glaubitz <adrian.glaub...@suse.com> + +- New upstream release + + Version 1.0.2 + + For detailed information about changes see the + HISTORY.txt file provided with this package +- Update Requires from setup.py + +------------------------------------------------------------------- Old: ---- adal-0.5.0.tar.gz New: ---- adal-1.0.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-adal.spec ++++++ --- /var/tmp/diff_new_pack.lfqlre/_old 2018-09-26 16:12:23.735389150 +0200 +++ /var/tmp/diff_new_pack.lfqlre/_new 2018-09-26 16:12:23.739389144 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-adal -Version: 0.5.0 +Version: 1.0.2 Release: 0 Summary: Azure Active Directory library License: MIT @@ -33,7 +33,7 @@ Requires: python-PyJWT >= 1.0.0 Requires: python-cryptography >= 1.1.0 Requires: python-python-dateutil >= 2.1.0 -Requires: python-requests >= 2.7.0 +Requires: python-requests >= 2.0.0 BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildArch: noarch ++++++ adal-0.5.0.tar.gz -> adal-1.0.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/PKG-INFO new/adal-1.0.2/PKG-INFO --- old/adal-0.5.0/PKG-INFO 2018-01-26 01:06:26.000000000 +0100 +++ new/adal-1.0.2/PKG-INFO 2018-06-26 21:24:16.000000000 +0200 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: adal -Version: 0.5.0 +Version: 1.0.2 Summary: The ADAL for Python library makes it easy for python application to authenticate to Azure Active Directory (AAD) in order to access AAD protected web resources. Home-page: https://github.com/AzureAD/azure-activedirectory-library-for-python Author: Microsoft Corporation Author-email: nuget...@microsoft.com License: MIT -Description-Content-Type: UNKNOWN Description: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/README.md new/adal-1.0.2/README.md --- old/adal-0.5.0/README.md 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/README.md 2018-06-26 21:23:14.000000000 +0200 @@ -1,57 +1,33 @@ # Microsoft Azure Active Directory Authentication Library (ADAL) for Python -The ADAL for python library makes it easy for python applications to authenticate to AAD in order to access AAD protected web resources. + `master` branch | `dev` branch | Reference Docs +--------------------|-----------------|--------------- +[![Build Status](https://travis-ci.org/AzureAD/azure-activedirectory-library-for-python.svg?branch=master)](https://travis-ci.org/AzureAD/azure-activedirectory-library-for-python) | [![Build Status](https://travis-ci.org/AzureAD/azure-activedirectory-library-for-python.svg?branch=dev)](https://travis-ci.org/AzureAD/azure-activedirectory-library-for-python) | [![Documentation Status](https://readthedocs.org/projects/adal-python/badge/?version=latest)](https://adal-python.readthedocs.io/en/latest/?badge=latest) -## Usage +|[Getting Started](https://github.com/AzureAD/azure-activedirectory-library-for-python/wiki)| [Docs](https://aka.ms/aaddev)| [Samples](https://github.com/azure-samples?query=active-directory)| [Support](README.md#community-help-and-support) +| --- | --- | --- | --- | -### Install -To support 'service principal' with certificate, ADAL depends on the 'cryptography' package. For smooth installation, some suggestions: +The ADAL for Python library enables python applications to authenticate with Azure AD and get tokens to access Azure AD protected web resources. -* For Windows and macOS +You can learn in detail about ADAL Python functionality and usage documented in the [Wiki](https://github.com/AzureAD/azure-activedirectory-library-for-python/wiki). -Upgrade to the latest pip (8.1.2 as of June 2016) and just do `pip install adal`. +## Installation and Usage -* For Linux +You can find the steps to install and basic usage of the library under [ADAL Basics](https://github.com/AzureAD/azure-activedirectory-library-for-python/wiki/ADAL-basics) page in the Wiki. -Upgrade to the latest pip (8.1.2 as of June 2016). - -You'll need a C compiler, libffi + its development headers, and openssl + its development headers. Refer to [cryptography installation](https://cryptography.io/en/latest/installation/) - -* To install from source: - -Upgrade to the latest pip (8.1.2 as of June 2016). -Before run `python setup.py install`, to avoid dealing with compilation errors from cryptography, run `pip install cryptography` first to use statically-linked wheels. -If you still like build from source, refer to [cryptography installation](https://cryptography.io/en/latest/installation/). - -For more context, starts with this [stackoverflow thread](http://stackoverflow.com/questions/22073516/failed-to-install-python-cryptography-package-with-pip-and-setup-py). - -### Acquire Token with Client Credentials - -In order to use this token acquisition method, you need to configure a service principal. Please follow [this walkthrough](https://azure.microsoft.com/en-us/documentation/articles/resource-group-create-service-principal-portal/). - -Find the `Main logic` part in the [sample](sample/client_credentials_sample.py#L46-L55). - -### Acquire Token with client certificate -A service principal is also required. -Find the `Main logic` part in the [sample](sample/certificate_credentials_sample.py#L55-L64). - -### Acquire Token with Refresh Token -Find the `Main logic` part in the [sample](sample/refresh_token_sample.py#L47-L69). - -### Acquire Token with device code -Find the `Main logic` part in the [sample](sample/device_code_sample.py#L49-L54). +## Samples and Documentation +We provide a full suite of [sample applications on GitHub](https://github.com/azure-samples?utf8=%E2%9C%93&q=active-directory&type=&language=) to help you get started with learning the Azure Identity system. This includes tutorials for native clients and web applications. We also provide full walkthroughs for authentication flows such as OAuth2, OpenID Connect and for calling APIs such as the Graph API. -### Acquire Token with authorization code -Find the `Main logic` part in the [sample](sample/website_sample.py#L107-L115) for a complete bare bones web site that makes use of the code below. +You can find the relevant samples by scenarios listed in this [wiki page for acquiring tokens using ADAL Python](https://github.com/AzureAD/azure-activedirectory-library-for-python/wiki/Acquire-tokens#adal-python-apis-for-corresponding-flows). +The documents on [Auth Scenarios](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-scenarios#application-types-and-scenarios) and [Auth protocols](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-openid-connect-code) are recommended reading. -## Samples and Documentation -We provide a full suite of [sample applications on GitHub](https://github.com/azure-samples?utf8=%E2%9C%93&q=active-directory&type=&language=) and an [Azure AD developer landing page](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-developers-guide) to help you get started with learning the Azure Identity system. This includes tutorials for native clients and web applications. We also provide full walkthroughs for authentication flows such as OAuth2, OpenID Connect and for calling APIs such as the Graph API. +## Versions -It is recommended to read the [Auth Scenarios](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-scenarios) doc, specifically the [Scenarios section](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-scenarios#application-types-and-scenarios). For some topics about registering/integrating an app, checkout [this doc](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications). And finally, we have a great topic on the Auth protocols you would be using and how they play with Azure AD in [this doc](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-openid-connect-code). +This library follows [Semantic Versioning](http://semver.org/). -While Python-specific samples will be added into the aforementioned documents as an on-going effort, you can always find [most relevant samples just inside this library repo](https://github.com/AzureAD/azure-activedirectory-library-for-python/tree/dev/sample). +You can find the changes for each version under [Releases](https://github.com/AzureAD/azure-activedirectory-library-for-python/releases). ## Community Help and Support @@ -65,29 +41,8 @@ ## Contributing -All code is licensed under the MIT license and we triage actively on GitHub. We enthusiastically welcome contributions and feedback. You can clone the repo and start contributing now. +All code is licensed under the MIT license and we triage actively on GitHub. We enthusiastically welcome contributions and feedback. Please read the [contributing guide](./contributing.md) before starting. ## 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. - -## Quick Start - -### Installation - -``` $ pip install adal ``` - -### http tracing/proxy -If need to bypass self-signed certificates, turn on the environment variable of `ADAL_PYTHON_SSL_NO_VERIFY` - - -## Note - -### Changes on 'client_id' and 'resource' arguments after 0.1.0 -The convinient methods in 0.1.0 have been removed, and now your application should provide parameter values to `client_id` and `resource`. - -2 Reasons: - -* Each adal client should have an Application ID representing an valid application registered in a tenant. The old methods borrowed the client-id of [azure-cli](https://github.com/Azure/azure-xplat-cli), which is never right. It is simple to register your application and get a client id. Many walkthroughs exist. You can follow [one of those](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications). Do check out if you are new to AAD. - -* The old method defaults the `resource` argument to 'https://management.core.windows.net/', now you can just supply this value explictly. Please note, there are lots of different azure resources you can acquire tokens through adal though, for example, the samples in the repository acquire for the 'graph' resource. Because it is not an appropriate assumption to be made at the library level, we removed the old defaults. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/__init__.py new/adal-1.0.2/adal/__init__.py --- old/adal-0.5.0/adal/__init__.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/__init__.py 2018-06-26 21:23:14.000000000 +0200 @@ -27,7 +27,7 @@ # pylint: disable=wrong-import-position -__version__ = '0.5.0' +__version__ = '1.0.2' import logging diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/authentication_context.py new/adal-1.0.2/adal/authentication_context.py --- old/adal-0.5.0/adal/authentication_context.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/authentication_context.py 2018-06-26 21:23:14.000000000 +0200 @@ -47,7 +47,7 @@ def __init__( self, authority, validate_authority=None, cache=None, - api_version='1.0', timeout=None): + api_version=None, timeout=None, enable_pii=False, verify_ssl=None, proxies=None): '''Creates a new AuthenticationContext object. By default the authority will be checked against a list of known Azure @@ -56,7 +56,8 @@ This behavior can be turned off via the validate_authority parameter below. - :param str authority: A URL that identifies a token authority. + :param str authority: A URL that identifies a token authority. It should be of the + format https://login.microsoftonline.com/your_tenant :param bool validate_authority: (optional) Turns authority validation on or off. This parameter default to true. :param TokenCache cache: (optional) Sets the token cache used by this @@ -67,17 +68,28 @@ AuthenticationContexts. :param api_version: (optional) Specifies API version using on the wire. Historically it has a hardcoded default value as "1.0". - Developers are now encouraged to set it as None explicitly, + Developers have been encouraged to set it as None explicitly, which means the underlying API version will be automatically chosen. - In next major release, this default value will be changed to None. + Starting from ADAL Python 1.0, this default value becomes None. :param timeout: (optional) requests timeout. How long to wait for the server to send data before giving up, as a float, or a `(connect timeout, read timeout) <timeouts>` tuple. + :param enable_pii: (optional) Unless this is set to True, + there will be no Personally Identifiable Information (PII) written in log. + :param verify_ssl: (optional) requests verify. Either a boolean, in which case it + controls whether we verify the server's TLS certificate, or a string, in which + case it must be a path to a CA bundle to use. If this value is not provided, and + ADAL_PYTHON_SSL_NO_VERIFY env varaible is set, behavior is equivalent to + verify_ssl=False. + :param proxies: (optional) requests proxies. Dictionary mapping protocol to the URL + of the proxy. See http://docs.python-requests.org/en/master/user/advanced/#proxies + for details. ''' self.authority = Authority(authority, validate_authority is None or validate_authority) self._oauth2client = None self.correlation_id = None - env_value = os.environ.get('ADAL_PYTHON_SSL_NO_VERIFY') + env_verify = 'ADAL_PYTHON_SSL_NO_VERIFY' not in os.environ + verify = verify_ssl if verify_ssl is not None else env_verify if api_version is not None: warnings.warn( """The default behavior of including api-version=1.0 on the wire @@ -92,8 +104,10 @@ self._call_context = { 'options': GLOBAL_ADAL_OPTIONS, 'api_version': api_version, - 'verify_ssl': None if env_value is None else not env_value, # mainly for tracing through proxy - 'timeout':timeout + 'verify_ssl': verify, + 'proxies':proxies, + 'timeout':timeout, + "enable_pii": enable_pii, } self._token_requests_with_user_code = {} self.cache = cache or TokenCache() @@ -107,9 +121,9 @@ def options(self, val): self._call_context['options'] = val - def _acquire_token(self, token_func): + def _acquire_token(self, token_func, correlation_id=None): self._call_context['log_context'] = log.create_log_context( - self.correlation_id, self._call_context.get('enable_pii', False)) + correlation_id or self.correlation_id, self._call_context.get('enable_pii', False)) self.authority.validate(self._call_context) return token_func(self) @@ -166,7 +180,7 @@ def acquire_token_with_authorization_code(self, authorization_code, redirect_uri, resource, - client_id, client_secret): + client_id, client_secret=None, code_verifier=None): '''Gets a token for a given resource via auhtorization code for a server app. @@ -177,8 +191,13 @@ :param str resource: A URI that identifies the resource for which the token is valid. :param str client_id: The OAuth client id of the calling application. - :param str client_secret: The OAuth client secret of the calling - application. + :param str client_secret: (only for confidential clients)The OAuth + client secret of the calling application. This parameter if not set, + defaults to None + :param str code_verifier: (optional)The code verifier that was used to + obtain authorization code if PKCE was used in the authorization + code grant request.(usually used by public clients) This parameter if not set, + defaults to None :returns: dict with several keys, include "accessToken" and "refreshToken". ''' @@ -191,7 +210,7 @@ redirect_uri) return token_request.get_token_with_authorization_code( authorization_code, - client_secret) + client_secret, code_verifier) return self._acquire_token(token_func) @@ -260,9 +279,6 @@ :returns: dict with several keys, include "accessToken" and "refreshToken". ''' - self._call_context['log_context'] = log.create_log_context( - self.correlation_id, self._call_context.get('enable_pii', False)) - def token_func(self): token_request = TokenRequest(self._call_context, self, client_id, resource) @@ -277,7 +293,7 @@ return token - return self._acquire_token(token_func) + return self._acquire_token(token_func, user_code_info.get('correlation_id', None)) def cancel_request_to_get_token_with_device_code(self, user_code_info): '''Cancels the polling request to get token with device code. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/authority.py new/adal-1.0.2/adal/authority.py --- old/adal-0.5.0/adal/authority.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/authority.py 2018-06-26 21:23:14.000000000 +0200 @@ -70,6 +70,12 @@ if self._url.query: raise ValueError("The authority url must not have a query string.") + path_parts = [part for part in self._url.path.split('/') if part] + if len(path_parts) > 1: + raise ValueError("The authority url must be of the format https://login.microsoftonline.com/your_tenant") + elif len(path_parts) == 1: + self._url = urlparse(self._url.geturl().rstrip('/')) + def _parse_authority(self): self._host = self._url.hostname @@ -115,7 +121,8 @@ try: resp = requests.get(discovery_endpoint.geturl(), headers=get_options['headers'], - verify=self._call_context.get('verify_ssl', None)) + verify=self._call_context.get('verify_ssl', None), + proxies=self._call_context.get('proxies', None)) util.log_return_correlation_id(self._log, operation, resp) except Exception: self._log.exception("%(operation)s request failed", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/code_request.py new/adal-1.0.2/adal/code_request.py --- old/adal-0.5.0/adal/code_request.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/code_request.py 2018-06-26 21:23:14.000000000 +0200 @@ -32,7 +32,6 @@ OAUTH2_PARAMETERS = constants.OAuth2.Parameters class CodeRequest(object): - """description of class""" def __init__(self, call_context, authentication_context, client_id, resource): self._log = log.Logger("CodeRequest", call_context['log_context']) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/constants.py new/adal-1.0.2/adal/constants.py --- old/adal-0.5.0/adal/constants.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/constants.py 2018-06-26 21:23:14.000000000 +0200 @@ -42,6 +42,7 @@ REDIRECT_URI = 'redirect_uri' RESOURCE = 'resource' CODE = 'code' + CODE_VERIFIER = 'code_verifier' SCOPE = 'scope' ASSERTION = 'assertion' AAD_API_VERSION = 'api-version' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/mex.py new/adal-1.0.2/adal/mex.py --- old/adal-0.5.0/adal/mex.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/mex.py 2018-06-26 21:23:14.000000000 +0200 @@ -79,7 +79,8 @@ try: operation = "Mex Get" resp = requests.get(self._url, headers=options['headers'], - verify=self._call_context.get('verify_ssl', None)) + verify=self._call_context.get('verify_ssl', None), + proxies=self._call_context.get('proxies', None)) util.log_return_correlation_id(self._log, operation, resp) except Exception: self._log.exception( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/oauth2_client.py new/adal-1.0.2/adal/oauth2_client.py --- old/adal-0.5.0/adal/oauth2_client.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/oauth2_client.py 2018-06-26 21:23:14.000000000 +0200 @@ -264,6 +264,7 @@ data=url_encoded_token_request, headers=post_options['headers'], verify=self._call_context.get('verify_ssl', None), + proxies=self._call_context.get('proxies', None), timeout=self._call_context.get('timeout', None)) util.log_return_correlation_id(self._log, operation, resp) @@ -298,6 +299,7 @@ data=url_encoded_code_request, headers=post_options['headers'], verify=self._call_context.get('verify_ssl', None), + proxies=self._call_context.get('proxies', None), timeout=self._call_context.get('timeout', None)) util.log_return_correlation_id(self._log, operation, resp) except Exception: @@ -305,7 +307,9 @@ raise if util.is_http_success(resp.status_code): - return self._handle_get_device_code_response(resp.text) + user_code_info = self._handle_get_device_code_response(resp.text) + user_code_info['correlation_id'] = resp.headers.get('client-request-id') + return user_code_info else: if resp.status_code == 429: resp.raise_for_status() # Will raise requests.exceptions.HTTPError @@ -337,6 +341,7 @@ resp = requests.post( token_url.geturl(), data=url_encoded_code_request, headers=post_options['headers'], + proxies=self._call_context.get('proxies', None), verify=self._call_context.get('verify_ssl', None)) if resp.status_code == 429: resp.raise_for_status() # Will raise requests.exceptions.HTTPError diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/token_cache.py new/adal-1.0.2/adal/token_cache.py --- old/adal-0.5.0/adal/token_cache.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/token_cache.py 2018-06-26 21:23:14.000000000 +0200 @@ -81,8 +81,9 @@ with self._lock: for e in entries: key = _get_cache_key(e) - self._cache.pop(key) - self.has_state_changed = True + removed = self._cache.pop(key, None) + if removed is not None: + self.has_state_changed = True def add(self, entries): with self._lock: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/token_request.py new/adal-1.0.2/adal/token_request.py --- old/adal-0.5.0/adal/token_request.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/token_request.py 2018-06-26 21:23:14.000000000 +0200 @@ -316,15 +316,18 @@ self._cache_driver.add(token) return token - def get_token_with_authorization_code(self, authorization_code, client_secret): + def get_token_with_authorization_code(self, authorization_code, client_secret, code_verifier): self._log.info("Getting token with auth code.") - oauth_parameters = self._create_oauth_parameters(OAUTH2_GRANT_TYPE.AUTHORIZATION_CODE) oauth_parameters[OAUTH2_PARAMETERS.CODE] = authorization_code - oauth_parameters[OAUTH2_PARAMETERS.CLIENT_SECRET] = client_secret - - return self._oauth_get_token(oauth_parameters) + if client_secret is not None: + oauth_parameters[OAUTH2_PARAMETERS.CLIENT_SECRET] = client_secret + if code_verifier is not None: + oauth_parameters[OAUTH2_PARAMETERS.CODE_VERIFIER] = code_verifier + token = self._oauth_get_token(oauth_parameters) + self._add_token_into_cache(token) + return token def _get_token_with_refresh_token(self, refresh_token, resource, client_secret): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/user_realm.py new/adal-1.0.2/adal/user_realm.py --- old/adal-0.5.0/adal/user_realm.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/user_realm.py 2018-06-26 21:23:14.000000000 +0200 @@ -143,6 +143,7 @@ operation = 'User Realm Discovery' resp = requests.get(user_realm_url.geturl(), headers=options['headers'], + proxies=self._call_context.get('proxies', None), verify=self._call_context.get('verify_ssl', None)) util.log_return_correlation_id(self._log, operation, resp) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/wstrust_request.py new/adal-1.0.2/adal/wstrust_request.py --- old/adal-0.5.0/adal/wstrust_request.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/wstrust_request.py 2018-06-26 21:23:14.000000000 +0200 @@ -145,7 +145,10 @@ operation = "WS-Trust RST" resp = requests.post(self._wstrust_endpoint_url, headers=options['headers'], data=rst, - allow_redirects=True, verify=self._call_context.get('verify_ssl', None)) + allow_redirects=True, + verify=self._call_context.get('verify_ssl', None), + proxies=self._call_context.get('proxies', None), + timeout=self._call_context.get('timeout', None)) util.log_return_correlation_id(self._log, operation, resp) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal/wstrust_response.py new/adal-1.0.2/adal/wstrust_response.py --- old/adal-0.5.0/adal/wstrust_response.py 2018-01-26 01:05:17.000000000 +0100 +++ new/adal-1.0.2/adal/wstrust_response.py 2018-06-26 21:23:14.000000000 +0200 @@ -55,6 +55,35 @@ return 'RSTR Response: ' + scrubbed_rstr +def findall_content(xml_string, tag): + """ + Given a tag name without any prefix, + this function returns a list of the raw content inside this tag as-is. + + >>> findall_content("<ns0:foo> what <bar> ever </bar> content </ns0:foo>", "foo") + [" what <bar> ever </bar> content "] + + Motivation: + + Usually we would use XML parser to extract the data by xpath. + However the ElementTree in Python will implicitly normalize the output + by "hoisting" the inner inline namespaces into the outmost element. + The result will be a semantically equivalent XML snippet, + but not fully identical to the original one. + While this effect shouldn't become a problem in all other cases, + it does not seem to fully comply with Exclusive XML Canonicalization spec + (https://www.w3.org/TR/xml-exc-c14n/), and void the SAML token signature. + SAML signature algo needs the "XML -> C14N(XML) -> Signed(C14N(Xml))" order. + + The binary extention lxml is probably the canonical way to solve this + (https://stackoverflow.com/questions/22959577/python-exclusive-xml-canonicalization-xml-exc-c14n) + but here we use this workaround, based on Regex, to return raw content as-is. + """ + # \w+ is good enough for https://www.w3.org/TR/REC-xml/#NT-NameChar + pattern = r"<(?:\w+:)?%(tag)s(?:[^>]*)>(.*)</(?:\w+:)?%(tag)s" % {"tag": tag} + return re.findall(pattern, xml_string, re.DOTALL) + + class WSTrustResponse(object): def __init__(self, call_context, response, wstrust_version): @@ -157,6 +186,7 @@ # Adjust namespaces (without this they are autogenerated) so this is understood # by the receiver. Then make a string repr of the element tree node. + # See also http://blog.tomhennigan.co.uk/post/46945128556/elementtree-and-xmlns ET.register_namespace('saml', 'urn:oasis:names:tc:SAML:1.0:assertion') ET.register_namespace('ds', 'http://www.w3.org/2000/09/xmldsig#') @@ -178,6 +208,15 @@ if self.token is None: raise AdalError("Unable to find any tokens in RSTR.") + @staticmethod + def _parse_token_by_re(raw_response): + for rstr in findall_content(raw_response, "RequestSecurityTokenResponse"): + token_types = findall_content(rstr, "TokenType") + tokens = findall_content(rstr, "RequestedSecurityToken") + if token_types and tokens: + return tokens[0].encode('us-ascii'), token_types[0] + + def parse(self): if not self._response: raise AdalError("Received empty RSTR response body.") @@ -195,7 +234,12 @@ str_fault_message = self.fault_message or 'NONE' error_template = 'Server returned error in RSTR - ErrorCode: {} : FaultMessage: {}' raise AdalError(error_template.format(str_error_code, str_fault_message)) - self._parse_token() + + token_found = self._parse_token_by_re(self._response) + if token_found: + self.token, self.token_type = token_found + else: # fallback to old logic + self._parse_token() finally: self._dom = None self._parents = None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/adal-0.5.0/adal.egg-info/PKG-INFO new/adal-1.0.2/adal.egg-info/PKG-INFO --- old/adal-0.5.0/adal.egg-info/PKG-INFO 2018-01-26 01:06:26.000000000 +0100 +++ new/adal-1.0.2/adal.egg-info/PKG-INFO 2018-06-26 21:24:16.000000000 +0200 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: adal -Version: 0.5.0 +Version: 1.0.2 Summary: The ADAL for Python library makes it easy for python application to authenticate to Azure Active Directory (AAD) in order to access AAD protected web resources. Home-page: https://github.com/AzureAD/azure-activedirectory-library-for-python Author: Microsoft Corporation Author-email: nuget...@microsoft.com License: MIT -Description-Content-Type: UNKNOWN Description: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha