#!/usr/bin/python3 # ==================================================================== # password vault 03 - menus # ==================================================================== import sys import copy import user_interface as ui # uer interface import password_vault_04_utils as utl # utility functions import password_vault_02_ed as ed # JSON encrypt/decrypt # ---- the "vault" is the only data encrypted and stored on disk # ---- the "filename", "password" are in memory and are lost when # ---- the program ends default_vault_context = \ { "vfilename": None, # vault file name "vpassword": None, # vault password "vault" : { "dbname" : "Default Password Vault", "update" : "January 1, 1970", "lastid" : 0, "entries": [] } } test_vault_context = \ { "vfilename": None, "vpassword": None, "vault" : { "dbname" : "test Password Vault", "update" : "January 1, 1970", "lastid" : 6, "entries": [ { "id" : 1, "name" : "amazon.com", "password": "goodboy", "note" : None }, { "id" : 2, "name" : "AMAZON.COM", "password": "badboy", "note" : "refurbished computers" }, { "id" : 3, "name" : "bestbuy.com", "password": "72zz93#", }, { "id" : 5, "name" : "www.adafruit.com", "password": "AD8##sx", "note" : "the good place, lots of DIY projects" }, { "id" : 6, "name" : "www.chase.com", "password": "m0M9m8##", "note" : "" } ] # end of entry list } # end of vault } # end of vault info # ------------------------------------------------------------------- # ---- query yes/no # ------------------------------------------------------------------- def query_yes_no(p=' [yY]: '): ans = ui.get_user_input(p) if not ans: return False if ans[0] == 'y' or ans[0] == 'Y': return True return False # ------------------------------------------------------------------- # ---- get vault password # ------------------------------------------------------------------- def get_vault_password(vault_context): pw = vault_context["vpassword"] print() print(f'The currrent vault\'s pasword is ({pw})') tf = query_yes_no('Use this password [yY]? ') if tf: return None pw = ui.get_user_input('Enter a password: ') if not pw: return None return pw # ------------------------------------------------------------------- # ---- get vault file name # ------------------------------------------------------------------- def get_vault_filename(vault_context): fn = vault_context["vfilename"] print() print(f'The currrent vault\'s file name is ({fn})') tf = query_yes_no('Use this filename [yY]? ') if tf: return None fn = ui.get_user_input('Enter a file name: ') if not fn: return None return fn # ------------------------------------------------------------------- # ---- get vault dbname # ------------------------------------------------------------------- def get_vault_dbname(vault_context): db = vault_context["vault"]["dbname"] print() print(f'The currrent vault\'s db name is ({db})') tf = query_yes_no('Use this db name [yY]? ') if tf: return None db = ui.get_user_input('Enter a db name: ') if not db: return None return db # ------------------------------------------------------------------- # ---- menu - change vault password # ------------------------------------------------------------------- def change_vault_password_action(vault_context): pw = get_vault_password(vault_context) if not pw: print() print('no password entered - no action taken') return vault_context["vpassword"] = pw print() print(f'vault\'s password changed to ({pw})') return # ------------------------------------------------------------------- # ---- menu - change vault file name # ------------------------------------------------------------------- def change_vault_filename_action(vault_context): fn = get_vault_filename(vault_context) if not fn: print() print('no file name entered - no action taken') return vault_context["vfilename"] = fn print() print(f'vault\'s file name changed to ({fn})') return # ------------------------------------------------------------------- # ---- menu - change vault db name # ------------------------------------------------------------------- def change_vault_dbname_action(vault_context): db = get_vault_dbname(vault_context) if not db: print() print('no db name entered - no action taken') return vault_context["vault"]["dbname"] = db print() print(f'vault\'s db name changed to ({db})') return # ------------------------------------------------------------------- # ---- menu - load a vault # ------------------------------------------------------------------- def load_vault_action(vault_context): # ---- get vault's file name print() fn = ui.get_user_input('Enter vault\'s file name: ') if not fn: print() print('no file name entered - no action taken') return None # ---- get vault's password print() pw = ui.get_user_input('Enter vault\'s password: ') if not pw: print() print('no password entered - no action taken') return None try: new_vault = ed.decrypt_dictionary(pw,fn) ##except BaseException as ex: ## print(f'Exception Name: {type(ex).__name__}') ## print(f'Exception Desc: {ex}') ## err = True except BaseException as ex: print('Decryption error') print(f'Exception Name: {type(ex).__name__}') print('probably a bad password') return vault_context["vpassword"] = pw vault_context["vfilename"] = fn vault_context["vault"] = new_vault print() print('A new vault is now in memory - ' + 'The old vault was replaced') return # ------------------------------------------------------------------- # ---- menu - save the current vault encrypted to a file # ------------------------------------------------------------------- def save_vault_action(vault_context): vault_stats_action(vault_context) print() print('These are the current vault\'s information') print('Are they the values you want?') tf = query_yes_no('Proceed with saving [yY]? ') if not tf: print() print('change the vault\'s information - then try again') return None pw = vault_context["vpassword"] fn = vault_context["vfilename"] db = vault_context["vault"]["dbname"] if not pw or not fn or not db: print() print('Bad vault information - no action taken') return vault_context["vault"]["update"] = utl.current_date() ed.encrypt_dictionary(vault_context["vault"],pw,fn) print() print(f'vault written to file ({fn})') return # ------------------------------------------------------------------- # ---- create a new vault # ------------------------------------------------------------------- def create_new_vault_action(vault_context): vault = vault_context["vault"] print() print(f'The current vault in memory is ({vault["dbname"]})') print('Creating a new vault will delete any existing data') print('in the current vault unless it has been saved.') print() if not query_yes_no('create a new vault [yY]: '): print() print('no action taken') return None vault_context["vault"] = copy.deepcopy(default_vault_context['vault']) vault_context["vfilename"] = None vault_context["vpassword"] = None vault_context["vault"]["dbname"] = None vault_context["vault"]["update"] = utl.current_date() print() print('A new vault is now in memory - ' + 'The old vault was replaced') print('Please update the new vault\'s information') return # ------------------------------------------------------------------- # ---- menu - display the current vault's stats # ------------------------------------------------------------------- def vault_stats_action(vault_context,all=False): print() print('----stats----------------------------------') print(f'vfilename: {vault_context["vfilename"]}') print(f'vpassword: {vault_context["vpassword"]}') if vault_context["vault"] is None: print(f'vault : {vault_context["vault"]}') else: print(f'dbname : {vault_context["vault"]["dbname"]}') print(f'update : {vault_context["vault"]["update"]}') print(f'lastid : {vault_context["vault"]["lastid"]}') print(f'entries : {len(vault_context["vault"]["entries"])}') if all: for e in vault_context["vault"]["entries"]: print(f'ID = {e["id"]:<3} name = {e["name"]}') print('-------------------------------------------') return # ------------------------------------------------------------------- # ---- password vault help # ------------------------------------------------------------------- def vault_help(): print() utl.display_message(0) print() utl.display_message(2) print() utl.display_message(3) print() utl.display_message(4) # ------------------------------------------------------------------- # ---- menu - main # ------------------------------------------------------------------- def main_menu(vault_context): if not ui.running_python3(): print() print('Not running Python3 - exit program') sys.exit() while(True): ####ui.clear_screen() dbname = vault_context["vault"]["dbname"] print(' ==================================================') print(f' {utl.return_message(2)} ({dbname})') print(' ==================================================') print(' ## Action') print(' -- ----------------------------------------------') print(' 0 exit program') print(' 1 search primary name') print(' 2 search notes') print(' 3 search for ID') print(' 4 add entry') print(' 5 delete entry') print(' 6 modify entry') print(' 10 load a new vault') print(' 11 save current vault') print(' 12 create a new vault') print(' 13 output CSV file') print(' 14 vault stats') print(' 15 vault stats (all)') print(' 16 change vault\'s password') print(' 17 change vault\'s file name') print(' 18 change vault\'s db name') print(' 88 renumber IDs') print(' 99 help') # --- ask the user to select an action print() sel = ui.get_user_input(' Enter selection: ') if not sel: # no selection? continue # --- valid selection? tf,n = ui.is_int(sel) if tf == False: print() print(f' Bad selection entered ({sel})') ui.pause() continue # --- take action if n == 0: break elif n == 1: pass elif n == 2: pass elif n == 3: pass elif n == 4: pass elif n == 5: pass elif n == 10: load_vault_action(vault_context) elif n == 11: save_vault_action(vault_context) elif n == 12: create_new_vault_action(vault_context) elif n == 13: pass elif n == 14: vault_stats_action(vault_context) elif n == 15: vault_stats_action(vault_context,True) elif n == 16: change_vault_password_action(vault_context) elif n == 17: change_vault_filename_action(vault_context) elif n == 18: change_vault_dbname_action(vault_context) elif n == 88: utl.renumber_vault_ids(vault_context) elif n == 99: ####ui.clear_screen() vault_help() else: print() print(f' Bad selection entered ({n})') ui.pause() # ------------------------------------------------------------------- # ---- main - use the test vault info # ------------------------------------------------------------------- if __name__ == '__main__': main_menu(test_vault_context)