diff --git a/files/dependencies.txt b/files/dependencies.txt index fa1c03e..94edb26 100644 --- a/files/dependencies.txt +++ b/files/dependencies.txt @@ -2,3 +2,4 @@ pysqlcipher3 password_strength hashlib pyotp +tabulate diff --git a/keyvault.py b/keyvault.py index 0886075..bc3dbe3 100644 --- a/keyvault.py +++ b/keyvault.py @@ -1,7 +1,10 @@ try: import base64 import pickle + from tabulate import tabulate from pysqlcipher3 import dbapi2 as sc + from pyotp import TOTP + from time import time from math import log2 from password_strength import PasswordStats from getpass import getpass as gp @@ -14,6 +17,8 @@ except ModuleNotFoundError: exit() def database_enc(): + global conn + global cursor conn = sc.connect("database/keyvault.db") cursor = conn.cursor() if path.isfile("database/keyvault.db"): @@ -106,9 +111,74 @@ def strength(): else: print(f"[PASSWORD STRENGTH]: {passstrength}\n[PASSWORD ENTROPY]: {entropy} bits\nYour password is practically uncrackable.\n") -global db -global conn -global cursor +def add(): + service = username = email = password = website = category = notes = totp = " " + print("For any of these fields, don't type anything to make it an empty field.") + service = input("Enter service: ") + username = input("Enter username: ") + email = input("Enter email: ") + password = gp(prompt = "Enter password (hidden for privacy): ") + website = input("Enter website: ") + category = input("Enter category: ") + notes = input("Enter notes: ") + totp = input("Enter TOTP secret: ") + data = [service, username, email, password, website, category, notes, totp] + for _ in range(len(data)): + if data[_] == "": + data[_] = None + cursor.execute("INSERT INTO data(service, username, email, password, website, category, notes, totp) VALUES(?, ?, ?, ?, ?, ?, ?, ?)", tuple(data)) + conn.commit() + +def ls(cmd="SELECT * FROM data"): + cursor.execute(cmd) + data = list(cursor.fetchall()) + if data == []: + print("The database is empty.") + else: + for _ in range(len(data)): + data[_] = list(data[_]) + if data[_][-1] != None: + data[_].append(TOTP(str(data[_][-1])).now()) + else: + data[_].append(None) + + head = ["ID", "Service", "Username", "Email", "Password", "Website", "Category", "Notes", "TOTP Secret", "TOTP Code"] + print(tabulate(data, headers = head, tablefmt = "grid")) + return data + +def rm(): + ls() + delid = int(input("Enter the ID of the record you want to delete: ")) + cursor.execute("DELETE FROM data WHERE id=?", (delid,)) + conn.commit() + +def find(): + print("The following search criteria are available: id, service, username, email, website, category") + criterian = input("Enter your criterian here: ").lower() + if criterian not in ['id', 'service', 'username', 'email', 'website', 'category']: + print("You have selected an invalid criterian.") + else: + srchquery = input("Enter your search query: ") + sqlquery = f"SELECT * FROM data WHERE {criterian}='{srchquery}'" + ls(sqlquery) + +def edit(): + print("The following edit criteria are available: id, service, username, email, password, website, category, notes, totp") + criterian = input("Enter your criterian here: ").lower() + if criterian not in ['id', 'service', 'username', 'email', 'password', 'website', 'category', 'notes', 'totp']: + print("You have selected an invalid criterian.") + else: + idsearch = input("Enter the ID of the entry to edit: ") + data = ls(f"SELECT * FROM data WHERE id={idsearch}") + if data == []: + print("This entry does not exist.") + else: + confirmation = input("Is this the correct entry? [y/n] > ").lower() + if confirmation == 'y': + newvalue = input("Enter the new value: ") + cursor.execute(f"UPDATE data SET {criterian}='{newvalue}' WHERE id={idsearch}") + else: + print("You have cancelled the entry edit process.") database_enc() @@ -122,7 +192,17 @@ print("keyvault is ready to use! Type 'help' for a list of commands.\n") while True: command = input("> ").lower() if command == 'help': - print("\nUsage:\n\nls - list entires\nrm - remove entry\ngen - generate a password or username\nstrength - check password strength\nedit - edit an entry\nshow/view - view an entry\nfind/search - open search wizard\nhelp - display this message\nversion - print current version\n") + print("\nUsage:\n\nadd - add an entry\nls - list entires\nrm - remove entry\ngen - generate a password or username\nstrength - check password strength\nedit - edit an entry\nfind/search - open search wizard\nhelp - display this message\nversion - print current version\n") + elif command == 'search' or command == 'find': + find() + elif command == 'ls': + ls() + elif command == 'add': + add() + elif command == 'rm': + rm() + elif command == 'edit': + edit() elif command == 'version': print("keyvault: v1.0.0") elif command == 'gen':