Skip to content
Draft
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
31 changes: 12 additions & 19 deletions src/azure-cli-core/azure/cli/core/_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,22 +103,17 @@ def _attach_token_tenant(subscription, tenant, tenant_id_description=None):
"""Attach the token tenant information to the subscription. CLI uses tenant_id to know which token should be used
to access the subscription.

This function supports multiple APIs:
- v2016_06_01: Subscription doesn't have tenant_id
- v2022_12_01:
- Subscription has tenant_id representing the home tenant ID, mapped to home_tenant_id
- TenantIdDescription has default_domain, mapped to tenant_default_domain
- TenantIdDescription has display_name, mapped to tenant_display_name
- Subscription has tenant_id representing the home tenant ID, mapped to home_tenant_id
- TenantIdDescription has default_domain, mapped to tenant_default_domain
- TenantIdDescription has display_name, mapped to tenant_display_name
"""
if hasattr(subscription, "tenant_id"):
setattr(subscription, 'home_tenant_id', subscription.tenant_id)
setattr(subscription, 'home_tenant_id', subscription.tenant_id)
setattr(subscription, 'tenant_id', tenant)

# Attach tenant_default_domain, if available
if tenant_id_description and hasattr(tenant_id_description, "default_domain"):
if tenant_id_description:
# Attach tenant_default_domain
setattr(subscription, 'tenant_default_domain', tenant_id_description.default_domain)
# Attach display_name, if available
if tenant_id_description and hasattr(tenant_id_description, "display_name"):
# Attach display_name
setattr(subscription, 'tenant_display_name', tenant_id_description.display_name)


