diff --git a/src/azure-cli-core/azure/cli/core/tests/test_util.py b/src/azure-cli-core/azure/cli/core/tests/test_util.py index 84a57be1ed5..c2b5405fea2 100644 --- a/src/azure-cli-core/azure/cli/core/tests/test_util.py +++ b/src/azure-cli-core/azure/cli/core/tests/test_util.py @@ -380,26 +380,38 @@ def test_send_raw_requests(self, send_mock, get_raw_token_mock): def test_scopes_to_resource(self): from azure.cli.core.util import scopes_to_resource # scopes as a list - self.assertEqual(scopes_to_resource(['https://management.core.windows.net/.default']), + self.assertEqual(scopes_to_resource(['https://management.core.windows.net//.default']), 'https://management.core.windows.net/') # scopes as a tuple self.assertEqual(scopes_to_resource(('https://storage.azure.com/.default',)), - 'https://storage.azure.com/') + 'https://storage.azure.com') - # Double slashes are reduced + # resource with trailing slash + self.assertEqual(scopes_to_resource(('https://management.azure.com//.default',)), + 'https://management.azure.com/') self.assertEqual(scopes_to_resource(['https://datalake.azure.net//.default']), 'https://datalake.azure.net/') + # resource without trailing slash + self.assertEqual(scopes_to_resource(('https://managedhsm.azure.com/.default',)), + 'https://managedhsm.azure.com') + def test_resource_to_scopes(self): from azure.cli.core.util import resource_to_scopes # resource converted to a scopes list self.assertEqual(resource_to_scopes('https://management.core.windows.net/'), - ['https://management.core.windows.net/.default']) + ['https://management.core.windows.net//.default']) - # Use double slashes for certain services + # resource with trailing slash + self.assertEqual(resource_to_scopes('https://management.azure.com/'), + ['https://management.azure.com//.default']) self.assertEqual(resource_to_scopes('https://datalake.azure.net/'), ['https://datalake.azure.net//.default']) + # resource without trailing slash + self.assertEqual(resource_to_scopes('https://managedhsm.azure.com'), + ['https://managedhsm.azure.com/.default']) + class TestBase64ToHex(unittest.TestCase): diff --git a/src/azure-cli-core/azure/cli/core/util.py b/src/azure-cli-core/azure/cli/core/util.py index e85f32be8d6..aa15a16d041 100644 --- a/src/azure-cli-core/azure/cli/core/util.py +++ b/src/azure-cli-core/azure/cli/core/util.py @@ -1169,32 +1169,32 @@ def handle_version_update(): def resource_to_scopes(resource): """Convert the ADAL resource ID to MSAL scopes by appending the /.default suffix and return a list. - For example: 'https://management.core.windows.net/' -> ['https://management.core.windows.net/.default'] + For example: + 'https://management.core.windows.net/' -> ['https://management.core.windows.net//.default'] + 'https://managedhsm.azure.com' -> ['https://managedhsm.azure.com/.default'] + :param resource: The ADAL resource ID :return: A list of scopes """ - if 'datalake' in resource or 'batch' in resource or 'database' in resource: - # For datalake, batch and database, the slash must be doubled due to service issue, like - # https://datalake.azure.net//.default - # TODO: This should be fixed on the service side. - scope = resource + '/.default' - else: - scope = resource.rstrip('/') + '/.default' + # https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#trailing-slash-and-default + # We should not trim the trailing slash, like in https://management.azure.com/ + # In other word, the trailing slash should be preserved and scope should be https://management.azure.com//.default + scope = resource + '/.default' return [scope] def scopes_to_resource(scopes): """Convert MSAL scopes to ADAL resource by stripping the /.default suffix and return a str. - For example: ['https://management.core.windows.net/.default'] -> 'https://management.core.windows.net/' + For example: + ['https://management.core.windows.net//.default'] -> 'https://management.core.windows.net/' + ['https://managedhsm.azure.com/.default'] -> 'https://managedhsm.azure.com' :param scopes: The MSAL scopes. It can be a list or tuple of string :return: The ADAL resource :rtype: str """ scope = scopes[0] - if scope.endswith(".default"): - scope = scope[:-len(".default")] + if scope.endswith("/.default"): + scope = scope[:-len("/.default")] - # Trim extra ending slashes. https://datalake.azure.net// -> https://datalake.azure.net/ - scope = scope.rstrip('/') + '/' return scope