[AIRFLOW-2370] Implement --use_random_password in create_user Closes #3262 from wrp/passwords
Project: http://git-wip-us.apache.org/repos/asf/incubator-airflow/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-airflow/commit/5aa15868 Tree: http://git-wip-us.apache.org/repos/asf/incubator-airflow/tree/5aa15868 Diff: http://git-wip-us.apache.org/repos/asf/incubator-airflow/diff/5aa15868 Branch: refs/heads/v1-10-test Commit: 5aa15868fd9276d82df33f8fe2e4e3cfc7f4d60a Parents: 840930b Author: William Pursell <willi...@wepay.com> Authored: Sat Apr 28 20:59:59 2018 +0200 Committer: Fokko Driesprong <fokkodriespr...@godatadriven.com> Committed: Sat Apr 28 20:59:59 2018 +0200 ---------------------------------------------------------------------- airflow/bin/cli.py | 32 ++++++++++++++++++++------------ tests/core.py | 7 +++++++ 2 files changed, 27 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/5aa15868/airflow/bin/cli.py ---------------------------------------------------------------------- diff --git a/airflow/bin/cli.py b/airflow/bin/cli.py index 975f481..8a92cfa 100644 --- a/airflow/bin/cli.py +++ b/airflow/bin/cli.py @@ -22,9 +22,10 @@ from __future__ import print_function import logging import os -import socket import subprocess import textwrap +import random +import string from importlib import import_module import daemon @@ -1209,27 +1210,28 @@ def create_user(args): } empty_fields = [k for k, v in fields.items() if not v] if empty_fields: - print('Missing arguments: {}.'.format(', '.join(empty_fields))) - sys.exit(0) + raise SystemExit('Required arguments are missing: {}.'.format( + ', '.join(empty_fields))) appbuilder = cached_appbuilder() role = appbuilder.sm.find_role(args.role) if not role: - print('{} is not a valid role.'.format(args.role)) - sys.exit(0) + raise SystemExit('{} is not a valid role.'.format(args.role)) - password = getpass.getpass('Password:') - password_confirmation = getpass.getpass('Repeat for confirmation:') - if password != password_confirmation: - print('Passwords did not match!') - sys.exit(0) + if args.use_random_password: + password = ''.join(random.choice(string.printable) for _ in range(16)) + else: + password = getpass.getpass('Password:') + password_confirmation = getpass.getpass('Repeat for confirmation:') + if password != password_confirmation: + raise SystemExit('Passwords did not match!') user = appbuilder.sm.add_user(args.username, args.firstname, args.lastname, args.email, role, password) if user: print('{} user {} created.'.format(args.role, args.username)) else: - print('Failed to create user.') + raise SystemExit('Failed to create user.') Arg = namedtuple( @@ -1619,6 +1621,11 @@ class CLIFactory(object): ('-u', '--username',), help='Username of the user', type=str), + 'use_random_password': Arg( + ('--use_random_password',), + help='Do not prompt for password. Use random string instead', + default=False, + action='store_true'), } subparsers = ( { @@ -1759,7 +1766,8 @@ class CLIFactory(object): }, { 'func': create_user, 'help': "Create an admin account", - 'args': ('role', 'username', 'email', 'firstname', 'lastname'), + 'args': ('role', 'username', 'email', 'firstname', 'lastname', + 'use_random_password'), }, ) subparsers_dict = {sp['func'].__name__: sp for sp in subparsers} http://git-wip-us.apache.org/repos/asf/incubator-airflow/blob/5aa15868/tests/core.py ---------------------------------------------------------------------- diff --git a/tests/core.py b/tests/core.py index 9cbae9d..6d18ffe 100644 --- a/tests/core.py +++ b/tests/core.py @@ -983,6 +983,13 @@ class CliTests(unittest.TestCase): args = self.parser.parse_args(['list_dags', '--report']) cli.list_dags(args) + def test_cli_create_user(self): + args = self.parser.parse_args([ + 'create_user', '-u', 'test', '-l', 'doe', '-f', 'jon', + '-e', 'j...@foo.com', '-r', 'Viewer', '--use_random_password' + ]) + cli.create_user(args) + def test_cli_list_tasks(self): for dag_id in self.dagbag.dags.keys(): args = self.parser.parse_args(['list_tasks', dag_id])