From f19fde48c6b3f65c164c931286e72a0d254c1fb3 Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Tue, 29 Mar 2022 20:44:03 +0200 Subject: Add the -P param and improve tests --- otp2289/__init__.py | 2 +- otp2289/__main__.py | 105 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 74 insertions(+), 33 deletions(-) (limited to 'otp2289') diff --git a/otp2289/__init__.py b/otp2289/__init__.py index 608595b..59694a7 100644 --- a/otp2289/__init__.py +++ b/otp2289/__init__.py @@ -40,7 +40,7 @@ from .server import ( ) __author__ = 'Simeon Simeonov' -__version__ = '1.1.0-beta1' +__version__ = '1.1.0' __license__ = 'BSD 2-Clause' diff --git a/otp2289/__main__.py b/otp2289/__main__.py index 471ae24..78e60e8 100644 --- a/otp2289/__main__.py +++ b/otp2289/__main__.py @@ -135,6 +135,48 @@ def generate_otp_range(args: argparse.Namespace) -> str: ) +def get_password(args: argparse.Namespace) -> str: + """ + Extract the provided password using the defined argparse arguments + + :param args: The arguments assigned from argparse + :type args: argparse.Namespace + + :raises KeyboardInterrupt: If the password prompt is interrupted + + :return: The extrated password string + :rtype: str + """ + if args.force_password_prompt: + while True: + password = getpass.getpass() + if not args.initiate_new_sequence or password == getpass.getpass( + 'Repeat password: ' + ): + break + eprint('The passwords do not match') + return password + + if not args.password: + password = os.environ.get('OTP2289_PASSWORD') + if password is not None: + return password + while True: + password = getpass.getpass() + if not args.initiate_new_sequence or password == getpass.getpass( + 'Repeat password: ' + ): + break + eprint('The passwords do not match') + return password + + if os.path.isfile(args.password): + with io.open(args.password, 'r', encoding='utf-8') as fp: + return fp.readline().strip() + + return args.password + + def get_rnd_seed() -> str: """ Returns a random seed in the format: @@ -192,6 +234,7 @@ def main(args=None): description='The following options are available', ) group = parser.add_mutually_exclusive_group(required=True) + password_group = parser.add_mutually_exclusive_group() group.add_argument( '--generate-otp-range', action='store_true', @@ -217,6 +260,28 @@ def main(args=None): 'and always outputs hex (ignores -f).' ), ) + password_group.add_argument( + '-P', + '--force-password-prompt', + dest='force_password_prompt', + action='store_true', + help=( + 'Force password prompt even if the env. variable ' + '"OTP2289_PASSWORD" is set' + ), + ) + password_group.add_argument( + '-p', + '--password', + metavar='', + type=str, + dest='password', + default='', + help=( + 'The password or path to password file ' + '(default & recommended: prompt for passwd)' + ), + ) parser.add_argument( '-a', '--hash-algorithm', @@ -253,18 +318,6 @@ def main(args=None): default=500, help='The step. Default for initiating a new sequence is: 500', ) - parser.add_argument( - '-p', - '--password', - metavar='', - type=str, - dest='password', - default='', - help=( - 'The password or path to password file ' - '(default & recommended: prompt for passwd)' - ), - ) parser.add_argument( '-q', '--quiet', @@ -303,26 +356,14 @@ def main(args=None): ) args = parser.parse_args(args) # handle the password before everything else - if not args.password: - try: - while True: - args.password = getpass.getpass() - if ( - not args.initiate_new_sequence - or args.password == getpass.getpass('Repeat password: ') - ): - break - eprint('The passwords do not match') - except KeyboardInterrupt: - eprint(os.linesep + 'Prompt terminated') - sys.exit(errno.EACCES) - elif os.path.isfile(args.password): - try: - with io.open(args.password, 'r', encoding='utf-8') as fp: - args.password = fp.readline().strip() - except Exception as exp: - eprint(f'Unable to open password file: {exp}') - sys.exit(1) + try: + args.password = get_password(args) + except KeyboardInterrupt: + eprint(os.linesep + 'Prompt terminated') + sys.exit(errno.EACCES) + except Exception as exp: + eprint(f'Unable to fetch password: {exp}') + sys.exit(1) try: if args.initiate_new_sequence: print(initiate_new_sequence(args)) -- cgit v1.3