Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user authentication API to UsernamePasswordCredential #11528

Merged
merged 4 commits into from
May 20, 2020
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
tests
  • Loading branch information
chlowell committed May 19, 2020

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 6e17d52e7ceb090405cc69c4a0127f098e864b64
4 changes: 4 additions & 0 deletions sdk/identity/azure-identity/tests/helpers.py
Original file line number Diff line number Diff line change
@@ -145,6 +145,10 @@ def mock_response(status_code=200, headers=None, json_payload=None):
response.text = lambda encoding=None: json.dumps(json_payload)
response.headers["content-type"] = "application/json"
response.content_type = "application/json"
else:
response.text = lambda encoding=None: ""
response.headers["content-type"] = "text/plain"
response.content_type = "text/plain"
return response


11 changes: 6 additions & 5 deletions sdk/identity/azure-identity/tests/test_browser_credential.py
Original file line number Diff line number Diff line change
@@ -83,16 +83,17 @@ def test_authenticate():
)
record = credential.authenticate(scopes=(scope,))

for auth_record in (record, credential.authentication_record):
assert auth_record.authority == environment
assert auth_record.home_account_id == object_id + "." + home_tenant
assert auth_record.tenant_id == home_tenant
assert auth_record.username == username

# credential should have a cached access token for the scope used in authenticate
with patch(WEBBROWSER_OPEN, Mock(side_effect=Exception("credential should authenticate silently"))):
token = credential.get_token(scope)
assert token.token == access_token

assert record.authority == environment
assert record.home_account_id == object_id + "." + home_tenant
assert record.tenant_id == home_tenant
assert record.username == username


def test_disable_automatic_authentication():
"""When configured for strict silent auth, the credential should raise when silent auth fails"""
10 changes: 5 additions & 5 deletions sdk/identity/azure-identity/tests/test_device_code_credential.py
Original file line number Diff line number Diff line change
@@ -78,16 +78,16 @@ def test_authenticate():
_cache=TokenCache(),
)
record = credential.authenticate(scopes=(scope,))
for auth_record in (record, credential.authentication_record):
assert auth_record.authority == environment
assert auth_record.home_account_id == object_id + "." + home_tenant
assert auth_record.tenant_id == home_tenant
assert auth_record.username == username

# credential should have a cached access token for the scope used in authenticate
token = credential.get_token(scope)
assert token.token == access_token

assert record.authority == environment
assert record.home_account_id == object_id + "." + home_tenant
assert record.tenant_id == home_tenant
assert record.username == username


def test_disable_automatic_authentication():
"""When configured for strict silent auth, the credential should raise when silent auth fails"""
Original file line number Diff line number Diff line change
@@ -2,14 +2,14 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# ------------------------------------
from azure.core.exceptions import ClientAuthenticationError
from azure.core.pipeline.policies import SansIOHTTPPolicy
from azure.identity import UsernamePasswordCredential
from azure.identity._internal.user_agent import USER_AGENT
import pytest

from helpers import (
build_aad_response,
build_id_token,
get_discovery_response,
mock_response,
Request,
@@ -26,7 +26,7 @@ def test_no_scopes():
"""The credential should raise when get_token is called with no scopes"""

credential = UsernamePasswordCredential("client-id", "username", "password")
with pytest.raises(ClientAuthenticationError):
with pytest.raises(ValueError):
xiangyan99 marked this conversation as resolved.
Show resolved Hide resolved
credential.get_token()


@@ -88,13 +88,50 @@ def test_username_password_credential():
assert token.token == expected_token


def test_cache_persistence():
"""The credential should cache only in memory"""
def test_authenticate():
client_id = "client-id"
environment = "localhost"
issuer = "https://" + environment
tenant_id = "some-tenant"
authority = issuer + "/" + tenant_id

expected_cache = Mock()
raise_when_called = Mock(side_effect=Exception("credential shouldn't attempt to load a persistent cache"))
with patch.multiple("msal_extensions.token_cache", WindowsTokenCache=raise_when_called):
with patch("msal.TokenCache", Mock(return_value=expected_cache)):
credential = UsernamePasswordCredential("...", "...", "...")
access_token = "***"
scope = "scope"

assert credential._cache is expected_cache
# mock AAD response with id token
object_id = "object-id"
home_tenant = "home-tenant-id"
username = "[email protected]"
id_token = build_id_token(aud=client_id, iss=issuer, object_id=object_id, tenant_id=home_tenant, username=username)
auth_response = build_aad_response(
uid=object_id, utid=home_tenant, access_token=access_token, refresh_token="**", id_token=id_token
)

transport = validating_transport(
requests=[Request(url_substring=issuer)] * 4,
responses=[
get_discovery_response(authority), # instance discovery
get_discovery_response(authority), # tenant discovery
mock_response(status_code=404), # user realm discovery
mock_response(json_payload=auth_response), # token request following authenticate()
],
)

credential = UsernamePasswordCredential(
username=username,
password="1234",
authority=environment,
client_id=client_id,
tenant_id=tenant_id,
transport=transport,
)
record = credential.authenticate(scopes=(scope,))
for auth_record in (record, credential.authentication_record):
assert auth_record.authority == environment
assert auth_record.home_account_id == object_id + "." + home_tenant
assert auth_record.tenant_id == home_tenant
assert auth_record.username == username

# credential should have a cached access token for the scope passed to authenticate
token = credential.get_token(scope)
assert token.token == access_token