Commit d5cd51e4 authored by Benjamin REED's avatar Benjamin REED

working build, basically feature complete, could use some bug testing

parent 792c364a
Pipeline #3049 canceled with stages
import sys import sys
from typing import Optional
import secrets import secrets
import os import os
import random import random
...@@ -156,93 +157,40 @@ class State: ...@@ -156,93 +157,40 @@ class State:
file.close() file.close()
def caesar_cipher(inp, offset):
pass
def generate_password(length, charset): def generate_password(length, charset):
s = [] s = []
for i in range(0, length): for i in range(0, length):
s.append(random.choice(list(charset))) s.append(random.choice(list(charset)))
return ''.join(s) return ''.join(s)
def aes_256(inp):
pass
def handle_args(db: str, password: str): def handle_args(db: str, password: str):
state = State(db, password) state = State(db, password)
return state return state
def main(): def handle_command(state: State, args: [str], cfg) -> Optional[bool]:
filepath = ""
if len(sys.argv) < 2:
print(f"No database path supplied. Usage: {sys.argv[0]} <database path> <password>")
return
else:
filepath = sys.argv[1]
if len(sys.argv) < 3:
print(f"No password supplied. Usage: {sys.argv[0]} <database path> <password>");
return
password = sys.argv[2]
try:
state = handle_args(filepath, password)
except FileNotFoundError:
print(f"Error while opening database file, {filepath} does not exist or cannot be opened.")
ask = input(f"Create {filepath}? (Y/N)")
ask = ask.strip()
ask = ask.lower()
if ask == "y":
file = open(filepath, "xb")
salt = secrets.token_bytes(16)
key = password_encrypt("super secret hihi >_>".encode(), password)
file.write(key)
file.write('\n'.encode())
file.close()
return main()
else:
return
except Exception as e:
print(f"Error parsing database {filepath}: {e}")
return
# TODO: make this serialized (somehow... :[)
cfg = {
"hints": True
}
print("Welcome to SmashPass. Type 'h' or 'help' for help")
while True:
command_input = input(">")
command_input = command_input.strip()
args = command_input.split(" ")
if len(args) == 0:
continue
command = args[0] command = args[0]
if command == "q" or command == "quit" or command == "exit": if command == "q" or command == "quit" or command == "exit":
if len(args) == 2: if len(args) == 2:
if args[1] == "f" or args[1] == "force" or args[1] == "nosave": if args[1] == "f" or args[1] == "force" or args[1] == "nosave":
if confirm("Are you sure you want to exit without saving?", "y", "n"): if len(args) > 2 and args[2] == "y":
return return True
elif confirm("Are you sure you want to exit without saving?", "y", "n"):
return True
else: else:
break return False
if command == "cfg" or command == "config" or command == "settings": if command == "cfg" or command == "config" or command == "settings":
if len(args) < 2: if len(args) < 2:
print(f"Settings: hints: {cfg['hints']}, ...") print(f"Settings: hints: {cfg['hints']}, ...")
continue return None
s = args[1].split("=") s = args[1].split("=")
if len(s) < 2: if len(s) < 2:
print(f"Incorrect format for modifying program parameters. Usage: {USAGES['cfg']}") print(f"Incorrect format for modifying program parameters. Usage: {USAGES['cfg']}")
continue return None
if s[0] not in cfg: if s[0] not in cfg:
print(f"Unknown cfg parameter '{s[0]}'. Type 'cfg' for a list of config parameters.") print(f"Unknown cfg parameter '{s[0]}'. Type 'cfg' for a list of config parameters.")
continue return None
try: try:
cfg[s[0]] = s[1] cfg[s[0]] = s[1]
except: except:
...@@ -257,15 +205,13 @@ def main(): ...@@ -257,15 +205,13 @@ def main():
cmd = args[1] cmd = args[1]
if not cmd in USAGES: if not cmd in USAGES:
print("Unknown command, you may have mistyped it.") print("Unknown command, you may have mistyped it.")
continue return None
print(USAGES[cmd]) print(USAGES[cmd])
elif command == "echo": elif command == "echo":
if len(args) < 2: if len(args) < 2:
print(f"Too few arguments for {command}, usage: {USAGES['echo']}") print(f"Too few arguments for {command}, usage: {USAGES['echo']}")
continue return None
print(" ".join(args[1:])) print(" ".join(args[1:]))
elif command == "dbg":
print(vars(state))
elif command == "save" or command == "s": elif command == "save" or command == "s":
try: try:
state.save() state.save()
...@@ -275,7 +221,7 @@ def main(): ...@@ -275,7 +221,7 @@ def main():
elif command == "drop" or command == "delete" or command == "del" or command == "rm": elif command == "drop" or command == "delete" or command == "del" or command == "rm":
if len(args) < 2: if len(args) < 2:
print(f"Too few arguments for command {command}, usage: {USAGES['drop']}") print(f"Too few arguments for command {command}, usage: {USAGES['drop']}")
continue return None
label = args[1].strip().lower() label = args[1].strip().lower()
if label in state.to_remove: if label in state.to_remove:
...@@ -294,13 +240,13 @@ def main(): ...@@ -294,13 +240,13 @@ def main():
elif command == "undo" or command == "un": elif command == "undo" or command == "un":
if len(state.to_remove) == 0: if len(state.to_remove) == 0:
print("Already on latest change") print("Already on latest change")
continue return None
ltst = state.to_remove.pop() ltst = state.to_remove.pop()
print(f"Undone latest deletion: {ltst}") print(f"Undone latest deletion: {ltst}")
elif command == "restore" or command == "res" or command == "r": elif command == "restore" or command == "res" or command == "r":
if len(args) < 2: if len(args) < 2:
print(f"Too few arguments for command {command}. Usage: {USAGES['restore']}") print(f"Too few arguments for command {command}. Usage: {USAGES['restore']}")
continue return None
args[1].strip() args[1].strip()
og_label = args[1].lower() og_label = args[1].lower()
...@@ -327,7 +273,7 @@ def main(): ...@@ -327,7 +273,7 @@ def main():
elif command == "rename" or command == "rn": elif command == "rename" or command == "rn":
if len(args) < 3: if len(args) < 3:
print(f"Too few args for {command}. Usage: {USAGES['rename']}.") print(f"Too few args for {command}. Usage: {USAGES['rename']}.")
continue return None
if args[1] in state.passwords: if args[1] in state.passwords:
state.passwords[args[2]] = state.passwords[args[1]] state.passwords[args[2]] = state.passwords[args[1]]
...@@ -346,12 +292,12 @@ def main(): ...@@ -346,12 +292,12 @@ def main():
elif command == "new": # Form: new <length> [ <label> ] elif command == "new": # Form: new <length> [ <label> ]
if len(args) < 2: if len(args) < 2:
print(f"Too few arguments for {command}, usage: {USAGES['new']}") print(f"Too few arguments for {command}, usage: {USAGES['new']}")
continue return None
try: try:
length = int(args[1]) length = int(args[1])
except: except:
print(f"Error parsing length as number, usage: {USAGES['new']}") print(f"Error parsing length as number, usage: {USAGES['new']}")
continue return None
if len(args) >= 3: if len(args) >= 3:
label = args[2] label = args[2]
...@@ -370,7 +316,7 @@ def main(): ...@@ -370,7 +316,7 @@ def main():
if cfg['hints'] == True: if cfg['hints'] == True:
print("(Hint: use the 'restore' command to undo this action)") print("(Hint: use the 'restore' command to undo this action)")
else: else:
continue return None
charset = "all" charset = "all"
...@@ -403,8 +349,67 @@ def main(): ...@@ -403,8 +349,67 @@ def main():
print("(Hint: type 'list <key>' to decrypt your chosen password") print("(Hint: type 'list <key>' to decrypt your chosen password")
elif len(args) == 2: elif len(args) == 2:
print(state.get_password(args[1]).decode('utf-8')) print(state.get_password(args[1]).decode('utf-8'))
return None
def main():
filepath = ""
if len(sys.argv) < 2:
print(f"No database path supplied. Usage: {sys.argv[0]} <database path> <password>")
return
else:
filepath = sys.argv[1]
if len(sys.argv) < 3:
print(f"No password supplied. Usage: {sys.argv[0]} <database path> <password>");
return
password = sys.argv[2]
try:
state = handle_args(filepath, password)
except FileNotFoundError:
print(f"Error while opening database file, {filepath} does not exist or cannot be opened.")
ask = input(f"Create {filepath}? (Y/N)")
ask = ask.strip()
ask = ask.lower()
if ask == "y":
file = open(filepath, "xb")
salt = secrets.token_bytes(16)
key = password_encrypt("super secret hihi >_>".encode(), password)
file.write(key)
file.write('\n'.encode())
file.close()
return main()
else:
return
except Exception as e:
print(f"Error parsing database {filepath}: {e}")
return
# TODO: make this serialized (somehow... :[)
cfg = {
"hints": True
}
print("Welcome to SmashPass. Type 'h' or 'help' for help")
while True:
command_input = input(">")
command_input = command_input.strip()
args = command_input.split(" ")
if len(args) == 0:
continue
should_immediately_exit = None
try:
should_immediately_exit = handle_command(state, args, cfg)
except e:
print(f"ERROR: handling the inputted command: {e}")
if should_immediately_exit is not None:
if should_immediately_exit:
return
else:
break
state.save() state.save()
print("Thanks for using!") print("Thanks for using!")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment