import json import pathlib import sys # name of the file where we store the pw database PWDB_FLNAME = pathlib.Path('pwdb.json') def get_credentials(): # get input from terminal username = input('Enter your username: ') # get password using the appropriate module, so that typed characters are not # echoed to the terminal password = input('Enter your password: ') return (username, password) def authenticate(username, password, pwdb): # calculate hash and compare with stored hash return password == pwdb[username] def add_user(username, pwdb): # do not try to add a username twice if username in pwdb: raise Exception(f'Username already exists [{username}]!') else: pwdb[username] = input(f'Enter password for {username}: ') return pwdb def read_pwdb(pwdb_path): # try to read from the database # if anything happens, report the error! if not pwdb_path.exists(): initialize_pwdb(pwdb_path) try: with open(pwdb_path, 'rt') as pwdb_file: pwdb = json.load(pwdb_file) except json.decoder.JSONDecodeError as exc: # this happens when the json data is invalid raise Exception(f'Invalid database {pwdb_path}: {exc}') except Exception as exc: # this is a catch-all condition raise Exception(f'Unkown error reading {pwdb_path}: {exc}') return pwdb def write_pwdb(pwdb, pwdb_path): with open(pwdb_path, 'wt') as pwdb_file: json.dump(pwdb, pwdb_file) def initialize_pwdb(pwdb_path): write_pwdb({}, pwdb_path) def main(pwdb_path): # load the password database from file pwdb = read_pwdb(pwdb_path) # if we are passed an argument, we want to add a new user if len(sys.argv) > 1: pwdb = add_user(sys.argv[1], pwdb) write_pwdb(pwdb, pwdb_path) return # ask for credentials username, password = get_credentials() if username not in pwdb: print('Wrong username!') return # try to authenticate if authenticate(username, password, pwdb): print('Successfully authenticated!') else: # report wrong password print('Wrong password!') return if __name__ == '__main__': main(PWDB_FLNAME)