Skip to content

Commit 993d3db

Browse files
committed
v1.1 Release: Enhanced Security
1 parent 12c6203 commit 993d3db

3 files changed

Lines changed: 48 additions & 27 deletions

File tree

app-gui.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import os
77
import sys
88
from dotenv import load_dotenv
9+
import bcrypt # Added bcrypt for password hashing
910

1011
# Load environment variables from .env file
1112
load_dotenv()
@@ -15,6 +16,10 @@
1516
redis_port = int(os.getenv("REDIS_PORT"))
1617
redis_password = os.getenv("REDIS_PASSWORD")
1718

19+
# Validate environment variables
20+
if not redis_host or not redis_port:
21+
raise ValueError("REDIS_HOST and REDIS_PORT must be set.")
22+
1823
# Initialize the Redis connection
1924
redis_client = redis.StrictRedis(
2025
host=redis_host,
@@ -25,24 +30,29 @@
2530
)
2631

2732
class User:
28-
def __init__(self, username, password):
33+
def __init__(self, username):
2934
self.username = username
30-
self.password = password
3135

3236
def check_password(self, password):
33-
return self.password == password
37+
stored_password = redis_client.hget('users', self.username)
38+
return stored_password and bcrypt.checkpw(password.encode(), stored_password.encode())
39+
40+
def set_password(self, password):
41+
hashed_password = bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
42+
redis_client.hset('users', self.username, hashed_password)
3443

3544
class UserManager:
3645
def login(self, username, password):
37-
stored_password = redis_client.hget('users', username)
38-
if stored_password and stored_password == password:
39-
return User(username, password)
46+
user = User(username)
47+
if user.check_password(password):
48+
return user
4049
return None
4150

4251
def signup(self, username, password):
4352
if not redis_client.hexists('users', username):
44-
redis_client.hset('users', username, password)
45-
return User(username, password)
53+
user = User(username)
54+
user.set_password(password)
55+
return user
4656
return None
4757

4858
class PackageManager:
@@ -101,7 +111,7 @@ def download_pip(user, packages, progress_callback):
101111
if len(package_info) >= 1:
102112
package_name = package_info[0]
103113
progress_callback(f"Downloading and installing {package_name}...")
104-
subprocess.call(['pip3', 'install', package_name])
114+
subprocess.call([sys.executable, '-m', 'pip', 'install', package_name])
105115
progress_callback(f"{package_name} has been downloaded and installed.")
106116
return True
107117

@@ -116,7 +126,7 @@ def download_all_packages(user, progress_callback):
116126
if len(package_info) >= 1:
117127
package_name = package_info[0]
118128
progress_callback(f"Downloading and installing {package_name}...")
119-
subprocess.call(['pip3', 'install', package_name])
129+
subprocess.call([sys.executable, '-m', 'pip', 'install', package_name])
120130
progress_callback(f"{package_name} has been downloaded and installed.")
121131
return True
122132
else:

app.py

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,21 @@
44
import pkg_resources
55
import os
66
import sys
7-
import pip # Import pip module for direct usage
7+
from dotenv import load_dotenv
8+
import bcrypt # Added bcrypt for password hashing
89

10+
load_dotenv()
911
# Define Redis connection parameters
1012
redis_host = os.getenv("REDIS_HOST")
11-
redis_port = int(os.getenv("REDIS_PORT"))
13+
redis_port = os.getenv("REDIS_PORT")
1214
redis_password = os.getenv("REDIS_PASSWORD")
1315

16+
# Validate environment variables
17+
if not redis_host or not redis_port:
18+
raise ValueError("REDIS_HOST and REDIS_PORT must be set.")
19+
20+
redis_port = int(redis_port)
21+
1422
# Initialize the Redis connection
1523
redis_client = redis.StrictRedis(
1624
host=redis_host,
@@ -21,22 +29,25 @@
2129
)
2230

2331
class User:
24-
def __init__(self, username, password):
32+
def __init__(self, username):
2533
self.username = username
26-
self.password = password
2734

2835
def check_password(self, password):
29-
return self.password == password
36+
stored_password = redis_client.hget('users', self.username)
37+
return stored_password and bcrypt.checkpw(password.encode(), stored_password.encode())
38+
39+
def set_password(self, password):
40+
hashed_password = bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
41+
redis_client.hset('users', self.username, hashed_password)
3042

3143
class UserManager:
3244
def login(self):
3345
while True:
3446
username = input("Enter your username: ")
3547
password = getpass.getpass("Enter your password: ")
36-
stored_password = redis_client.hget('users', username)
37-
38-
if stored_password and stored_password == password:
39-
return User(username, password)
48+
user = User(username)
49+
if user.check_password(password):
50+
return user
4051
else:
4152
print("Invalid username or password. Try again.")
4253

@@ -46,9 +57,10 @@ def signup(self):
4657
password = getpass.getpass("Enter a password: ")
4758

4859
if not redis_client.hexists('users', username):
49-
redis_client.hset('users', username, password)
60+
user = User(username)
61+
user.set_password(password)
5062
print("Signup successful. You can now log in.")
51-
return User(username, password)
63+
return user
5264
else:
5365
print("Username already exists. Try a different one.")
5466

@@ -72,7 +84,6 @@ def get_local_pip_list_using_pip():
7284
Retrieve the list of installed packages using pip module.
7385
"""
7486
try:
75-
# Using python -m pip to avoid wrapper script warning
7687
result = subprocess.run(
7788
[sys.executable, '-m', 'pip', 'list', '--format=freeze'],
7889
capture_output=True,
@@ -117,7 +128,7 @@ def download_all_packages(user):
117128
if len(package_info) >= 1:
118129
package_name = package_info[0]
119130
print(f"Downloading and installing {package_name}...")
120-
subprocess.call(['pip3', 'install', package_name])
131+
subprocess.call([sys.executable, '-m', 'pip', 'install', package_name])
121132
print(f"{package_name} has been downloaded and installed.")
122133
else:
123134
print("No pip data found for the user.")
@@ -140,7 +151,6 @@ def main():
140151
user = user_manager.signup()
141152
elif choice == '3':
142153
if user is not None:
143-
# Ask the user whether to use the pip module or pkg_resources
144154
use_pip_module = input("Use pip module to get pip list? (yes/no): ").strip().lower() == 'yes'
145155
package_manager.upload_pip(user, use_pip_module)
146156
else:
@@ -152,12 +162,12 @@ def main():
152162
print("Please log in first.")
153163
elif choice == '5':
154164
if user is not None:
155-
user = None # Sign out by resetting the user
165+
user = None
156166
print("Signed out.")
157167
else:
158168
break
159169
else:
160170
print("Invalid choice. Please try again.")
161171

162172
if __name__ == '__main__':
163-
main()
173+
main()

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
tkinter
22
redis
3-
python-dotenv
3+
python-dotenv
4+
import bcrypt

0 commit comments

Comments
 (0)