Skip to content

Commit

Permalink
Centralized interactive input() function that checks if STDIN is a TTY (
Browse files Browse the repository at this point in the history
#1856)

* Centralized interactive input() function that checks if STDIN is a TTY

- Promote _prompting to prompting
- Use prompt() to check TTY before getting user input
+ fix pep8 spacing

* Centralized password prompting with confirmation option
  • Loading branch information
derekbekoe authored Jan 25, 2017
1 parent 171ad46 commit 6224ec0
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/azure-cli-core/azure/cli/core/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import azure.cli.core.telemetry as telemetry
from azure.cli.core._util import CLIError
from azure.cli.core.application import APPLICATION
from azure.cli.core._prompting import prompt_y_n, NoTTYException
from azure.cli.core.prompting import prompt_y_n, NoTTYException
from azure.cli.core._config import az_config

from ._introspection import (extract_args_from_signature,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# --------------------------------------------------------------------------------------------

import sys
import getpass
from six.moves import input # pylint: disable=redefined-builtin

import azure.cli.core.azlogging as azlogging
Expand All @@ -21,6 +22,20 @@ def _verify_is_a_tty():
raise NoTTYException()


def prompt(msg):
_verify_is_a_tty()
return input(msg)


def prompt_pass(msg='Password: ', confirm=False):
_verify_is_a_tty()
password = getpass.getpass(msg)
if confirm:
password2 = getpass.getpass('Confirm ' + msg)
assert password == password2, 'Passwords do not match.'
return password


def prompt_y_n(msg, default=None):
_verify_is_a_tty()
if default not in [None, 'y', 'n']:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

import sys
import requests

from azure.cli.core.prompting import prompt, prompt_pass, NoTTYException
from azure.cli.core._util import CLIError

from ._utils import (
Expand Down Expand Up @@ -49,10 +49,10 @@ def _validate_user_credentials(registry_name, path, resultIndex, username=None,

if username:
if not password:
if not sys.stdin.isatty():
try:
password = prompt_pass(msg='Password: ')
except NoTTYException:
raise CLIError('Please specify both username and password in non-interactive mode.')
import getpass
password = getpass.getpass('Password: ')
return _obtain_data_from_registry(login_server, path, resultIndex, username, password)

try:
Expand All @@ -63,19 +63,13 @@ def _validate_user_credentials(registry_name, path, resultIndex, username=None,
except: #pylint: disable=bare-except
pass

if not sys.stdin.isatty():
try:
username = prompt('Username: ')
password = prompt_pass(msg='Password: ')
except NoTTYException:
raise CLIError(
'Unable to authenticate using admin login credentials or admin is not enabled. ' +
'Please specify both username and password in non-interactive mode.')

try:
user_input = raw_input
except NameError:
user_input = input

import getpass
username = user_input("Username: ")
password = getpass.getpass('Password: ')
return _obtain_data_from_registry(login_server, path, resultIndex, username, password)

def acr_repository_list(registry_name, username=None, password=None):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from azure.cli.core.commands.arm import is_valid_resource_id, parse_resource_id
from azure.cli.core.commands import LongRunningOperation

from azure.cli.core.prompting import prompt_pass, NoTTYException
import azure.cli.core.azlogging as azlogging
from azure.cli.core._util import CLIError
from ._params import web_client_factory, _generic_site_operation
Expand Down Expand Up @@ -344,8 +345,10 @@ def set_deployment_user(user_name, password=None):
user = User(location='not-really-needed') #TODO: open bug for this one is not needed
user.publishing_user_name = user_name
if password is None:
import getpass
password = getpass.getpass('Password: ')
try:
password = prompt_pass(msg='Password: ', confirm=True)
except NoTTYException:
raise CLIError('Please specify both username and password in non-interactive mode.')

user.publishing_password = password
result = client.provider.update_publishing_user(user)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@
from __future__ import print_function
import os
import sys
from six.moves import input, configparser #pylint: disable=redefined-builtin
from six.moves import configparser # pylint: disable=redefined-builtin
from adal.adal_error import AdalError

import azure.cli.core.azlogging as azlogging
from azure.cli.core._config import (GLOBAL_CONFIG_DIR, GLOBAL_CONFIG_PATH,
CONTEXT_CONFIG_DIR, ACTIVE_CONTEXT_CONFIG_PATH,
ENV_VAR_PREFIX)
from azure.cli.core._util import CLIError
from azure.cli.core._prompting import (prompt_y_n, prompt_choice_list, NoTTYException)
from azure.cli.core.prompting import (prompt,
prompt_y_n,
prompt_choice_list,
prompt_pass,
NoTTYException)
from azure.cli.command_modules.configure._consts import (OUTPUT_LIST, CLOUD_LIST, LOGIN_METHOD_LIST,
MSG_INTRO,
MSG_CLOSING,
Expand All @@ -31,8 +35,7 @@
MSG_PROMPT_TELEMETRY,
MSG_PROMPT_FILE_LOGGING)
from azure.cli.command_modules.configure._utils import get_default_from_config
import azure.cli.command_modules.configure._help # pylint: disable=unused-import
import azure.cli.core.telemetry as telemetry
import azure.cli.command_modules.configure._help # pylint: disable=unused-import

logger = azlogging.get_az_logger(__name__)

Expand Down Expand Up @@ -65,7 +68,6 @@ def _config_env_public_azure(_):
list(get_mgmt_service_client(ResourceManagementClient).resources.list())
except CLIError:
# Not logged in
import getpass
login_successful = False
while not login_successful:
method_index = prompt_choice_list(MSG_PROMPT_LOGIN, LOGIN_METHOD_LIST)
Expand All @@ -80,13 +82,13 @@ def _config_env_public_azure(_):
if method_index == 0: # device auth
interactive = True
elif method_index == 1: # username and password
username = input('Username: ')
password = getpass.getpass('Password: ')
username = prompt('Username: ')
password = prompt_pass(msg='Password: ')
elif method_index == 2: # service principal with secret
service_principal = True
username = input('Service principal: ')
tenant = input('Tenant: ')
password = getpass.getpass('Client secret: ')
username = prompt('Service principal: ')
tenant = prompt('Tenant: ')
password = prompt_pass(msg='Client secret: ')
elif method_index == 3: # skip
return
try:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

from __future__ import print_function
import sys
from six.moves import input #pylint: disable=redefined-builtin

from azure.cli.core import __version__ as core_version
from azure.cli.core._util import CLIError
from azure.cli.core.prompting import prompt, NoTTYException
import azure.cli.core.azlogging as azlogging

import azure.cli.command_modules.feedback._help # pylint: disable=unused-import
Expand Down Expand Up @@ -35,7 +37,7 @@
def _prompt_net_promoter_score():
while True:
try:
score = int(input(MESSAGES['prompt_how_likely']))
score = int(prompt(MESSAGES['prompt_how_likely']))
if 0 <= score <= 10:
return score
raise ValueError
Expand Down Expand Up @@ -75,11 +77,13 @@ def handle_feedback():
response_do_well = None
response_what_changes = None
if score == 10:
response_do_well = input(MESSAGES['prompt_do_well'])
response_do_well = prompt(MESSAGES['prompt_do_well'])
else:
response_what_changes = input(MESSAGES['prompt_what_changes'])
email_address = input(MESSAGES['prompt_email_addr'])
response_what_changes = prompt(MESSAGES['prompt_what_changes'])
email_address = prompt(MESSAGES['prompt_email_addr'])
_send_feedback(score, response_what_changes, response_do_well, email_address)
print(MESSAGES['thanks'])
except NoTTYException:
raise CLIError('This command is interactive and no tty available.')
except (EOFError, KeyboardInterrupt):
print()
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
import requests
from adal.adal_error import AdalError

from azure.cli.core.prompting import prompt_pass, NoTTYException
import azure.cli.core.azlogging as azlogging
from azure.cli.core._profile import Profile, CLOUD
from azure.cli.core._util import CLIError
import azure.cli.core.azlogging as azlogging

logger = azlogging.get_az_logger(__name__)

Expand Down Expand Up @@ -52,8 +53,10 @@ def login(username=None, password=None, service_principal=None, tenant=None):

if username:
if not password:
import getpass
password = getpass.getpass('Password: ')
try:
password = prompt_pass('Password: ')
except NoTTYException:
raise CLIError('Please specify both username and password in non-interactive mode.')
else:
interactive = True

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from azure.cli.core.commands.parameters import get_one_of_subscription_locations
from azure.cli.core.commands.arm import resource_exists
import azure.cli.core.azlogging as azlogging
from azure.cli.core.prompting import prompt_pass, NoTTYException

from six.moves.urllib.request import urlopen # pylint: disable=import-error

Expand Down Expand Up @@ -101,8 +102,10 @@ def _handle_auth_types(**kwargs):
if args.ssh_dest_key_path:
raise CLIError('SSH parameters cannot be used with password authentication type')
elif not args.admin_password:
import getpass
args.admin_password = getpass.getpass('Admin Password: ')
try:
args.admin_password = prompt_pass('Admin Password: ', confirm=True)
except NoTTYException:
raise CLIError('Please specify both username and password in non-interactive mode.')
elif args.authentication_type == 'ssh':
if args.admin_password:
raise CLIError('Admin password cannot be used with SSH authentication type')
Expand Down

0 comments on commit 6224ec0

Please sign in to comment.