diff --git a/src/command_modules/azure-cli-role/azure/cli/command_modules/role/_help.py b/src/command_modules/azure-cli-role/azure/cli/command_modules/role/_help.py index 7dbdb73e49f..93fc3af7f0d 100644 --- a/src/command_modules/azure-cli-role/azure/cli/command_modules/role/_help.py +++ b/src/command_modules/azure-cli-role/azure/cli/command_modules/role/_help.py @@ -159,6 +159,24 @@ az ad app update --id e042ec79-34cd-498f-9d9f-123456781234 --set groupMembershipClaims=All """ +helps['ad app permission'] = """ + type: group + short-summary: manage an application's OAuth2 permissions. +""" +helps['ad app permission grant'] = """ + type: command + short-summary: Grant an app OAuth2 permissions from another app + examples: + - name: Grant a native application with OAuth2 permissions from an existing AAD app with TTL of 2 years + text: az ad app permission grant --id e042ec79-34cd-498f-9d9f-1234234 --app-id a0322f79-57df-498f-9d9f-12678 --expires 2 +""" +helps['ad app permission list'] = """ + type: command + short-summary: List the app OAuth2 permissions + examples: + - name: List the OAuth2 permissions for an existing AAD app + text: az ad app permission list --id e042ec79-34cd-498f-9d9f-1234234 +""" helps['ad app owner'] = """ type: group short-summary: Manage application owners. diff --git a/src/command_modules/azure-cli-role/azure/cli/command_modules/role/_params.py b/src/command_modules/azure-cli-role/azure/cli/command_modules/role/_params.py index e86110a3dca..3b35066a54e 100644 --- a/src/command_modules/azure-cli-role/azure/cli/command_modules/role/_params.py +++ b/src/command_modules/azure-cli-role/azure/cli/command_modules/role/_params.py @@ -42,6 +42,13 @@ def load_arguments(self, _): help="resource scopes and roles the application requires access to. Should be in manifest json format. See examples below for details") c.argument('native_app', arg_type=get_three_state_flag(), help="an application which can be installed on a user's device or computer") + with self.argument_context('ad app permission grant') as c: + c.argument('app_id', help='clientId of an existing app from which you want to grant permissions to your app') + c.argument('expires', help='Expiry date for the permissions in years, options include 1, 2 or never.') + + with self.argument_context('ad app permission list') as c: + c.argument('identifier', options_list=['--id'], help='identifier uri, application id, or object id of the associated application') + with self.argument_context('ad app owner list') as c: c.argument('identifier', options_list=['--id'], help='identifier uri, application id, or object id of the application') diff --git a/src/command_modules/azure-cli-role/azure/cli/command_modules/role/commands.py b/src/command_modules/azure-cli-role/azure/cli/command_modules/role/commands.py index 99b968e7b61..b40f121822a 100644 --- a/src/command_modules/azure-cli-role/azure/cli/command_modules/role/commands.py +++ b/src/command_modules/azure-cli-role/azure/cli/command_modules/role/commands.py @@ -84,6 +84,8 @@ def load_command_table(self, _): g.custom_command('delete', 'delete_application') g.custom_command('list', 'list_apps') g.custom_show_command('show', 'show_application') + g.custom_command('permission grant', 'grant_application') + g.custom_command('permission list', 'list_granted_application') g.generic_update_command('update', setter_name='patch_application', setter_type=role_custom, getter_name='show_application', getter_type=role_custom, custom_func_name='update_application', custom_func_type=role_custom) diff --git a/src/command_modules/azure-cli-role/azure/cli/command_modules/role/custom.py b/src/command_modules/azure-cli-role/azure/cli/command_modules/role/custom.py index f25d140047b..984f27d9adb 100644 --- a/src/command_modules/azure-cli-role/azure/cli/command_modules/role/custom.py +++ b/src/command_modules/azure-cli-role/azure/cli/command_modules/role/custom.py @@ -632,6 +632,53 @@ def create_application(client, display_name, homepage=None, identifier_uris=None return result +def list_granted_application(cmd, identifier): + graph_client = _graph_client_factory(cmd.cli_ctx) + + # Get the Service Principal ObjectId for the client app + client_sp_object_id = _resolve_service_principal(graph_client.service_principals, identifier) + + # Get the OAuth2 permissions client app + permissions = graph_client.oauth2.get( + filter="clientId eq '{}'".format(client_sp_object_id)) # pylint: disable=no-member + + return permissions.additional_properties['value'] + + +def grant_application(cmd, identifier, app_id, expires='1'): + graph_client = _graph_client_factory(cmd.cli_ctx) + + # Get the Service Principal ObjectId for the client app + client_sp_object_id = _resolve_service_principal(graph_client.service_principals, identifier) + + # Get the Service Principal ObjectId for associated app + associated_sp_object_id = _resolve_service_principal(graph_client.service_principals, app_id) + + # Build payload + start_date = datetime.datetime.utcnow() + end_date = start_date + relativedelta(years=1) + + if expires == '2': + end_date = start_date + relativedelta(years=2) + elif expires.lower() == 'never': + end_date = start_date + relativedelta(years=1000) + + payload = { + "odata.type": "Microsoft.DirectoryServices.OAuth2PermissionGrant", + "clientId": client_sp_object_id, + "consentType": "AllPrincipals", + "resourceId": associated_sp_object_id, + "scope": "user_impersonation", + "startTime": start_date.isoformat(), + "expiryTime": end_date.isoformat() + } + + # Grant OAuth2 permissions + response = graph_client.oauth2.post(payload) # pylint: disable=no-member + + return response + + def update_application(instance, display_name=None, homepage=None, # pylint: disable=unused-argument identifier_uris=None, password=None, reply_urls=None, key_value=None, key_type=None, key_usage=None, start_date=None, end_date=None, available_to_other_tenants=None,