Skip to content

Commit e005514

Browse files
committed
Start decoupling crypto from client
1 parent 059f194 commit e005514

File tree

2 files changed

+77
-54
lines changed

2 files changed

+77
-54
lines changed

src/pw_client.py

Lines changed: 28 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,10 @@ def __init__(self, creds_dir: str, creds_file_path: str):
1717
self.creds_dir = creds_dir
1818
self.creds_file_path = creds_file_path
1919
self.pw_dict = pw_utils.get_pws_from_json_file(creds_file_path)
20+
# TODO: Move crypto to the command
2021
self.crypto = SynchronousEncryption(ENCRYPTION_KEY)
2122

22-
def print_sections(self):
23-
"""Print all keys of a dictionary (depth -> 1)."""
24-
for key in self.pw_dict.keys():
25-
print(key)
26-
27-
def print_keys_of_section(self, section_name):
28-
"""Output all available keys of a section to the console."""
29-
for key in self.pw_dict[section_name].keys():
30-
print(key)
31-
32-
def get_pw(self, entity: str, attribute: str = None, section: str = None,
33-
decryption: bool = True) -> None:
23+
def get_pw(self, entity: str, attribute: str = None, section: str = None) -> dict:
3424
"""Get data from self.pw_dict, copy to clipboard and print to console.
3525
3626
Args:
@@ -41,31 +31,13 @@ def get_pw(self, entity: str, attribute: str = None, section: str = None,
4131
section (str, optional):
4232
Defaults to "main". Adjust if you want to access data from an
4333
other section.
44-
decryption (bool, defaults to True):
45-
If set to True this function will decrypt the password before
46-
copying it to the clipboard.
4734
"""
4835
if attribute is None:
4936
attribute = 'password'
5037
if section is None:
5138
section = 'main'
52-
53-
pw_info = self.pw_dict[section][entity]
54-
55-
if decryption is True and attribute == 'password':
56-
pw_info[attribute] = self.crypto.decrypt(pw_info[attribute])
57-
58-
pyperclip.copy(pw_info[attribute])
59-
60-
print(f'Copied {attribute} for "{entity}" into your clipboard.')
61-
print('')
62-
63-
def create_backup(self):
64-
"""Create a backup of the dictionary with the passwords."""
65-
now = datetime.datetime.now().isoformat()
66-
pretty_now = now.split('.')[0].replace(':', '.')
67-
with open(f'{self.creds_dir}/.backups/{pretty_now}', 'w') as pw_file_json:
68-
json.dump(self.pw_dict, pw_file_json)
39+
pw_data = self.pw_dict[section][entity]
40+
return pw_data
6941

