-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.py
159 lines (147 loc) · 4.97 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
"""
===============================================
================= IVY JOURNAL =================
===============================================
A fully encrypted journal that can be used to store personal info/data.
Author: Vachan MN
github: vachanmn123
email: [email protected]
discord: TakedownIvy#3869
This program needs a `config.json` file to work.
FILE NAME: main.py
This file contains the main program loop.
"""
# Import nessesary modules
import json
import os
import hashlib
from cryptography.fernet import Fernet
import base64
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
import getpass
# set authenticated flag to false by default
authenticated = False
# Load the config
try:
with open('config.json', 'r') as f:
config = json.load(f)
except FileNotFoundError:
# If the config file doesn't exist print an error message
print("Config file not found. Please create a config.json file.")
exit()
# Load the path to the storage folder
try:
path_to_storage = os.path.join(config['path_to_storage'])
except FileNotFoundError:
# If the path to the storage folder doesn't exist print an error message
print(f"No such file or directory: '{config['path_to_storage']}'")
exit()
if not os.path.join(path_to_storage, 'passwd.ivypaswd'):
# If the password file doesn't exist print an error message
print("No password file found. Please create a passwd.ivypaswd file using create_journal.py")
exit()
# Ask user for password to journal and hash it SHA256
usr_passwd = hashlib.sha256(getpass.getpass(prompt="Please enter your password: ").encode()).hexdigest()
# Get stored password from file
with open(os.path.join(path_to_storage, 'paswd.ivypwd'), 'r') as f:
stored_passwd = f.read()
# Check if the password is correct
if usr_passwd == stored_passwd.lower():
# If the password is correct set authenticated flag to True
print("Loading your journal!\n")
authenticated = True
else:
# If the password is incorrect print an error message and exit
print("Wrong password")
authenticated = False
exit()
# Generate a new Fernet key from the entered password
usr_pwd = usr_passwd.encode()
salt = config['salt'].encode()
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),length=32,salt=salt,iterations=100000)
key = base64.urlsafe_b64encode(kdf.derive(usr_pwd))
Fernet = Fernet(key)
def create_entry():
"""
This function creates a new entry in the loaded journal
"""
# Ask user for the title of the entry
entry_name = input("Please enter the name of your entry: ").lower().replace(" ", "")
# Ask user for the content of the entry
entry_content = (f'{entry_name}\n\n{input("Please enter the content of your entry: ")}').encode()
# Encrypt the entry_content
enc_entry_content = Fernet.encrypt(entry_content)
entry_content = ''
# Save the entry_content to a file
try:
with open(os.path.join(path_to_storage, f'{entry_name}.ivyentry'), 'wb') as f:
f.write(enc_entry_content)
f.close()
# Print a success message
print(f"Entry '{entry_name}' created!")
return
except Exception as e:
# If error occurs print the error message
print("An exception occured: ", e)
return
def list_entries():
all_files=os.listdir(path_to_storage)
entries = []
for file in all_files:
if file.endswith('.ivyentry'):
entries.append(file.replace('.ivyentry', ''))
print(entries)
return
def read_entry():
all_files=os.listdir(path_to_storage)
search = f'{input("Please enter the entry name: ")}.ivyentry'
if search in all_files:
entry = os.path.join(path_to_storage, search)
with open(entry, 'rb') as f:
entry_content = f.read()
entry_content = Fernet.decrypt(entry_content)
print(entry_content.decode())
return
else:
print("No such entry found")
return
def delete_entry():
all_files=os.listdir(path_to_storage)
search = f'{input("Please enter the entry name: ")}.ivyentry'
if search in all_files:
entry = os.path.join(path_to_storage, search)
os.remove(entry)
print(f"Entry '{search}' deleted!")
return
else:
print("No such entry found")
return
# List of all valid choices to be offered to user
options = [
'1. Create a new entry',
'2. List all entries',
'3. Read entry',
'4. Delete an entry',
'5. Exit'
]
# Print the options when authenticated
while authenticated:
for option in options:
print(option)
# take user input for their choice
choice = input("Select your option: ")
# call specific function based on choice
if choice == '1':
create_entry()
elif choice == '2':
list_entries()
elif choice == '3':
read_entry()
elif choice == '4':
delete_entry()
elif choice == '5':
print("Bye Bye!")
exit()
else:
print("Invalid choice")