Expand Down Expand Up @@ -948,18 +943,16 @@ def _transform_subscription_for_multiapi(s, s_dict):
:param s: subscription object
:param s_dict: subscription dict
"""
if hasattr(s, 'home_tenant_id'):
s_dict[_HOME_TENANT_ID] = s.home_tenant_id
s_dict[_HOME_TENANT_ID] = s.home_tenant_id
if hasattr(s, 'tenant_default_domain'):
s_dict[_TENANT_DEFAULT_DOMAIN] = s.tenant_default_domain
if hasattr(s, 'tenant_display_name'):
s_dict[_TENANT_DISPLAY_NAME] = s.tenant_display_name

if hasattr(s, 'managed_by_tenants'):
if s.managed_by_tenants is None:
s_dict[_MANAGED_BY_TENANTS] = None
else:
s_dict[_MANAGED_BY_TENANTS] = [{_TENANT_ID: t.tenant_id} for t in s.managed_by_tenants]
if s.managed_by_tenants is None:
s_dict[_MANAGED_BY_TENANTS] = None
else:
s_dict[_MANAGED_BY_TENANTS] = [{_TENANT_ID: t.tenant_id} for t in s.managed_by_tenants]


def _create_identity_instance(cli_ctx, authority, tenant_id=None, client_id=None):
Expand Down
56 changes: 24 additions & 32 deletions src/azure-cli-core/azure/cli/core/tests/test_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
MOCK_EXPIRES_ON_DATETIME = datetime.datetime.fromtimestamp(MOCK_EXPIRES_ON_INT).strftime("%Y-%m-%d %H:%M:%S.%f")
BEARER = 'Bearer'

MOCK_TENANT_ID = '15027ca3-935c-4327-92a5-da7bfd15c8cb'
MOCK_TENANT_DISPLAY_NAME = 'TEST_TENANT_DISPLAY_NAME'
MOCK_TENANT_DEFAULT_DOMAIN = 'test.onmicrosoft.com'

Expand Down Expand Up @@ -137,7 +138,7 @@ class TestProfile(unittest.TestCase):

@classmethod
def setUpClass(cls):
cls.tenant_id = 'test.onmicrosoft.com'
cls.tenant_id = MOCK_TENANT_ID
cls.tenant_display_name = MOCK_TENANT_DISPLAY_NAME
cls.tenant_default_domain = MOCK_TENANT_DEFAULT_DOMAIN

Expand All @@ -164,29 +165,29 @@ def setUpClass(cls):
managed_by_tenants=cls.managed_by_tenants)

cls.subscription1_output = [{'environmentName': 'AzureCloud',
'homeTenantId': 'test.onmicrosoft.com',
'homeTenantId': MOCK_TENANT_ID,
'id': '1',
'isDefault': True,
'managedByTenants': [{'tenantId': '00000003-0000-0000-0000-000000000000'},
{'tenantId': '00000004-0000-0000-0000-000000000000'}],
'name': 'foo account',
'state': 'Enabled',
'tenantId': 'test.onmicrosoft.com',
'tenantId': MOCK_TENANT_ID,
'user': {
'name': '[email protected]',
'type': 'user'
}}]

cls.subscription1_with_tenant_info_output = [{
'environmentName': 'AzureCloud',
'homeTenantId': 'test.onmicrosoft.com',
'homeTenantId': MOCK_TENANT_ID,
'id': '1',
'isDefault': True,
'managedByTenants': [{'tenantId': '00000003-0000-0000-0000-000000000000'},
{'tenantId': '00000004-0000-0000-0000-000000000000'}],
'name': 'foo account',
'state': 'Enabled',
'tenantId': 'test.onmicrosoft.com',
'tenantId': MOCK_TENANT_ID,
'tenantDisplayName': MOCK_TENANT_DISPLAY_NAME,
'tenantDefaultDomain': MOCK_TENANT_DEFAULT_DOMAIN,
'user': {
Expand All @@ -200,15 +201,16 @@ def setUpClass(cls):
cls.display_name1,
cls.state1,
tenant_id=cls.tenant_id,
managed_by_tenants=cls.managed_by_tenants,
home_tenant_id=cls.tenant_id)
home_tenant_id=cls.tenant_id,
managed_by_tenants=cls.managed_by_tenants)

# Dummy result of azure.cli.core._profile.SubscriptionFinder.find_using_common_tenant
# It also contains tenant information, compared to the result of find_using_specific_tenant
cls.subscription1_with_tenant_info = SubscriptionStub(
cls.id1, cls.display_name1, cls.state1,
tenant_id=cls.tenant_id, managed_by_tenants=cls.managed_by_tenants,
tenant_id=cls.tenant_id,
home_tenant_id=cls.tenant_id,
managed_by_tenants=cls.managed_by_tenants,
tenant_display_name=cls.tenant_display_name, tenant_default_domain=cls.tenant_default_domain)

# Dummy result of azure.cli.core._profile.Profile._normalize_properties
Expand Down Expand Up @@ -490,14 +492,14 @@ def test_login_with_service_principal(self, login_with_service_principal_mock,
subs = profile.login(False, 'my app', {'secret': 'very_secret'}, True, self.tenant_id, use_device_code=True,
allow_no_subscriptions=False)
output = [{'environmentName': 'AzureCloud',
'homeTenantId': 'test.onmicrosoft.com',
'homeTenantId': MOCK_TENANT_ID,
'id': '1',
'isDefault': True,
'managedByTenants': [{'tenantId': '00000003-0000-0000-0000-000000000000'},
{'tenantId': '00000004-0000-0000-0000-000000000000'}],
'name': 'foo account',
'state': 'Enabled',
'tenantId': 'test.onmicrosoft.com',
'tenantId': MOCK_TENANT_ID,
'user': {
'name': 'my app',
'type': 'servicePrincipal'}}]
Expand Down Expand Up @@ -1842,7 +1844,7 @@ def __exit__(self, _2, _3, _4):

class SubscriptionStub(Subscription): # pylint: disable=too-few-public-methods

def __init__(self, id, display_name, state, tenant_id, managed_by_tenants=[], home_tenant_id=None,
def __init__(self, id, display_name, state, tenant_id, home_tenant_id=None, managed_by_tenants=[],
tenant_display_name=None, tenant_default_domain=None): # pylint: disable=redefined-builtin
policies = SubscriptionPolicies()
policies.spending_limit = SpendingLimit.current_period_off
Expand All @@ -1858,8 +1860,7 @@ def __init__(self, id, display_name, state, tenant_id, managed_by_tenants=[], ho
self.managed_by_tenants = managed_by_tenants

# Below attributes are added by CLI. Without them, this denotes a Subscription from SDK
if home_tenant_id:
self.home_tenant_id = home_tenant_id
self.home_tenant_id = home_tenant_id
if tenant_display_name:
self.tenant_display_name = tenant_display_name
if tenant_default_domain:
Expand Down Expand Up @@ -1894,39 +1895,29 @@ def test_attach_token_tenant_v2022_12_01(self):
def test_transform_subscription_for_multiapi(self):

class SimpleSubscription:
pass
def __init__(self):
self.home_tenant_id = tenant_id
self.managed_by_tenants = []

class SimpleManagedByTenant:
pass

tenant_id = "00000001-0000-0000-0000-000000000000"

# No 2019-06-01 property is set.
s = SimpleSubscription()
d = {}
_transform_subscription_for_multiapi(s, d)
assert d == {}

# home_tenant_id is set.
# managed_by_tenants is set, but is []. It is still preserved.
s = SimpleSubscription()
s.home_tenant_id = tenant_id
d = {}
_transform_subscription_for_multiapi(s, d)
assert d == {'homeTenantId': '00000001-0000-0000-0000-000000000000'}
assert d == {'homeTenantId': '00000001-0000-0000-0000-000000000000',
'managedByTenants': []}

# managed_by_tenants is set, but is None. It is still preserved.
s = SimpleSubscription()
s.managed_by_tenants = None
d = {}
_transform_subscription_for_multiapi(s, d)
assert d == {'managedByTenants': None}

# managed_by_tenants is set, but is []. It is still preserved.
s = SimpleSubscription()
s.managed_by_tenants = []
d = {}
_transform_subscription_for_multiapi(s, d)
assert d == {'managedByTenants': []}
assert d == {'homeTenantId': '00000001-0000-0000-0000-000000000000',
'managedByTenants': None}

# managed_by_tenants is set, and has valid items. It is preserved.
s = SimpleSubscription()
Expand All @@ -1935,7 +1926,8 @@ class SimpleManagedByTenant:
s.managed_by_tenants = [t]
d = {}
_transform_subscription_for_multiapi(s, d)
assert d == {'managedByTenants': [{"tenantId": tenant_id}]}
assert d == {'homeTenantId': '00000001-0000-0000-0000-000000000000',
'managedByTenants': [{"tenantId": tenant_id}]}


if __name__ == '__main__':
Expand Down