Skip to content
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
15 changes: 13 additions & 2 deletions sdk/identity/azure-identity/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
# Release History

## 1.5.0b2 (2020-10-06)
## 1.5.0b2 (2020-10-07)
### Fixed
- `AzureCliCredential.get_token` correctly sets token expiration time,
preventing clients from using expired tokens
([#14345](https://github.com/Azure/azure-sdk-for-python/issues/14345))

### Changed
- Adopted msal-extensions 0.3.0
([#13107](https://github.com/Azure/azure-sdk-for-python/issues/13107))
([#13107](https://github.com/Azure/azure-sdk-for-python/issues/13107))

## 1.4.1 (2020-10-07)
### Fixed
- `AzureCliCredential.get_token` correctly sets token expiration time,
preventing clients from using expired tokens
([#14345](https://github.com/Azure/azure-sdk-for-python/issues/14345))

## 1.5.0b1 (2020-09-08)
### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import platform
import re
import sys
import time
from typing import TYPE_CHECKING

import subprocess
Expand Down Expand Up @@ -67,14 +68,18 @@ def get_token(self, *scopes, **kwargs): # pylint:disable=no-self-use,unused-arg
def parse_token(output):
"""Parse output of 'az account get-access-token' to an AccessToken.

In particular, convert the CLI's "expiresOn" value, the string representation of a naive datetime, to epoch seconds.
In particular, convert the "expiresOn" value to epoch seconds. This value is a naive local datetime as returned by
datetime.fromtimestamp.
"""
try:
token = json.loads(output)
parsed_expires_on = datetime.strptime(token["expiresOn"], "%Y-%m-%d %H:%M:%S.%f")

# calculate seconds since the epoch; parsed_expires_on is naive
expires_on = (parsed_expires_on - datetime.fromtimestamp(0)).total_seconds()
dt = datetime.strptime(token["expiresOn"], "%Y-%m-%d %H:%M:%S.%f")
if hasattr(dt, "timestamp"):
# Python >= 3.3
expires_on = dt.timestamp()
else:
# taken from Python 3.5's datetime.timestamp()
expires_on = time.mktime((dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, -1, -1, -1))

return AccessToken(token["accessToken"], int(expires_on))
except (KeyError, ValueError):
Expand Down
7 changes: 3 additions & 4 deletions sdk/identity/azure-identity/tests/test_cli_credential.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,10 @@ def test_get_token():
"""The credential should parse the CLI's output to an AccessToken"""

access_token = "access token"
valid_seconds = 42
expected_expires_on = 1602015811
successful_output = json.dumps(
{
# expiresOn is a naive datetime representing valid_seconds from the epoch
"expiresOn": datetime.fromtimestamp(valid_seconds).strftime("%Y-%m-%d %H:%M:%S.%f"),
"expiresOn": datetime.fromtimestamp(expected_expires_on).strftime("%Y-%m-%d %H:%M:%S.%f"),
"accessToken": access_token,
"subscription": "some-guid",
"tenant": "some-guid",
Expand All @@ -68,7 +67,7 @@ def test_get_token():

assert token.token == access_token
assert type(token.expires_on) == int
assert token.expires_on == valid_seconds
assert token.expires_on == expected_expires_on


def test_cli_not_installed_linux():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,10 @@ async def test_get_token():
"""The credential should parse the CLI's output to an AccessToken"""

access_token = "access token"
valid_seconds = 42
expected_expires_on = 1602015811
successful_output = json.dumps(
{
# expiresOn is a naive datetime representing valid_seconds from the epoch
"expiresOn": datetime.fromtimestamp(valid_seconds).strftime("%Y-%m-%d %H:%M:%S.%f"),
"expiresOn": datetime.fromtimestamp(expected_expires_on).strftime("%Y-%m-%d %H:%M:%S.%f"),
"accessToken": access_token,
"subscription": "some-guid",
"tenant": "some-guid",
Expand All @@ -93,7 +92,7 @@ async def test_get_token():

assert token.token == access_token
assert type(token.expires_on) == int
assert token.expires_on == valid_seconds
assert token.expires_on == expected_expires_on


async def test_cli_not_installed_linux():
Expand Down