Skip to content
This repository has been archived by the owner on Sep 29, 2023. It is now read-only.

Release 1.2.2 #208

Merged
merged 18 commits into from
Jul 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
--------------------|-----------------|---------------
[![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)

|[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)
|[Getting Started](https://github.com/AzureAD/azure-activedirectory-library-for-python/wiki)| [Docs](https://aka.ms/aaddev)| [Python Samples](https://github.com/Azure-Samples?q=active-directory&language=python)| [Support](README.md#community-help-and-support)
| --- | --- | --- | --- |


Expand All @@ -17,27 +17,29 @@ You can learn in detail about ADAL Python functionality and usage documented in
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.

## 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.
We provide a full suite of [Python sample applications on GitHub](https://github.com/Azure-Samples?q=active-directory&language=python) to help you get started with learning the Azure Identity system. This will include 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.

There are also some [lightweight samples existing inside this repo](https://github.com/AzureAD/azure-activedirectory-library-for-python/tree/dev/sample).

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.

## Versions

This library follows [Semantic Versioning](http://semver.org/).
This library follows [Semantic Versioning](https://semver.org/).

You can find the changes for each version under [Releases](https://github.com/AzureAD/azure-activedirectory-library-for-python/releases).

## Community Help and Support

We leverage [Stack Overflow](http://stackoverflow.com/) to work with the community on supporting Azure Active Directory and its SDKs, including this one! We highly recommend you ask your questions on Stack Overflow (we're all on there!) Also browser existing issues to see if someone has had your question before.
We leverage [Stack Overflow](https://stackoverflow.com/) to work with the community on supporting Azure Active Directory and its SDKs, including this one! We highly recommend you ask your questions on Stack Overflow (we're all on there!) Also browser existing issues to see if someone has had your question before.

We recommend you use the "adal" tag so we can see it! Here is the latest Q&A on Stack Overflow for ADAL: [http://stackoverflow.com/questions/tagged/adal](http://stackoverflow.com/questions/tagged/adal)
We recommend you use the "adal" tag so we can see it! Here is the latest Q&A on Stack Overflow for ADAL: [https://stackoverflow.com/questions/tagged/adal](https://stackoverflow.com/questions/tagged/adal)

## Security Reporting

If you find a security issue with our libraries or services please report it to [secure@microsoft.com](mailto:secure@microsoft.com) with as much detail as possible. Your submission may be eligible for a bounty through the [Microsoft Bounty](http://aka.ms/bugbounty) program. Please do not post security issues to GitHub Issues or any other public site. We will contact you shortly upon receiving the information. We encourage you to get notifications of when security incidents occur by visiting [this page](https://technet.microsoft.com/en-us/security/dd252948) and subscribing to Security Advisory Alerts.
If you find a security issue with our libraries or services please report it to [secure@microsoft.com](mailto:secure@microsoft.com) with as much detail as possible. Your submission may be eligible for a bounty through the [Microsoft Bounty](https://aka.ms/bugbounty) program. Please do not post security issues to GitHub Issues or any other public site. We will contact you shortly upon receiving the information. We encourage you to get notifications of when security incidents occur by visiting [this page](https://technet.microsoft.com/en-us/security/dd252948) and subscribing to Security Advisory Alerts.

## Contributing

Expand Down
2 changes: 1 addition & 1 deletion adal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

# pylint: disable=wrong-import-position

__version__ = '1.2.1'
__version__ = '1.2.2'

import logging

Expand Down
2 changes: 1 addition & 1 deletion adal/authentication_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def token_func(self):
def acquire_token_with_authorization_code(self, authorization_code,
redirect_uri, resource,
client_id, client_secret=None, code_verifier=None):
'''Gets a token for a given resource via auhtorization code for a
'''Gets a token for a given resource via authorization code for a
server app.

:param str authorization_code: An authorization code returned from a
Expand Down
7 changes: 6 additions & 1 deletion adal/authority.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,12 @@ def _validate_authority_url(self):

path_parts = [part for part in self._url.path.split('/') if part]
if (len(path_parts) > 1) and (not self._whitelisted()): #if dsts host, path_parts will be 2
raise ValueError("The authority url must be of the format https://login.microsoftonline.com/your_tenant")
raise ValueError(
"The path of authority_url (also known as tenant) is invalid, "
"it should either be a domain name (e.g. mycompany.onmicrosoft.com) "
"or a tenant GUID id. "
'Your tenant input was "%s" and your entire authority_url was "%s".'
% ('/'.join(path_parts), self._url.geturl()))
elif len(path_parts) == 1:
self._url = urlparse(self._url.geturl().rstrip('/'))

Expand Down
17 changes: 16 additions & 1 deletion adal/self_signed_jwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,21 @@ def _raise_on_invalid_jwt_signature(encoded_jwt):
if len(segments) < 3 or not segments[2]:
raise AdalError('Failed to sign JWT. This is most likely due to an invalid certificate.')

def _extract_certs(public_cert_content):
# Parses raw public certificate file contents and returns a list of strings
# Usage: headers = {"x5c": extract_certs(open("my_cert.pem").read())}
public_certificates = re.findall(
r'-----BEGIN CERTIFICATE-----(?P<cert_value>[^-]+)-----END CERTIFICATE-----',
public_cert_content, re.I)
if public_certificates:
return [cert.strip() for cert in public_certificates]
# The public cert tags are not found in the input,
# let's make best effort to exclude a private key pem file.
if "PRIVATE KEY" in public_cert_content:
raise ValueError(
"We expect your public key but detect a private key instead")
return [public_cert_content.strip()]

class SelfSignedJwt(object):

NumCharIn128BitHexString = 128/8*2
Expand All @@ -82,7 +97,7 @@ def _create_header(self, thumbprint, public_certificate):
x5t = _create_x5t_value(thumbprint)
header = {'typ':'JWT', 'alg':'RS256', 'x5t':x5t}
if public_certificate:
header['x5c'] = public_certificate
header['x5c'] = _extract_certs(public_certificate)
self._log.debug("Creating self signed JWT header. x5t: %(x5t)s, x5c: %(x5c)s",
{"x5t": x5t, "x5c": public_certificate})

Expand Down
3 changes: 3 additions & 0 deletions adal/token_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ def __eq__(self, other):
_string_cmp(self.client_id, other.client_id) and \
_string_cmp(self.user_id, other.user_id)

def __ne__(self, other):
return not self == other

# pylint: disable=protected-access

def _get_cache_key(entry):
Expand Down
15 changes: 5 additions & 10 deletions adal/token_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#------------------------------------------------------------------------------

from base64 import b64encode
import re

from . import constants
from . import log
Expand Down Expand Up @@ -257,18 +256,14 @@ def _get_token_username_password_federated(self, username, password):
username, password)
@staticmethod
def _parse_wstrust_version_from_federation_active_authurl(federation_active_authurl):
wstrust2005_regex = r'[/trust]?[2005][/usernamemixed]?'
wstrust13_regex = r'[/trust]?[13][/usernamemixed]?'

if re.search(wstrust2005_regex, federation_active_authurl):
if '/trust/2005/usernamemixed' in federation_active_authurl:
return WSTrustVersion.WSTRUST2005
elif re.search(wstrust13_regex, federation_active_authurl):
if '/trust/13/usernamemixed' in federation_active_authurl:
return WSTrustVersion.WSTRUST13

return WSTrustVersion.UNDEFINED

def get_token_with_username_password(self, username, password):
self._log.info("Acquiring token with username password.")
self._log.debug("Acquiring token with username password.")
self._user_id = username
try:
token = self._find_token_from_cache()
Expand Down Expand Up @@ -301,7 +296,7 @@ def get_token_with_username_password(self, username, password):
return token

def get_token_with_client_credentials(self, client_secret):
self._log.info("Getting token with client credentials.")
self._log.debug("Getting token with client credentials.")
try:
token = self._find_token_from_cache()
if token:
Expand Down Expand Up @@ -347,7 +342,7 @@ def get_token_with_refresh_token(self, refresh_token, client_secret):
return self._get_token_with_refresh_token(refresh_token, None, client_secret)

def get_token_from_cache_with_refresh(self, user_id):
self._log.info("Getting token from cache with refresh if necessary.")
self._log.debug("Getting token from cache with refresh if necessary.")
self._user_id = user_id
return self._find_token_from_cache()

Expand Down
2 changes: 1 addition & 1 deletion adal/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def create_request_options(self, *options):

def log_return_correlation_id(log, operation_message, response):
if response and response.headers and response.headers.get('client-request-id'):
log.info("{} Server returned this correlation_id: {}".format(
log.debug("{} Server returned this correlation_id: {}".format(
operation_message,
response.headers['client-request-id']))

Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
requests==2.20.0
PyJWT==1.0.0
PyJWT==1.7.0
#need 2.x for Python3 support
python-dateutil==2.1.0
#1.1.0 is the first that can be installed on windows
cryptography==2.3.0
cryptography==2.3.1
#for testing
httpretty==0.8.14
pylint==1.5.4
3 changes: 1 addition & 2 deletions tests/test_authority.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,7 @@ def test_bad_url_has_query(self):

@httpretty.activate
def test_url_extra_path_elements(self):
with six.assertRaisesRegex(self, ValueError, "The authority url must be of the format "+
"https://login.microsoftonline.com/your_tenant"):
with six.assertRaisesRegex(self, ValueError, "tenant"): # Some tenant specific error message
context = AuthenticationContext(self.nonHardCodedAuthority + '/extra/path')

@httpretty.activate
Expand Down