diff --git a/mpwcli.py b/mpwcli.py index 0b814df..7c3a8f7 100755 --- a/mpwcli.py +++ b/mpwcli.py @@ -7,6 +7,8 @@ from argparse import RawTextHelpFormatter import hashlib import json +import copy + def parse_commandline_arguments(config_path_for_help_message): """Parse commandline argument and return namespace""" # Define what arguments to accept and with what help message and defaults. @@ -72,6 +74,11 @@ def read_config(config_path): return dict() return config +def write_config(config, config_path): + f = open(config_path, 'w') + f.write(json.dumps(config, indent=4)) + f.close() + def process_arguments(args, config): # Check if environment variables are set. if args.full_name is None: @@ -87,6 +94,19 @@ def process_arguments(args, config): args.site_result_type = short_site_result_type_dict[args.site_result_type] return args +def update_config(args, config): + new_config = copy.deepcopy(config) + do_not_ask = 'ASK_TO_SET_DEFAULT_NAME' in config and config['ASK_TO_SET_DEFAULT_NAME'] == False + if 'FULL_NAME' not in config and not do_not_ask: + answer = input('Do you want to use this name as the default (y/n): ') + if answer.lower() == 'y': + new_config['FULL_NAME'] = args.full_name + if answer.lower() == 'n': + ask_again_answer = input('Do you want to to get this question the ' + 'next time you run mpw (y/n): ') + if ask_again_answer.lower() == 'n': + new_config['ASK_TO_SET_DEFAULT_NAME'] = False + return new_config def generate_results(args, master_password): try: @@ -137,6 +157,8 @@ def run(config_path): # Look for environment variables or ask when missing information in arguments. config = read_config(config_path) args = process_arguments(args, config) + new_config = update_config(args, config) + write_config(new_config, config_path) # Get password from user. master_password = getpass.getpass() # Run the algorithm. @@ -150,3 +172,6 @@ def run(config_path): if args.verbose: print(str(e)) print_results(site_result, identicon, args) + +if '__main__' == __name__: + run('config.json') diff --git a/tests/test_mpwcli.py b/tests/test_mpwcli.py index 245d3c1..df1f442 100755 --- a/tests/test_mpwcli.py +++ b/tests/test_mpwcli.py @@ -3,6 +3,7 @@ from tests.testcases import load_test_cases import pprint import sys +import os num_tests_run = 0 @@ -10,11 +11,45 @@ def is_ascii(s): maxAnsiCode = 127 return all([c <= maxAnsiCode for c in s.encode()]) +def clear_config(): + config_directory = os.environ['HOME'] + '/.config/mpw/' + if not os.path.exists(config_directory): + os.makedirs(config_directory) + with open(config_directory + 'config.json', 'w') as config: + config.write('{}') + def run_test_keyword_short(fullName, masterPassword, siteName, siteCounter, resultType, keyPurpose, result, identicon): global num_tests_run arguments = locals() + clear_config() + spawn_command = 'mpw -u \"%s\" -c %s -t %s -p %s %s' % (fullName, + siteCounter, + resultType, + keyPurpose, + siteName) + child = pexpect.spawnu(spawn_command) + if keyPurpose == "Authentication": + child.expect(r'Do you want to use this name as the default \(y/n\): ') + child.sendline('y') + child.expect("Password: ") + child.sendline(masterPassword) + output = child.read() + child.close() + assert(result in output) + assert(identicon in output) + else: + output = child.read() + child.close() + assert("Only Authentication key purpose is currrently supported" in output) + +def run_test_do_not_ask_again(fullName, masterPassword, siteName, + siteCounter, resultType, keyPurpose, + result, identicon): + global num_tests_run + arguments = locals() + clear_config() spawn_command = 'mpw -u \"%s\" -c %s -t %s -p %s %s' % (fullName, siteCounter, resultType, @@ -22,6 +57,55 @@ def run_test_keyword_short(fullName, masterPassword, siteName, siteName) child = pexpect.spawnu(spawn_command) if keyPurpose == "Authentication": + child.expect(r'Do you want to use this name as the default \(y/n\): ') + child.sendline('n') + child.expect(r'Do you want to to get this question the next time you run mpw \(y/n\): ') + child.sendline('N') + child.expect("Password: ") + child.sendline(masterPassword) + output = child.read() + child.close() + assert(result in output) + assert(identicon in output) + + child = pexpect.spawnu(spawn_command) + child.expect("Password: ") + child.sendline(masterPassword) + output = child.read() + child.close() + assert(result in output) + assert(identicon in output) + + else: + output = child.read() + child.close() + assert("Only Authentication key purpose is currrently supported" in output) + +def run_test_set_password(fullName, masterPassword, siteName, + siteCounter, resultType, keyPurpose, + result, identicon): + global num_tests_run + arguments = locals() + clear_config() + spawn_command = 'mpw -u \"%s\" -c %s -t %s -p %s %s' % (fullName, + siteCounter, + resultType, + keyPurpose, + siteName) + child = pexpect.spawnu(spawn_command) + if keyPurpose == "Authentication": + child.expect(r'Do you want to use this name as the default \(y/n\): ') + child.sendline('Y') + child.expect("Password: ") + child.sendline(masterPassword) + output = child.read() + child.close() + assert(result in output) + assert(identicon in output) + child = pexpect.spawnu('mpw -c %s -t %s -p %s %s' % (siteCounter, + resultType, + keyPurpose, + siteName)) child.expect("Password: ") child.sendline(masterPassword) output = child.read() @@ -43,3 +127,11 @@ def test_keyword_short(): case['siteName'], case['siteCounter'], case['resultType'], case['keyPurpose'], case['result'], case['identicon']) + run_test_do_not_ask_again(case['fullName'], case['masterPassword'], + case['siteName'], case['siteCounter'], + case['resultType'], case['keyPurpose'], + case['result'], case['identicon']) + run_test_set_password(case['fullName'], case['masterPassword'], + case['siteName'], case['siteCounter'], + case['resultType'], case['keyPurpose'], + case['result'], case['identicon'])