Skip to content
Closed
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
36 changes: 20 additions & 16 deletions src/azure-cli-core/azure/cli/core/_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def _normalize_properties(self, user, subscriptions, is_service_principal, cert_
subscription_dict = {
_SUBSCRIPTION_ID: s.id.rpartition('/')[2],
_SUBSCRIPTION_NAME: display_name,
_STATE: s.state.value,
_STATE: s.state,
_USER_ENTITY: {
_USER_NAME: user,
_USER_TYPE: _SERVICE_PRINCIPAL if is_service_principal else _USER
Expand Down Expand Up @@ -815,12 +815,14 @@ def create_arm_client_factory(credentials):
return arm_client_factory(credentials)
from azure.cli.core.profiles._shared import get_client_class
from azure.cli.core.profiles import ResourceType, get_api_version
from azure.cli.core.commands.client_factory import configure_common_settings
from azure.cli.core.commands.client_factory import _prepare_client_kwargs_track2
client_type = get_client_class(ResourceType.MGMT_RESOURCE_SUBSCRIPTIONS)
api_version = get_api_version(cli_ctx, ResourceType.MGMT_RESOURCE_SUBSCRIPTIONS)

client_kwargs = _prepare_client_kwargs_track2(cli_ctx)
# We don't need to change credential_scopes as 'scopes' is ignored by BasicTokenCredential anyway
client = client_type(credentials, api_version=api_version,
base_url=self.cli_ctx.cloud.endpoints.resource_manager)
configure_common_settings(cli_ctx, client)
base_url=self.cli_ctx.cloud.endpoints.resource_manager, **client_kwargs)
return client

self._arm_client_factory = create_arm_client_factory
Expand All @@ -838,9 +840,9 @@ def find_from_user_account(self, username, password, tenant, resource):
self.user_id = token_entry[_TOKEN_ENTRY_USER_ID]

if tenant is None:
result = self._find_using_common_tenant(token_entry[_ACCESS_TOKEN], resource)
result = self._find_using_common_tenant(token_entry, resource)
else:
result = self._find_using_specific_tenant(tenant, token_entry[_ACCESS_TOKEN])
result = self._find_using_specific_tenant(tenant, token_entry)
return result

def find_through_authorization_code_flow(self, tenant, resource, authority_url):
Expand All @@ -857,9 +859,9 @@ def find_through_authorization_code_flow(self, tenant, resource, authority_url):
self.user_id = token_entry[_TOKEN_ENTRY_USER_ID]
logger.warning("You have logged in. Now let us find all the subscriptions to which you have access...")
if tenant is None:
result = self._find_using_common_tenant(token_entry[_ACCESS_TOKEN], resource)
result = self._find_using_common_tenant(token_entry, resource)
else:
result = self._find_using_specific_tenant(tenant, token_entry[_ACCESS_TOKEN])
result = self._find_using_specific_tenant(tenant, token_entry)
return result

def find_through_interactive_flow(self, tenant, resource):
Expand All @@ -869,16 +871,16 @@ def find_through_interactive_flow(self, tenant, resource):
token_entry = context.acquire_token_with_device_code(resource, code, _CLIENT_ID)
self.user_id = token_entry[_TOKEN_ENTRY_USER_ID]
if tenant is None:
result = self._find_using_common_tenant(token_entry[_ACCESS_TOKEN], resource)
result = self._find_using_common_tenant(token_entry, resource)
else:
result = self._find_using_specific_tenant(tenant, token_entry[_ACCESS_TOKEN])
result = self._find_using_specific_tenant(tenant, token_entry)
return result

def find_from_service_principal_id(self, client_id, sp_auth, tenant, resource):
context = self._create_auth_context(tenant, False)
token_entry = sp_auth.acquire_token(context, resource, client_id)
self.user_id = client_id
result = self._find_using_specific_tenant(tenant, token_entry[_ACCESS_TOKEN])
result = self._find_using_specific_tenant(tenant, token_entry)
self.tenants = [tenant]
return result

Expand All @@ -895,16 +897,17 @@ def _create_auth_context(self, tenant, use_token_cache=True):

def _find_using_common_tenant(self, access_token, resource):
import adal
from msrest.authentication import BasicTokenAuthentication
from azure.cli.core.adal_authentication import BasicTokenCredential

all_subscriptions = []
empty_tenants = []
mfa_tenants = []
token_credential = BasicTokenAuthentication({'access_token': access_token})
token_credential = BasicTokenCredential(access_token)
client = self._arm_client_factory(token_credential)
tenants = client.tenants.list()
for t in tenants:
tenant_id = t.tenant_id
logger.debug("Finding subscriptions under tenant %s", tenant_id)
# display_name is available since /tenants?api-version=2018-06-01,
# not available in /tenants?api-version=2016-06-01
if not hasattr(t, 'display_name'):
Expand All @@ -913,6 +916,7 @@ def _find_using_common_tenant(self, access_token, resource):
t.display_name = t.additional_properties.get('displayName')
temp_context = self._create_auth_context(tenant_id)
try:
logger.debug("Acquiring a token with tenant=%s, resource=%s", tenant_id, resource)
temp_credentials = temp_context.acquire_token(resource, self.user_id, _CLIENT_ID)
except adal.AdalError as ex:
# because user creds went through the 'common' tenant, the error here must be
Expand All @@ -927,7 +931,7 @@ def _find_using_common_tenant(self, access_token, resource):
continue
subscriptions = self._find_using_specific_tenant(
tenant_id,
temp_credentials[_ACCESS_TOKEN])
temp_credentials)

if not subscriptions:
empty_tenants.append(t)
Expand Down Expand Up @@ -969,9 +973,9 @@ def _find_using_common_tenant(self, access_token, resource):
return all_subscriptions

def _find_using_specific_tenant(self, tenant, access_token):
from msrest.authentication import BasicTokenAuthentication
from azure.cli.core.adal_authentication import BasicTokenCredential

token_credential = BasicTokenAuthentication({'access_token': access_token})
token_credential = BasicTokenCredential(access_token)
client = self._arm_client_factory(token_credential)
subscriptions = client.subscriptions.list()
all_subscriptions = []
Expand Down
10 changes: 10 additions & 0 deletions src/azure-cli-core/azure/cli/core/adal_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,13 @@ def set_token(self):
def signed_session(self, session=None):
logger.debug("MSIAuthenticationWrapper.signed_session invoked by Track 1 SDK")
super().signed_session(session)


class BasicTokenCredential:
# pylint:disable=too-few-public-methods
"""A Track 2 implementation of msrest.authentication.BasicTokenAuthentication."""
def __init__(self, token_entry):
self.token_entry = token_entry

def get_token(self, *scopes, **kwargs): # pylint:disable=unused-argument
return AccessToken(self.token_entry['accessToken'], int(self.token_entry['expiresIn'] + time.time()))
12 changes: 10 additions & 2 deletions src/azure-cli-core/azure/cli/core/commands/client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,20 @@ def configure_common_settings(cli_ctx, client):
client.config.generate_client_request_id = 'x-ms-client-request-id' not in cli_ctx.data['headers']


def configure_common_settings_track2(cli_ctx):
def _prepare_client_kwargs_track2(cli_ctx):
"""Prepare kwargs for Track 2 SDK client."""
client_kwargs = {}

# Change SSL verification behavior
client_kwargs.update(_debug.change_ssl_cert_verification_track2())

# Enable NetworkTraceLoggingPolicy which logs all headers (except Authorization) without being redacted
client_kwargs['logging_enable'] = True

# Disable ARMHttpLoggingPolicy which logs only allowed headers
from azure.core.pipeline.policies import SansIOHTTPPolicy
client_kwargs['http_logging_policy'] = SansIOHTTPPolicy()

client_kwargs['user_agent'] = get_az_user_agent()

try:
Expand Down Expand Up @@ -169,7 +177,7 @@ def _get_mgmt_service_client(cli_ctx,
client_kwargs.update(kwargs)

if is_track2(client_type):
client_kwargs.update(configure_common_settings_track2(cli_ctx))
client_kwargs.update(_prepare_client_kwargs_track2(cli_ctx))
client_kwargs['credential_scopes'] = resource_to_scopes(resource)

if subscription_bound:
Expand Down
2 changes: 1 addition & 1 deletion src/azure-cli-core/azure/cli/core/tests/test_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def test_subscription_finder_constructor(self, get_api_mock):
cli.cloud.endpoints.resource_manager = 'http://foo_arm'
finder = SubscriptionFinder(cli, None, None, arm_client_factory=None)
result = finder._arm_client_factory(mock.MagicMock())
self.assertEqual(result.config.base_url, 'http://foo_arm')
self.assertEqual(result._client._base_url, 'http://foo_arm')

@mock.patch('adal.AuthenticationContext', autospec=True)
def test_get_auth_info_for_logged_in_service_principal(self, mock_auth_context):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ def test_subscription_finder_constructor(self, get_api_mock):
cli.cloud.endpoints.resource_manager = 'http://foo_arm'
finder = SubscriptionFinder(cli, None, None, arm_client_factory=None)
result = finder._arm_client_factory(mock.MagicMock())
self.assertEqual(result.config.base_url, 'http://foo_arm')
self.assertEqual(result._client._base_url, 'http://foo_arm')

@mock.patch('adal.AuthenticationContext', autospec=True)
def test_get_auth_info_for_logged_in_service_principal(self, mock_auth_context):
Expand Down
2 changes: 1 addition & 1 deletion src/azure-cli-core/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
'requests~=2.22',
'six~=1.12',
'pkginfo>=1.5.0.1',
'azure-mgmt-resource==10.2.0',
'azure-mgmt-resource==15.0.0',
'azure-mgmt-core==1.2.0'
]

Expand Down
2 changes: 1 addition & 1 deletion src/azure-cli/requirements.py3.Darwin.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ azure-mgmt-redhatopenshift==0.1.0
azure-mgmt-redis==7.0.0rc1
azure-mgmt-relay==0.1.0
azure-mgmt-reservations==0.6.0
azure-mgmt-resource==10.2.0
azure-mgmt-resource==15.0.0
azure-mgmt-search==2.1.0
azure-mgmt-security==0.4.1
azure-mgmt-servicebus==0.6.0
Expand Down
2 changes: 1 addition & 1 deletion src/azure-cli/requirements.py3.Linux.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ azure-mgmt-redhatopenshift==0.1.0
azure-mgmt-redis==7.0.0rc1
azure-mgmt-relay==0.1.0
azure-mgmt-reservations==0.6.0
azure-mgmt-resource==10.2.0
azure-mgmt-resource==15.0.0
azure-mgmt-search==2.1.0
azure-mgmt-security==0.4.1
azure-mgmt-servicebus==0.6.0
Expand Down
2 changes: 1 addition & 1 deletion src/azure-cli/requirements.py3.windows.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ azure-mgmt-redhatopenshift==0.1.0
azure-mgmt-redis==7.0.0rc1
azure-mgmt-relay==0.1.0
azure-mgmt-reservations==0.6.0
azure-mgmt-resource==10.2.0
azure-mgmt-resource==15.0.0
azure-mgmt-search==2.1.0
azure-mgmt-security==0.4.1
azure-mgmt-servicebus==0.6.0
Expand Down