From 25912763773261340f880bab8f5e360ebc5f735c Mon Sep 17 00:00:00 2001 From: Jiashuo Li <4003950+jiasli@users.noreply.github.com> Date: Tue, 14 Jun 2022 11:58:21 +0800 Subject: [PATCH] [Graph] Support special characters in object names (#22739) --- .../azure/cli/testsdk/__init__.py | 4 +- .../azure/cli/testsdk/utilities.py | 27 +- .../role/_msgrpah/_graph_client.py | 5 +- .../recordings/test_special_characters.yaml | 369 ++++++++++++++++++ .../role/tests/latest/test_graph.py | 35 +- 5 files changed, 424 insertions(+), 16 deletions(-) create mode 100644 src/azure-cli/azure/cli/command_modules/role/tests/latest/recordings/test_special_characters.yaml diff --git a/src/azure-cli-testsdk/azure/cli/testsdk/__init__.py b/src/azure-cli-testsdk/azure/cli/testsdk/__init__.py index af21d296bb9..ae5429e7f7c 100644 --- a/src/azure-cli-testsdk/azure/cli/testsdk/__init__.py +++ b/src/azure-cli-testsdk/azure/cli/testsdk/__init__.py @@ -13,7 +13,7 @@ from .checkers import (JMESPathCheck, JMESPathCheckExists, JMESPathCheckGreaterThan, NoneCheck, StringCheck, StringContainCheck) from .decorators import api_version_constraint -from .utilities import create_random_name, MSGraphUserReplacer +from .utilities import create_random_name, MSGraphNameReplacer from .patches import MOCKED_USER_NAME __all__ = ['ScenarioTest', 'LiveScenarioTest', 'ResourceGroupPreparer', 'StorageAccountPreparer', @@ -21,7 +21,7 @@ 'ManagedApplicationPreparer', 'CliTestError', 'JMESPathCheck', 'JMESPathCheckExists', 'NoneCheck', 'live_only', 'record_only', 'StringCheck', 'StringContainCheck', 'get_sha1_hash', 'KeyVaultPreparer', 'JMESPathCheckGreaterThan', 'api_version_constraint', - 'create_random_name', 'MOCKED_USER_NAME', 'MSGraphUserReplacer', 'LocalContextScenarioTest', + 'create_random_name', 'MOCKED_USER_NAME', 'MSGraphNameReplacer', 'LocalContextScenarioTest', 'VirtualNetworkPreparer', 'VnetNicPreparer', 'LogAnalyticsWorkspacePreparer'] diff --git a/src/azure-cli-testsdk/azure/cli/testsdk/utilities.py b/src/azure-cli-testsdk/azure/cli/testsdk/utilities.py index cb9f1621388..7d5cdabc04b 100644 --- a/src/azure-cli-testsdk/azure/cli/testsdk/utilities.py +++ b/src/azure-cli-testsdk/azure/cli/testsdk/utilities.py @@ -180,26 +180,33 @@ def process_response(self, response): return response -class MSGraphUserReplacer(RecordingProcessor): - def __init__(self, test_user, mock_user): - self.test_user = test_user - self.mock_user = mock_user +class MSGraphNameReplacer(RecordingProcessor): + """If a name appears in URL, it should be percent-encoded, e.g. + - test-name+/ is encoded as test-name%2B%2F + - example@example.com is encoded as example%40example.com + + Theoretically, GeneralNameReplacer should also follow this pattern, but since we haven't seen any ARM name that + is percent-encoded, we only replace percent-encoded names for MS Graph for better test performance. + """ + def __init__(self, test_name, mock_name): + from urllib.parse import quote + self.test_name = test_name + self.test_name_encoded = quote(test_name, safe='') + self.mock_name = mock_name + self.mock_name_encoded = quote(mock_name, safe='') def process_request(self, request): - if self.test_user in request.uri: - request.uri = request.uri.replace(self.test_user, self.mock_user) + request.uri = request.uri.replace(self.test_name_encoded, self.mock_name_encoded) if request.body: body = _byte_to_str(request.body) - if self.test_user in body: - request.body = body.replace(self.test_user, self.mock_user) + request.body = body.replace(self.test_name, self.mock_name) return request def process_response(self, response): if response['body']['string']: - response['body']['string'] = response['body']['string'].replace(self.test_user, - self.mock_user) + response['body']['string'] = response['body']['string'].replace(self.test_name, self.mock_name) return response diff --git a/src/azure-cli/azure/cli/command_modules/role/_msgrpah/_graph_client.py b/src/azure-cli/azure/cli/command_modules/role/_msgrpah/_graph_client.py index 58cd3de51b1..f0979e465dc 100644 --- a/src/azure-cli/azure/cli/command_modules/role/_msgrpah/_graph_client.py +++ b/src/azure-cli/azure/cli/command_modules/role/_msgrpah/_graph_client.py @@ -296,7 +296,10 @@ def oauth2_permission_grant_delete(self, id): def _filter_to_query(filter): if filter is not None: - return "?$filter={}".format(filter) + # https://docs.microsoft.com/en-us/graph/query-parameters#encoding-query-parameters + # The values of query parameters should be percent-encoded. + from urllib.parse import quote + return "?$filter={}".format(quote(filter, safe='')) return '' diff --git a/src/azure-cli/azure/cli/command_modules/role/tests/latest/recordings/test_special_characters.yaml b/src/azure-cli/azure/cli/command_modules/role/tests/latest/recordings/test_special_characters.yaml new file mode 100644 index 00000000000..38bdd80efa3 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/role/tests/latest/recordings/test_special_characters.yaml @@ -0,0 +1,369 @@ +interactions: +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - ad group create + Connection: + - keep-alive + ParameterSetName: + - --display-name --mail-nickname + User-Agent: + - python/3.10.4 (Windows-10-10.0.22000-SP0) AZURECLI/2.37.0 + method: GET + uri: https://graph.microsoft.com/v1.0/groups?$filter=displayName%20eq%20%27azure-cli-test-group%2B%2F000001%27%20and%20mailNickname%20eq%20%27deleteme11%27 + response: + body: + string: '{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups","value":[]}' + headers: + cache-control: + - no-cache + content-length: + - '81' + content-type: + - application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8 + date: + - Fri, 10 Jun 2022 03:13:43 GMT + odata-version: + - '4.0' + request-id: + - 7cc946f1-b303-42d1-8727-0d77d632d1cc + strict-transport-security: + - max-age=31536000 + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-ms-ags-diagnostic: + - '{"ServerInfo":{"DataCenter":"Southeast Asia","Slice":"E","Ring":"5","ScaleUnit":"001","RoleInstance":"SI2PEPF000018C7"}}' + x-ms-resource-unit: + - '1' + status: + code: 200 + message: OK +- request: + body: '{"displayName": "azure-cli-test-group+/000001", "mailNickname": "deleteme11", + "mailEnabled": false, "securityEnabled": true}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - ad group create + Connection: + - keep-alive + Content-Length: + - '124' + Content-Type: + - application/json + ParameterSetName: + - --display-name --mail-nickname + User-Agent: + - python/3.10.4 (Windows-10-10.0.22000-SP0) AZURECLI/2.37.0 + method: POST + uri: https://graph.microsoft.com/v1.0/groups + response: + body: + string: '{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups/$entity","id":"795b1624-5b39-4705-bfea-48a52592e18f","deletedDateTime":null,"classification":null,"createdDateTime":"2022-06-10T03:13:45Z","creationOptions":[],"description":null,"displayName":"azure-cli-test-group+/000001","expirationDateTime":null,"groupTypes":[],"isAssignableToRole":null,"mail":null,"mailEnabled":false,"mailNickname":"deleteme11","membershipRule":null,"membershipRuleProcessingState":null,"onPremisesDomainName":null,"onPremisesLastSyncDateTime":null,"onPremisesNetBiosName":null,"onPremisesSamAccountName":null,"onPremisesSecurityIdentifier":null,"onPremisesSyncEnabled":null,"preferredDataLocation":null,"preferredLanguage":null,"proxyAddresses":[],"renewedDateTime":"2022-06-10T03:13:45Z","resourceBehaviorOptions":[],"resourceProvisioningOptions":[],"securityEnabled":true,"securityIdentifier":"S-1-12-1-2036012580-1191533369-2773019327-2413924901","theme":null,"visibility":null,"onPremisesProvisioningErrors":[]}' + headers: + cache-control: + - no-cache + content-length: + - '1009' + content-type: + - application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8 + date: + - Fri, 10 Jun 2022 03:13:45 GMT + location: + - https://graph.microsoft.com/v2/54826b22-38d6-4fb2-bad9-b7b93a3e9c5a/directoryObjects/795b1624-5b39-4705-bfea-48a52592e18f/Microsoft.DirectoryServices.Group + odata-version: + - '4.0' + request-id: + - 93d57688-c0a6-4ecc-aad5-887984907899 + strict-transport-security: + - max-age=31536000 + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-ms-ags-diagnostic: + - '{"ServerInfo":{"DataCenter":"Southeast Asia","Slice":"E","Ring":"5","ScaleUnit":"001","RoleInstance":"SI2PEPF000023FD"}}' + x-ms-resource-unit: + - '1' + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - ad group show + Connection: + - keep-alive + ParameterSetName: + - --group + User-Agent: + - python/3.10.4 (Windows-10-10.0.22000-SP0) AZURECLI/2.37.0 + method: GET + uri: https://graph.microsoft.com/v1.0/groups?$filter=displayName%20eq%20%27azure-cli-test-group%2B%2F000001%27 + response: + body: + string: '{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups","value":[{"id":"795b1624-5b39-4705-bfea-48a52592e18f","deletedDateTime":null,"classification":null,"createdDateTime":"2022-06-10T03:13:45Z","creationOptions":[],"description":null,"displayName":"azure-cli-test-group+/000001","expirationDateTime":null,"groupTypes":[],"isAssignableToRole":null,"mail":null,"mailEnabled":false,"mailNickname":"deleteme11","membershipRule":null,"membershipRuleProcessingState":null,"onPremisesDomainName":null,"onPremisesLastSyncDateTime":null,"onPremisesNetBiosName":null,"onPremisesSamAccountName":null,"onPremisesSecurityIdentifier":null,"onPremisesSyncEnabled":null,"preferredDataLocation":null,"preferredLanguage":null,"proxyAddresses":[],"renewedDateTime":"2022-06-10T03:13:45Z","resourceBehaviorOptions":[],"resourceProvisioningOptions":[],"securityEnabled":true,"securityIdentifier":"S-1-12-1-2036012580-1191533369-2773019327-2413924901","theme":null,"visibility":null,"onPremisesProvisioningErrors":[]}]}' + headers: + cache-control: + - no-cache + content-length: + - '1013' + content-type: + - application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8 + date: + - Fri, 10 Jun 2022 03:13:46 GMT + odata-version: + - '4.0' + request-id: + - 4b5ce3c2-8888-4a19-b5dc-5c637030744a + strict-transport-security: + - max-age=31536000 + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-ms-ags-diagnostic: + - '{"ServerInfo":{"DataCenter":"Southeast Asia","Slice":"E","Ring":"5","ScaleUnit":"001","RoleInstance":"SI2PEPF00000BCC"}}' + x-ms-resource-unit: + - '1' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - ad group show + Connection: + - keep-alive + ParameterSetName: + - --group + User-Agent: + - python/3.10.4 (Windows-10-10.0.22000-SP0) AZURECLI/2.37.0 + method: GET + uri: https://graph.microsoft.com/v1.0/groups/795b1624-5b39-4705-bfea-48a52592e18f + response: + body: + string: '{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups/$entity","id":"795b1624-5b39-4705-bfea-48a52592e18f","deletedDateTime":null,"classification":null,"createdDateTime":"2022-06-10T03:13:45Z","creationOptions":[],"description":null,"displayName":"azure-cli-test-group+/000001","expirationDateTime":null,"groupTypes":[],"isAssignableToRole":null,"mail":null,"mailEnabled":false,"mailNickname":"deleteme11","membershipRule":null,"membershipRuleProcessingState":null,"onPremisesDomainName":null,"onPremisesLastSyncDateTime":null,"onPremisesNetBiosName":null,"onPremisesSamAccountName":null,"onPremisesSecurityIdentifier":null,"onPremisesSyncEnabled":null,"preferredDataLocation":null,"preferredLanguage":null,"proxyAddresses":[],"renewedDateTime":"2022-06-10T03:13:45Z","resourceBehaviorOptions":[],"resourceProvisioningOptions":[],"securityEnabled":true,"securityIdentifier":"S-1-12-1-2036012580-1191533369-2773019327-2413924901","theme":null,"visibility":null,"onPremisesProvisioningErrors":[]}' + headers: + cache-control: + - no-cache + content-length: + - '1009' + content-type: + - application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8 + date: + - Fri, 10 Jun 2022 03:13:47 GMT + odata-version: + - '4.0' + request-id: + - 82309287-35c3-4ab2-963e-0f6f4b79b6d6 + strict-transport-security: + - max-age=31536000 + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-ms-ags-diagnostic: + - '{"ServerInfo":{"DataCenter":"Southeast Asia","Slice":"E","Ring":"5","ScaleUnit":"001","RoleInstance":"SI2PEPF00001642"}}' + x-ms-resource-unit: + - '1' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - ad group list + Connection: + - keep-alive + ParameterSetName: + - --display-name + User-Agent: + - python/3.10.4 (Windows-10-10.0.22000-SP0) AZURECLI/2.37.0 + method: GET + uri: https://graph.microsoft.com/v1.0/groups?$filter=startswith%28displayName%2C%27azure-cli-test-group%2B%2F000001%27%29 + response: + body: + string: '{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups","value":[{"id":"795b1624-5b39-4705-bfea-48a52592e18f","deletedDateTime":null,"classification":null,"createdDateTime":"2022-06-10T03:13:45Z","creationOptions":[],"description":null,"displayName":"azure-cli-test-group+/000001","expirationDateTime":null,"groupTypes":[],"isAssignableToRole":null,"mail":null,"mailEnabled":false,"mailNickname":"deleteme11","membershipRule":null,"membershipRuleProcessingState":null,"onPremisesDomainName":null,"onPremisesLastSyncDateTime":null,"onPremisesNetBiosName":null,"onPremisesSamAccountName":null,"onPremisesSecurityIdentifier":null,"onPremisesSyncEnabled":null,"preferredDataLocation":null,"preferredLanguage":null,"proxyAddresses":[],"renewedDateTime":"2022-06-10T03:13:45Z","resourceBehaviorOptions":[],"resourceProvisioningOptions":[],"securityEnabled":true,"securityIdentifier":"S-1-12-1-2036012580-1191533369-2773019327-2413924901","theme":null,"visibility":null,"onPremisesProvisioningErrors":[]}]}' + headers: + cache-control: + - no-cache + content-length: + - '1013' + content-type: + - application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8 + date: + - Fri, 10 Jun 2022 03:13:48 GMT + odata-version: + - '4.0' + request-id: + - 09b9fd42-f9f1-4981-9d05-aa2a72875683 + strict-transport-security: + - max-age=31536000 + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-ms-ags-diagnostic: + - '{"ServerInfo":{"DataCenter":"Southeast Asia","Slice":"E","Ring":"5","ScaleUnit":"001","RoleInstance":"SI2PEPF00001E1E"}}' + x-ms-resource-unit: + - '1' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - ad group delete + Connection: + - keep-alive + ParameterSetName: + - --group + User-Agent: + - python/3.10.4 (Windows-10-10.0.22000-SP0) AZURECLI/2.37.0 + method: GET + uri: https://graph.microsoft.com/v1.0/groups?$filter=displayName%20eq%20%27azure-cli-test-group%2B%2F000001%27 + response: + body: + string: '{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups","value":[{"id":"795b1624-5b39-4705-bfea-48a52592e18f","deletedDateTime":null,"classification":null,"createdDateTime":"2022-06-10T03:13:45Z","creationOptions":[],"description":null,"displayName":"azure-cli-test-group+/000001","expirationDateTime":null,"groupTypes":[],"isAssignableToRole":null,"mail":null,"mailEnabled":false,"mailNickname":"deleteme11","membershipRule":null,"membershipRuleProcessingState":null,"onPremisesDomainName":null,"onPremisesLastSyncDateTime":null,"onPremisesNetBiosName":null,"onPremisesSamAccountName":null,"onPremisesSecurityIdentifier":null,"onPremisesSyncEnabled":null,"preferredDataLocation":null,"preferredLanguage":null,"proxyAddresses":[],"renewedDateTime":"2022-06-10T03:13:45Z","resourceBehaviorOptions":[],"resourceProvisioningOptions":[],"securityEnabled":true,"securityIdentifier":"S-1-12-1-2036012580-1191533369-2773019327-2413924901","theme":null,"visibility":null,"onPremisesProvisioningErrors":[]}]}' + headers: + cache-control: + - no-cache + content-length: + - '1013' + content-type: + - application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8 + date: + - Fri, 10 Jun 2022 03:13:49 GMT + odata-version: + - '4.0' + request-id: + - 7b393c81-62e7-4640-8677-e13625417e0c + strict-transport-security: + - max-age=31536000 + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-ms-ags-diagnostic: + - '{"ServerInfo":{"DataCenter":"Southeast Asia","Slice":"E","Ring":"5","ScaleUnit":"001","RoleInstance":"SI2PEPF00001643"}}' + x-ms-resource-unit: + - '1' + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - ad group delete + Connection: + - keep-alive + Content-Length: + - '0' + ParameterSetName: + - --group + User-Agent: + - python/3.10.4 (Windows-10-10.0.22000-SP0) AZURECLI/2.37.0 + method: DELETE + uri: https://graph.microsoft.com/v1.0/groups/795b1624-5b39-4705-bfea-48a52592e18f + response: + body: + string: '' + headers: + cache-control: + - no-cache + date: + - Fri, 10 Jun 2022 03:13:51 GMT + request-id: + - 025f2140-3b2b-4c3a-a025-28cc508ab089 + strict-transport-security: + - max-age=31536000 + x-ms-ags-diagnostic: + - '{"ServerInfo":{"DataCenter":"Southeast Asia","Slice":"E","Ring":"5","ScaleUnit":"001","RoleInstance":"SI2PEPF000023FA"}}' + x-ms-resource-unit: + - '1' + status: + code: 204 + message: No Content +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + CommandName: + - ad group list + Connection: + - keep-alive + ParameterSetName: + - --display-name + User-Agent: + - python/3.10.4 (Windows-10-10.0.22000-SP0) AZURECLI/2.37.0 + method: GET + uri: https://graph.microsoft.com/v1.0/groups?$filter=startswith%28displayName%2C%27azure-cli-test-group%2B%2F000001%27%29 + response: + body: + string: '{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups","value":[]}' + headers: + cache-control: + - no-cache + content-length: + - '81' + content-type: + - application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8 + date: + - Fri, 10 Jun 2022 03:13:52 GMT + odata-version: + - '4.0' + request-id: + - c26c2963-89a3-4557-aa18-eb5a608be6fb + strict-transport-security: + - max-age=31536000 + transfer-encoding: + - chunked + vary: + - Accept-Encoding + x-ms-ags-diagnostic: + - '{"ServerInfo":{"DataCenter":"Southeast Asia","Slice":"E","Ring":"5","ScaleUnit":"001","RoleInstance":"SI2PEPF000022D6"}}' + x-ms-resource-unit: + - '1' + status: + code: 200 + message: OK +version: 1 diff --git a/src/azure-cli/azure/cli/command_modules/role/tests/latest/test_graph.py b/src/azure-cli/azure/cli/command_modules/role/tests/latest/test_graph.py index d24c19691d6..0dbfd3aad38 100644 --- a/src/azure-cli/azure/cli/command_modules/role/tests/latest/test_graph.py +++ b/src/azure-cli/azure/cli/command_modules/role/tests/latest/test_graph.py @@ -12,7 +12,7 @@ import dateutil.parser from azure.cli.testsdk.scenario_tests import AllowLargeResponse from azure.cli.testsdk.scenario_tests.const import MOCKED_TENANT_ID -from azure.cli.testsdk import ScenarioTest, MSGraphUserReplacer, MOCKED_USER_NAME +from azure.cli.testsdk import ScenarioTest, MSGraphNameReplacer, MOCKED_USER_NAME from knack.util import CLIError from azure.cli.testsdk import ScenarioTest, LiveScenarioTest, ResourceGroupPreparer, KeyVaultPreparer @@ -363,7 +363,7 @@ def test_app_owner(self): 'owner': owner, 'display_name': self.create_random_name('azure-cli-test', 30) } - self.recording_processors.append(MSGraphUserReplacer(owner, 'example@example.com')) + self.recording_processors.append(MSGraphNameReplacer(owner, 'example@example.com')) self.kwargs['owner_object_id'] = self.cmd('ad user show --id {owner}').get_output_in_json()['id'] self.kwargs['app_id'] = self.cmd('ad app create --display-name {display_name}').get_output_in_json()['appId'] @@ -753,7 +753,7 @@ def test_group_scenario(self): 'app_name': self.create_random_name(prefix='testgroupapp', length=24) } - self.recording_processors.append(MSGraphUserReplacer('@' + domain, '@example.com')) + self.recording_processors.append(MSGraphNameReplacer('@' + domain, '@example.com')) try: # create group group_result = self.cmd( @@ -879,6 +879,35 @@ def test_group_scenario(self): self.clean_resource(self.kwargs['app_id'], type='app') +class MiscellaneousScenarioTest(GraphScenarioTestBase): + def test_special_characters(self): + # Test special characters in object names. Ensure these characters are correctly percent-encoded. + # For example, displayName with +(%2B), /(%2F) + from azure.cli.testsdk.scenario_tests.utilities import create_random_name + prefix = 'azure-cli-test-group+/' + mock_name = prefix + '000001' + if self.in_recording: + display_name = create_random_name(prefix=prefix, length=32) + self.recording_processors.append(MSGraphNameReplacer(display_name, mock_name)) + else: + display_name = mock_name + + self.kwargs = { + 'display_name': display_name, + 'mail_nick_name': 'deleteme11' + } + self.cmd('ad group create --display-name {display_name} --mail-nickname {mail_nick_name}', + checks=self.check('displayName', '{display_name}')) + self.cmd('ad group show --group {display_name}', + checks=self.check('displayName', '{display_name}')) + self.cmd('ad group list --display-name {display_name}', + checks=[self.check('length(@)', 1), + self.check('[0].displayName', '{display_name}')]) + self.cmd('ad group delete --group {display_name}') + self.cmd('ad group list --display-name {display_name}', + checks=self.check('length(@)', 0)) + + def _get_id_from_value(permissions, value): """Get id from value for appRoles or oauth2PermissionScopes.""" # https://docs.microsoft.com/en-us/graph/api/resources/serviceprincipal?view=graph-rest-1.0#properties