Skip to content
Merged
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
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ mock==1.3.0
pylint==1.5.4
six==1.10.0
vcrpy==1.7.4

#Same as: -e git+https://github.com/yugangw-msft/azure-activedirectory-library-for-python.git@device#egg=azure-activedirectory-library-for-python
http://40.112.211.51:8080/packages/adal-0.2.0.zip
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[bdist_wheel]
universal=1

[install]
[easy-install]
single-version-externally-managed=1
record=RECORD.txt
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python

#-------------------------------------------------------------------------
# Copyright (c) Microsoft. All rights reserved.
Expand Down Expand Up @@ -59,6 +59,7 @@
'azure==2.0.0rc1',
'six',
'jmespath',
'adal==0.2.0' #from internal index server.
]

with open('README.rst', 'r', encoding='utf-8') as f:
Expand Down
4 changes: 3 additions & 1 deletion src/azure/cli/commands/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ def list_subscriptions(args, unexpected): #pylint: disable=unused-argument

@command('account set')
@description(L('Set the current subscription'))
@option('--subscription-id -n <subscription-id>', L('Subscription Id, unique name also works.'))
@option('--subscription-id -n <subscription-id>',
L('Subscription Id, unique name also works.'),
required=True)
def set_active_subscription(args, unexpected): #pylint: disable=unused-argument
subscription_id = args.get('subscription-id')
if not id:
Expand Down
71 changes: 44 additions & 27 deletions src/azure/cli/commands/login.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,61 @@
from msrestazure.azure_active_directory import UserPassCredentials, ServicePrincipalCredentials
from __future__ import print_function
from msrest.authentication import BasicTokenAuthentication
from adal import (acquire_token_with_username_password,
acquire_token_with_client_credentials,
acquire_user_code,
acquire_token_with_device_code)
from azure.mgmt.resource.subscriptions import (SubscriptionClient,
SubscriptionClientConfiguration)

from .._profile import Profile
from ..commands import command, description, option
from .._debug import should_disable_connection_verify
#TODO: update adal-python to support it
#from .._debug import should_disable_connection_verify
from .._locale import L

CLIENT_ID = '04b07795-8ddb-461a-bbee-02f9e1bf7b46'

@command('login')
@description(L('log in to an Azure subscription using Active Directory Organization Id'))
@option('--username -u <username>',
L('organization Id or service principal. Microsoft Account is not yet supported.'),
required=True)
L('organization Id or service principal. Microsoft Account is not yet supported.'))
@option('--password -p <password>', L('user password or client secret, will prompt if not given.'))
@option('--service-principal', L('the credential represents a service principal.'))
@option('--tenant -t <tenant>', L('the tenant associated with the service principal.'))
def login(args, unexpected): #pylint: disable=unused-argument
interactive = False

username = args.get('username')
if username:
password = args.get('password')
if not password:
import getpass
password = getpass.getpass(L('Password: '))
else:
interactive = True

password = args.get('password')
if not password:
import getpass
password = getpass.getpass(L('Password: '))

cert_verify = not should_disable_connection_verify()
if args.get('service-principal'):
tenant = args.get('tenant')
if not tenant:
raise ValueError(L('Please supply tenant using "--tenant"'))

credentials = ServicePrincipalCredentials(username,
password,
tenant=tenant,
verify=cert_verify)
tenant = args.get('tenant')
authority = _get_authority_url(tenant)
if interactive:
user_code = acquire_user_code(authority)
print(user_code['message'])
credentials = acquire_token_with_device_code(authority, user_code)
username = credentials['userId']
else:
credentials = UserPassCredentials(username, #pylint: disable=redefined-variable-type
password,
client_id=CLIENT_ID,
verify=cert_verify)
if args.get('service-principal'):
if not tenant:
raise ValueError(L('Please supply tenant using "--tenant"'))

client = SubscriptionClient(SubscriptionClientConfiguration(credentials))
credentials = acquire_token_with_client_credentials(
authority,
username,
password)
else:
credentials = acquire_token_with_username_password(
authority,
username,
password)

token_credential = BasicTokenAuthentication({'access_token': credentials['accessToken']})
client = SubscriptionClient(SubscriptionClientConfiguration(token_credential))
subscriptions = client.subscriptions.list()

if not subscriptions:
Expand All @@ -50,6 +64,9 @@ def login(args, unexpected): #pylint: disable=unused-argument
#keep useful properties and not json serializable
profile = Profile()
consolidated = Profile.normalize_properties(username, subscriptions)
profile.set_subscriptions(consolidated, credentials.token['access_token'])
profile.set_subscriptions(consolidated, credentials['accessToken'])

return list(subscriptions)

def _get_authority_url(tenant=None):
return 'https://login.microsoftonline.com/{}'.format(tenant or 'common')