7042
@staticmethod
7143
def generate_random_password(special_characters=True,
@@ -78,18 +50,6 @@ def generate_random_password(special_characters=True,
7850
random_password = ''.join(random.choice(characters) for i in range(password_length))
7951
return random_password
8052

81-
@staticmethod
82-
def copy_and_print_pw(pw):
83-
pyperclip.copy(pw)
84-
print('Here is your random password:')
85-
print(pw)
86-
print('It has been copied into your clipboard.')
87-
print('')
88-
89-
def save_dict_to_file(self):
90-
with open(self.creds_file_path, 'w') as pw_file_json:
91-
json.dump(self.pw_dict, pw_file_json)
92-
9353
def add_new_pw(self, entity: str, password: str = None, username: str = None,
9454
website: str = None, section: 'str' = None,
9555
encryption: bool = True) -> None:
@@ -135,6 +95,17 @@ def add_new_pw(self, entity: str, password: str = None, username: str = None,
13595
self.pw_dict[section].update(new_password)
13696
self.save_dict_to_file()
13797

98+
def create_backup(self):
99+
"""Create a backup of the dictionary with the passwords."""
100+
now = datetime.datetime.now().isoformat()
101+
pretty_now = now.split('.')[0].replace(':', '.')
102+
with open(f'{self.creds_dir}/.backups/{pretty_now}', 'w') as pw_file_json:
103+
json.dump(self.pw_dict, pw_file_json)
104+
105+
def save_dict_to_file(self):
106+
with open(self.creds_file_path, 'w') as pw_file_json:
107+
json.dump(self.pw_dict, pw_file_json)
108+
138109
def create_section(self, section_name: str) -> None:
139110
"""Creates a new section."""
140111
if self.check_existence_of_section(section_name):
@@ -143,6 +114,16 @@ def create_section(self, section_name: str) -> None:
143114
self.save_dict_to_file()
144115
print(f'Created a new section: "{section_name}".')
145116

117+
def print_sections(self):
118+
"""Print all keys of a dictionary (depth -> 1)."""
119+
for key in self.pw_dict.keys():
120+
print(key)
121+
122+
def print_keys_of_section(self, section_name):
123+
"""Output all available keys of a section to the console."""
124+
for key in self.pw_dict[section_name].keys():
125+
print(key)
126+
146127
def check_existence_of_section(self, section: str):
147128
if section in self.pw_dict:
148129
return True
@@ -181,6 +162,9 @@ def manipulate_passwords(self, crypto: Callable = None) -> None:
181162
v["password"] = manipulated_password
182163
self.save_dict_to_file()
183164

165+
def encrypt_single_string(self, text: str) -> str:
166+
return self.crypto.encrypt(text)
167+
184168
def encrypt_all_passwords(self):
185169
self.create_backup()
186170
self.manipulate_passwords(self.crypto.encrypt)

src/pw_command.py

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717
"""
1818
import argparse
1919

20+
import pyperclip
21+
2022
from pw_config import CREDS_DIR, CREDS_FILE_PATH
2123
import pw_client
24+
from pw_encryption import SynchronousEncryption
25+
from pw_config import ENCRYPTION_KEY
2226

2327
HELP_TEXT = {
2428
'input': 'Name of entity that holds the password.',
@@ -42,7 +46,7 @@
4246

4347

4448
def parse_args():
45-
parser = argparse.ArgumentParser(description='Manage your passwords from the terminal.')
49+
parser = argparse.ArgumentParser(description='Manage your passwords from your terminal.')
4650
parser.add_argument('input', type=str, help=HELP_TEXT['input'], nargs='?')
4751
parser.add_argument('-as', '--all_sections', action='store_true', help=HELP_TEXT['all_sections'])
4852
parser.add_argument('-s', '--section', type=str, help=HELP_TEXT['section'])
@@ -58,20 +62,31 @@ def parse_args():
5862
return args
5963

6064

61-
def main(parsed_args):
62-
args = parsed_args
65+
def main():
66+
args = parse_args()
67+
crypto = SynchronousEncryption(ENCRYPTION_KEY)
6368
pw = pw_client.PasswordClient(CREDS_DIR, CREDS_FILE_PATH)
6469

70+
# TODO: Get data inside pw_command.py
71+
# pw_data = pw.get_pw(???)
72+
6573
if args.all_sections:
6674
return pw.print_sections()
6775

6876
if args.add_new_password:
77+
if args.set_password:
78+
encrypted_password = crypto.encrypt(args.set_password)
79+
else:
80+
new_random_password = pw.generate_random_password()
81+
encrypted_password = crypto.encrypt(new_random_password)
6982
return pw.add_new_pw(entity=args.add_new_password, username=args.username,
7083
website=args.website, section=args.section,
71-
password=args.set_password)
84+
password=encrypted_password)
7285

7386
if args.username:
74-
return pw.get_pw(args.username, 'username', args.section)
87+
decrypted_username = pw.get_pw(args.username, 'username', args.section)
88+
encrypted_username = crypto.encrypt(decrypted_username)
89+
return encrypted_username
7590

7691
if args.website:
7792
return pw.get_pw(args.website, 'website', args.section)
@@ -83,7 +98,9 @@ def main(parsed_args):
8398
return pw.remove_section(args.remove_section)
8499

85100
if args.section and args.input:
86-
return pw.get_pw(entity=args.input, section=args.section)
101+
encrypted_password = pw.get_pw(entity=args.input, section=args.section)
102+
password = crypto.decrypt(encrypted_password)
103+
return password
87104

88105
if args.section:
89106
try:
@@ -96,14 +113,36 @@ def main(parsed_args):
96113
random_pw = pw.generate_random_password(password_length=int(args.input))
97114
else:
98115
random_pw = pw.generate_random_password()
99-
return pw.copy_and_print_pw(random_pw)
116+
pyperclip.copy(random_pw)
117+
print('The random password has been copied into your clipboard.')
118+
print('')
119+
return random_pw
100120

101121
if args.input is None:
102122
return print('Nothing happened. No flags used. No args passed after pw command.')
103123

104-
return pw.get_pw(args.input)
124+
if args.input:
125+
encrypted_password = pw.get_pw(args.input)
126+
decrypted_password = crypto.decrypt(encrypted_password)
127+
pyperclip.copy(decrypted_password)
128+
print(f'Copied {attribute} for "{entity}" into your clipboard.')
129+
print('')
130+
return encrypted_password
131+
132+
133+
def decrypt_pw_file():
134+
pw = pw_client.PasswordClient(CREDS_DIR, CREDS_FILE_PATH)
135+
return pw.decrypt_all_passwords()
136+
137+
138+
def encrypt_pw_file():
139+
pw = pw_client.PasswordClient(CREDS_DIR, CREDS_FILE_PATH)
140+
return pw.encrypt_all_passwords()
105141

106142

107143
if __name__ == '__main__':
108-
args = parse_args()
109-
main(args)
144+
main()
145+
146+
# decrypt_pw_file()
147+
# encrypt_pw_file()
148+

0 commit comments

Comments
 (0)