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
1 change: 1 addition & 0 deletions azure-cli.pyproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
</Compile>
<Compile Include="azure\cli\_argparse.py" />
<Compile Include="azure\cli\_logging.py" />
<Compile Include="azure\cli\_profile.py" />
<Compile Include="azure\cli\_session.py">
<SubType>Code</SubType>
</Compile>
Expand Down
22 changes: 22 additions & 0 deletions src/azure/cli/_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from msrest.authentication import BasicTokenAuthentication

from .main import CONFIG

class Profile(object):

def update(self, subscriptions, access_token):
subscriptions[0]['active'] = True
CONFIG['subscriptions'] = subscriptions
CONFIG['access_token'] = access_token

def get_credentials(self):
subscriptions = CONFIG['subscriptions']
sub = [x for x in subscriptions if x['active'] == True ]
if not sub and subscriptions:
sub = subscriptions

if sub:
return (BasicTokenAuthentication({ 'access_token': CONFIG['access_token']}),
sub[0]['id'] )
else:
raise ValueError('you need to login to')
91 changes: 36 additions & 55 deletions src/azure/cli/commands/login.py
Original file line number Diff line number Diff line change
@@ -1,71 +1,52 @@
from azure.mgmt.resource.subscriptions import SubscriptionClient, \
SubscriptionClientConfiguration
from msrestazure.azure_active_directory import UserPassCredentials

from .._logging import logging
from ..main import CONFIG, SESSION
from .._profile import Profile
from .._util import TableOutput
from ..commands import command, description, option

PII_WARNING_TEXT = _(
'If you choose to continue, Azure command-line interface will cache your '
'authentication information. Note that this sensitive information will be stored in '
'plain text on the file system of your computer at {}. Ensure that you take suitable '
'precautions to protect your computer from unauthorized access in order to minimize the '
'risk of that information being disclosed.'
'\nDo you wish to continue: (y/n) '
)
CLIENT_ID = '04b07795-8ddb-461a-bbee-02f9e1bf7b46'

@command('login')
@description('logs you in')
@option('--username -u <username>', _('user name or service principal ID. If multifactor authentication is required, '
'you will be prompted to use the login command without parameters for '
'interactive support.'))
@option('--environment -e <environment>', _('Environment to authenticate against, such as AzureChinaCloud; '
'must support active directory.'))
@option('--password -p <password>', _('user password or service principal secret, will prompt if not given.'))
@option('--service-principal', _('If given, log in as a service principal rather than a user.'))
@option('--certificate-file <certificateFile>', _('A PEM encoded certificate private key file.'))
@option('--thumbprint <thumbprint>', _('A hex encoded thumbprint of the certificate.'))
@option('--tenant <tenant>', _('Tenant domain or ID to log into.'))
@option('--quiet -q', _('do not prompt for confirmation of PII storage.'))
@description('log in to an Azure subscription using Active Directory Organization Id')
@option('--username -u <username>', _('organization Id. Microsoft Account is not yet supported.'))
@option('--password -p <password>', _('user password, will prompt if not given.'))
def login(args, unexpected):
username = args.get('username')
interactive = bool(username)

environment_name = args.get('environment') or 'AzureCloud'
environment = CONFIG['environments'].get(environment_name)
if not environment:
raise RuntimeError(_('Unknown environment {0}').format(environment_name))

tenant = args.get('tenant')
if args.get('service-principal') and not tenant:
tenant = input(_('Tenant: '))

# TODO: PII warning

password = args.get('password')
require_password = not args.get('service-principal') or not args.get('certificate-file')
if not interactive and require_password and not password:
if not password:
import getpass
password = getpass.getpass(_('Password: '))

if not require_password:
password = {
'certificateFile': args['certificate-file'],
'thumbprint': args.thumbprint,
}
credentials = UserPassCredentials(username, password, client_id=CLIENT_ID)
client = SubscriptionClient(SubscriptionClientConfiguration(credentials))
subscriptions = client.subscriptions.list()

if not interactive:
# TODO: Remove cached token
SESSION.pop(username + '_token', None)

# TODO: Perform login
token = ''

SESSION[username + '_token'] = token

# TODO: Get subscriptions
subscriptions = ['not-a-real-subscription']
if not subscriptions:
raise RuntimeError(_("No subscriptions found for this account"))

active_subscription = subscriptions[0]

logging.info(_('Setting subscription %s as default'), active_subscription)
SESSION['active_subscription'] = active_subscription
#keep useful properties and not json serializable
consolidated = []
for s in subscriptions:
subscription = {};
subscription['id'] = s.id.split('/')[-1]
subscription['name'] = s.display_name
subscription['state'] = s.state
subscription['user'] = username
consolidated.append(subscription)

profile = Profile()
profile.update(consolidated, credentials.token['access_token'])

#TODO, replace with JSON display
with TableOutput() as to:
for subscription in consolidated:
to.cell('Name', subscription['name'])
to.cell('Active', bool(subscription['active']))
to.cell('User', subscription['user'])
to.cell('Subscription Id', subscription['id'])
to.cell('State', subscription['state'])
to.end_row()
15 changes: 5 additions & 10 deletions src/azure/cli/commands/storage.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from ..main import CONFIG, SESSION
from ..main import CONFIG, SESSION
from .._logging import logging
from .._util import TableOutput
from ..commands import command, description, option
from .._profile import Profile

@command('storage account list')
@description('List storage accounts')
Expand All @@ -11,17 +12,11 @@ def list_accounts(args, unexpected):
from azure.mgmt.storage import StorageManagementClient, StorageManagementClientConfiguration
from azure.mgmt.storage.models import StorageAccount
from msrestazure.azure_active_directory import UserPassCredentials

username = '' # TODO: get username somehow
password = '' # TODO: get password somehow

logging.code('''smc = StorageManagementClient(StorageManagementClientConfiguration(
credentials=UserPassCredentials(%r, %r),
subscription_id=%r
)''', username, password, args.subscription)
profile = Profile()
#credentials, subscription_id = profile.get_credentials()
smc = StorageManagementClient(StorageManagementClientConfiguration(
credentials=UserPassCredentials(username, password),
subscription_id=args.subscription,
*profile.get_credentials(),
))

group = args.get('resource-group')
Expand Down