Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add new az ad app permissions grant and list commands for OAuth2 permissions for AAD registered apps #6975

Closed
wants to merge 4 commits into from
Closed
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
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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')

Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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,