From 40cf3957978cb662cf752b0cedf51724e0cd440e Mon Sep 17 00:00:00 2001 From: Tyler Lightwood Date: Thu, 8 Feb 2024 10:35:34 +0000 Subject: [PATCH] Major changes & refactoring - Removed all sudo scripts and merged into one for better useability as they were extremely similar code-wise - Changed import for sudo to new way and implemented the new way where needed - Added constants for repeated text as to make it easier to read and less repetitive - Refactored N_P_P.py for better readability and scaling. Also removes duped lines and adds a more effective system for showing the options based on the user's level - Created two new scripts to work upon, 'Notifications' and 'Staff_Portal' - Noticed previous variable of 'species' etc was unused in the filter so changed to 'species_query' etc - Ensured the filtered gender only returns those of Male or Female, not both as originally Male would also show Female due to the string containing 'male' --- N_P_P.py | 157 +++++++++++++++-------------------- add_animal.py | 7 +- client_database.py | 30 ++++--- edit_animal_entries.py | 5 +- login.py | 1 + notifications.py | 5 ++ staff_portal.py | 5 ++ sudo_admin.py | 88 -------------------- sudo_user.py | 94 --------------------- sudo_user_level_1.py | 95 --------------------- sudo_user_login.py | 184 +++++++++++++++++++++++++++++++++++++++++ user_management.py | 5 +- view_animal_profile.py | 5 +- view_animals.py | 30 ++++--- 14 files changed, 307 insertions(+), 404 deletions(-) create mode 100644 notifications.py create mode 100644 staff_portal.py delete mode 100644 sudo_admin.py delete mode 100644 sudo_user.py delete mode 100644 sudo_user_level_1.py create mode 100644 sudo_user_login.py diff --git a/N_P_P.py b/N_P_P.py index aec2001..1d30d76 100644 --- a/N_P_P.py +++ b/N_P_P.py @@ -1,8 +1,10 @@ import time from sys import exit from colorama import Fore, Style +from notifications import notifications +from staff_portal import staff_portal from view_animals import view_animals -from common_functions import clear_screen, log_action, hash_password, get_mongodb_uri +from common_functions import clear_screen, log_action, hash_password, get_mongodb_uri, load_animal_data from login import login from client_database import client_database from pymongo import MongoClient @@ -14,6 +16,7 @@ client = MongoClient(uri) db = client['animal_rescue'] users_collection = db['users'] +animals_collection = db['animals'] # Default password default_password = "ADMIN" @@ -29,100 +32,72 @@ "level": 3 } -def main(): - clear_screen() - - try: - while True: - # Display main menu options - print(Fore.CYAN + "\nšŸ• Welcome to Nexus Pet Portal! šŸˆ" + Style.RESET_ALL) - print("\n1. " + Fore.GREEN + "Login" + Style.RESET_ALL) - print("2. " + Fore.YELLOW + "Exit" + Style.RESET_ALL) - choice = input("\nPlease select an option: ") - - if choice == '1': - clear_screen() - # Pull the username and user level from the login function - current_user, user_level = login() - if current_user is not None: - while True: - clear_screen() - # Display main menu after successful login - print(Fore.CYAN + "\nšŸ“– Main Menu šŸ“–" + Style.RESET_ALL) - print("\n1. " + Fore.GREEN + "šŸ¶ Animal Database" + Style.RESET_ALL) - - # Initialize option counter - option_counter = 2 - - # Adjust options based on user level - if user_level >= 2: - print(f"{option_counter}. " + Fore.GREEN + "šŸ§‘ Client Database" + Style.RESET_ALL) - option_counter += 1 - - if user_level >= 3: - print(f"{option_counter}. " + Fore.GREEN + "šŸ‘¤ Staff Portal" + Style.RESET_ALL) - option_counter += 1 - - # Display Notifications option with the correct number - notifications_option = option_counter - print(f"{option_counter}. " + Fore.GREEN + "šŸ”” Notifications" + Style.RESET_ALL) - option_counter += 1 +def logout(): + return True - logout_option = option_counter - # Display Logout option with the correct number - print (f"{option_counter}. " + Fore.YELLOW + "šŸ” Logout" + Style.RESET_ALL) - option = input("\nPlease select an option: ") +# Main menu +def display_menu(options): + for i, option in enumerate(options, 1): + print(f"{i}. {option}") - # Animal Database - if option == '1': - log_action(current_user, "Entered, 'Animal Database" ) - time.sleep(2) - view_animals() - - # Client Database - elif option == '2' and user_level >= 2: - log_action(current_user, "Entered 'Client Database'") - time.sleep(2) - clear_screen() - client_database() - - - # Staff Portal - elif option == '3' and user_level == 3: - log_action(current_user, "Entered 'Staff Portal'") - print("This feature is coming soon.") - time.sleep(2) - - # Notifications - elif option == str(notifications_option): - log_action(current_user, "Entered 'Notifications'") - print("This feature is coming soon.") - time.sleep(2) +def handle_option(option, functions): + try: + # Convert the option to an integer + option = int(option) + # Call the function that corresponds to the selected option + function_choice = functions[option - 1] + result = function_choice() + return result + except (IndexError, ValueError): + print(Fore.RED + "\nInvalid option. Please try again." + Style.RESET_ALL) + time.sleep(2) - # Logout - elif option == str(logout_option): - log_action(current_user, "Logged out") - print("\nLogging out...") - time.sleep(2) - clear_screen() - break - - # Invalid option - else: - print(Fore.RED + "\nInvalid option. Please try again.") - time.sleep(2) - clear_screen() +def main_menu(): + options = [Fore.GREEN + "Login" + Style.RESET_ALL, Fore.YELLOW + "Exit" + Style.RESET_ALL] + functions = [login, exit] + while True: + clear_screen() + print(Fore.CYAN + "\nšŸ• Welcome to Nexus Pet Portal! šŸˆ\n" + Style.RESET_ALL) + display_menu(options) + choice = input("\nPlease select an option: ") + user_details = handle_option(choice, functions) + if user_details is not None: + user_menu(user_details[0], user_details[1]) + +def user_menu(current_user, user_level): + clear_screen() + options = [Fore.GREEN + "šŸ¶ Animal Database" + Style.RESET_ALL] + functions = [view_animals] + # Add options and functions based on user level + if user_level >= 2: + options.append(Fore.GREEN + "šŸ§‘ Client Database" + Style.RESET_ALL) + functions.append(client_database) + if user_level >= 3: + options.append(Fore.GREEN + "šŸ‘¤ Staff Portal" + Style.RESET_ALL) + functions.append(staff_portal) + # Add common options and functions + options.append(Fore.GREEN + "šŸ”” Notifications" + Style.RESET_ALL) + options.append(Fore.YELLOW + "šŸ” Logout" + Style.RESET_ALL) + functions.append(notifications) + functions.append(logout) + while True: + clear_screen() + print(Fore.CYAN + "\nšŸ“– Main Menu šŸ“–\n" + Style.RESET_ALL) + display_menu(options) + choice = input("\nPlease select an option: ") + # Logout option + if choice == str(len(options)): + log_action(current_user, "Logged out") + print("\nLogging out...") + time.sleep(2) + clear_screen() + break + handle_option(choice, functions) - elif choice == '2': - print("\nExiting...") - time.sleep(2) - exit() - - else: - print(Fore.RED + "\nInvalid option. Please try again." + Style.RESET_ALL) - time.sleep(2) - clear_screen() - +def main(): + clear_screen() + try: + main_menu() except KeyboardInterrupt: print("\n\nExiting...") time.sleep(2) diff --git a/add_animal.py b/add_animal.py index 918983c..30479ef 100644 --- a/add_animal.py +++ b/add_animal.py @@ -1,7 +1,7 @@ import time from colorama import Fore, Style from common_functions import clear_screen, log_action, get_mongodb_uri, load_animal_data -from sudo_user import sudo_user +from sudo_user_login import SudoUser from tables import print_animal_table from pymongo import MongoClient @@ -11,6 +11,7 @@ db = client['animal_rescue'] animals_collection = db['animals'] +users_collection = db['users'] def add_animal(): @@ -20,7 +21,7 @@ def add_animal(): while True: clear_screen() - sudo_user() + SudoUser(users_collection.database).login() # Display header print(Fore.CYAN + "\nšŸ¾ Add Animal šŸ¾\n" + Style.RESET_ALL) @@ -65,7 +66,7 @@ def add_animal(): clear_screen() # Make the user verify their identity - current_user = sudo_user() + current_user = SudoUser(users_collection.database).login() # Add hashed animal data to the animals collection animals_collection.insert_one ({ diff --git a/client_database.py b/client_database.py index ab37f20..af91641 100644 --- a/client_database.py +++ b/client_database.py @@ -1,8 +1,19 @@ import time -from sudo_user import sudo_user +from sudo_user_login import SudoUser from colorama import Fore, Style -from common_functions import clear_screen +from common_functions import clear_screen, get_mongodb_uri from customer_adoption_form_dog import adopt_dog_form +from pymongo import MongoClient + +# Connect to MongoDB +uri = get_mongodb_uri() +client = MongoClient(uri) + +db = client['animal_rescue'] +animals_collection = db['animals'] +users_collection = db['users'] + +new_feature_message = "\nThis feature is coming soon." def modify_clint_database(): clear_screen() @@ -30,7 +41,7 @@ def modify_clint_database(): adopt_dog_form() elif adoption_form == 'cats': - print("\nThis feature is coming soon.") + print(new_feature_message) time.sleep(2) clear_screen() @@ -40,7 +51,7 @@ def modify_clint_database(): clear_screen() elif choice == '3': - print("\nThis feature is coming soon.") + print(new_feature_message) time.sleep(2) clear_screen() @@ -48,7 +59,7 @@ def modify_clint_database(): print("\nExiting Modify Database...") time.sleep(1) clear_screen() - return + else: print(Fore.RED + "Invalid input. Please try again." + Style.RESET_ALL) @@ -60,7 +71,7 @@ def client_database(): clear_screen() - sudo_user() + SudoUser(users_collection.database).login() print(Fore.CYAN + "\nšŸ§‘ Client Database šŸ§‘" + Style.RESET_ALL) print("\n1. " + Fore.GREEN + "šŸ” Search" + Style.RESET_ALL) @@ -70,7 +81,7 @@ def client_database(): choice = input("\nPlease select an option: ") if choice == '1': - print("This feature is coming soon.") + print(new_feature_message) time.sleep(2) clear_screen() @@ -80,15 +91,14 @@ def client_database(): modify_clint_database() elif choice == '3': - print("This feature is coming soon.") - time.sleep(2) + print(new_feature_message) + time.sleep(1) clear_screen() elif choice == '4': print("Exiting Client Database...") time.sleep(1) clear_screen() - return else: print(Fore.RED + "\nInvalid input. Please try again." + Style.RESET_ALL) diff --git a/edit_animal_entries.py b/edit_animal_entries.py index 4032137..43fcf37 100644 --- a/edit_animal_entries.py +++ b/edit_animal_entries.py @@ -3,7 +3,7 @@ from tables import print_animal_table from colorama import Fore, Style from pymongo import MongoClient -from sudo_user import sudo_user +from sudo_user_login import SudoUser # Connect to MongoDB uri = get_mongodb_uri() @@ -11,6 +11,7 @@ db = client['animal_rescue'] animals_collection = db['animals'] +users_collection = db['users'] FIELDS = { 1: "name", @@ -46,7 +47,7 @@ def modify_animal(): animals = load_animal_data(animals_collection) clear_screen() - sudo_user() + SudoUser(users_collection.database).login() print(Fore.CYAN + "\nšŸ¾ Modify Animal šŸ¾\n" + Style.RESET_ALL) animal_name = get_animal_name() diff --git a/login.py b/login.py index 1c86da5..66d6434 100644 --- a/login.py +++ b/login.py @@ -96,6 +96,7 @@ def reset_password(username): reset_password(username) def login(): + clear_screen() attempts = 0 # Continuous loop for login while attempts < MAX_ATTEMPTS: diff --git a/notifications.py b/notifications.py new file mode 100644 index 0000000..26c2348 --- /dev/null +++ b/notifications.py @@ -0,0 +1,5 @@ +import time + +def notifications(): + print("\nThis is the notifications feature. It is currently under construction. Please come back later.") + time.sleep(2) \ No newline at end of file diff --git a/staff_portal.py b/staff_portal.py new file mode 100644 index 0000000..a575619 --- /dev/null +++ b/staff_portal.py @@ -0,0 +1,5 @@ +import time + +def staff_portal(): + print("\nThis is the staff portal. It is currently under construction. Please come back later.") + time.sleep(2) \ No newline at end of file diff --git a/sudo_admin.py b/sudo_admin.py deleted file mode 100644 index ef6cc45..0000000 --- a/sudo_admin.py +++ /dev/null @@ -1,88 +0,0 @@ -import getpass -import time -from colorama import Fore, Style -from common_functions import clear_screen, log_action, verify_password, get_mongodb_uri -from pymongo import MongoClient - -MAX_ATTEMPTS = 2 - -# Connect to MongoDB -uri = get_mongodb_uri() -client = MongoClient(uri) -db = client['animal_rescue'] -users_collection = db['users'] - -def sudo_admin(): - clear_screen() - - attempts = 0 - while attempts < MAX_ATTEMPTS: - print(Fore.LIGHTMAGENTA_EX + "\nšŸ‘¤ ADMIN Sudo Login šŸ‘¤" + Style.RESET_ALL) - print("\nPlease enter your credentials") - - username, password = get_credentials() - if username is None or password is None: - continue - - user = users_collection.find_one({'username': username}) - - if user: - stored_password = user['hashed_password'] - - if verify_password(stored_password, password): - if username == "ADMIN": - print(Fore.GREEN +"\nUser Verified..." + Style.RESET_ALL) - time.sleep(2) - clear_screen() - return username - else: - print_insufficient_clearance(username) - exit() - else: - print_incorrect_password(username, attempts) - attempts += 1 - else: - print_username_not_found() - - print_max_attempts_reached() - -def get_credentials(): - username = input("\nEnter your username: ") - password = getpass.getpass("Enter your password: ") - - if not username or not password: - print(Fore.RED + "\nUsername and password are required." + Style.RESET_ALL) - time.sleep(2) - clear_screen() - return None, None - - return username, password - -def print_insufficient_clearance(username): - print(Fore.RED + "\nYou do not have clearance to do this." + Style.RESET_ALL) - time.sleep(1) - print(Fore.RED + "\nADMIN user will be alerted." + Style.RESET_ALL) - time.sleep(1) - print(Fore.RED + "\nExiting..." + Style.RESET_ALL) - time.sleep(1) - log_action(username, "Tried to access without clearance") - -def print_incorrect_password(username, attempts): - print(Fore.RED + "\nIncorrect password." + Style.RESET_ALL) - time.sleep(2) - print(Fore.RED + f"\nRemaining attempts: {MAX_ATTEMPTS - attempts}" + Style.RESET_ALL) - log_action(username, "Failed attempted access via sudo") - time.sleep(2) - clear_screen() - -def print_username_not_found(): - print(Fore.RED + "\nUsername not found. Please try again." + Style.RESET_ALL) - time.sleep(2) - clear_screen() - -def print_max_attempts_reached(): - print(Fore.RED + "\nMaximum login attempts reached" + Style.RESET_ALL) - time.sleep(1) - print("\nExiting...") - time.sleep(2) - exit() \ No newline at end of file diff --git a/sudo_user.py b/sudo_user.py deleted file mode 100644 index deab430..0000000 --- a/sudo_user.py +++ /dev/null @@ -1,94 +0,0 @@ -import getpass -import time -from colorama import Fore, Style -from common_functions import clear_screen, log_action, verify_password, get_mongodb_uri -from pymongo import MongoClient - -MAX_ATTEMPTS = 2 - -# Connect to MongoDB -uri = get_mongodb_uri() -client = MongoClient(uri) -db = client['animal_rescue'] -users_collection = db['users'] - -def sudo_user(): - clear_screen() - attempts = 0 - - while attempts < MAX_ATTEMPTS: - print(Fore.LIGHTMAGENTA_EX + "\nšŸ‘¤ Sudo Login šŸ‘¤" + Style.RESET_ALL) - print("\nPlease enter your credentials") - - username, password = get_credentials() - if username is None or password is None: - continue - - user = users_collection.find_one({'username': username}) - - if user: - stored_password = user['hashed_password'] - - if verify_password(stored_password, password): - user_level = user['level'] - - if username == "ADMIN": - print("\nNot a valid username") - clear_screen() - return username - elif user_level >= 2: - print(Fore.GREEN +"\nUser Verified..." + Style.RESET_ALL) - time.sleep(2) - clear_screen() - return username - else: - print_insufficient_clearance(username) - exit() - else: - print_incorrect_password(username, attempts) - attempts += 1 - else: - print_username_not_found() - - print_max_attempts_reached() - -def get_credentials(): - username = input("\nEnter your username: ") - password = getpass.getpass("Enter your password: ") - - if not username or not password: - print(Fore.RED + "\nUsername and password are required." + Style.RESET_ALL) - time.sleep(2) - clear_screen() - return None, None - - return username, password - -def print_insufficient_clearance(username): - print(Fore.RED + "\nYou do not have clearance to do this." + Style.RESET_ALL) - time.sleep(1) - print(Fore.RED + "\nADMIN user will be alerted." + Style.RESET_ALL) - time.sleep(1) - print(Fore.RED + "\nExiting..." + Style.RESET_ALL) - time.sleep(1) - log_action(username, "Tried to access without clearance") - -def print_incorrect_password(username, attempts): - print(Fore.RED + "\nIncorrect password." + Style.RESET_ALL) - time.sleep(2) - print(Fore.RED + f"\nRemaining attempts: {MAX_ATTEMPTS - attempts}" + Style.RESET_ALL) - log_action(username, "Failed attempted access via sudo") - time.sleep(2) - clear_screen() - -def print_username_not_found(): - print(Fore.RED + "\nUsername not found. Please try again." + Style.RESET_ALL) - time.sleep(2) - clear_screen() - -def print_max_attempts_reached(): - print(Fore.RED + "\nMaximum login attempts reached" + Style.RESET_ALL) - time.sleep(1) - print("\nExiting...") - time.sleep(2) - exit() \ No newline at end of file diff --git a/sudo_user_level_1.py b/sudo_user_level_1.py deleted file mode 100644 index 75fab47..0000000 --- a/sudo_user_level_1.py +++ /dev/null @@ -1,95 +0,0 @@ -import getpass -import time -from colorama import Fore, Style -from common_functions import clear_screen, log_action, verify_password, get_mongodb_uri -from pymongo import MongoClient - -MAX_ATTEMPTS = 2 - -# Connect to MongoDB -uri = get_mongodb_uri() -client = MongoClient(uri) -db = client['animal_rescue'] -users_collection = db['users'] - -def sudo_user(): - clear_screen() - attempts = 0 - - while attempts < MAX_ATTEMPTS: - print(Fore.LIGHTMAGENTA_EX + "\nšŸ‘¤ Sudo Login šŸ‘¤" + Style.RESET_ALL) - print("\nPlease enter your credentials") - - username, password = get_credentials() - if username is None or password is None: - continue - - user = users_collection.find_one({'username': username}) - - if user: - stored_password = user['hashed_password'] - - if verify_password(stored_password, password): - user_level = user['level'] - - if username == "ADMIN": - print("\nNot a valid username") - clear_screen() - sudo_user() - return username - elif user_level >= 1: - print(Fore.GREEN +"\nUser Verified..." + Style.RESET_ALL) - time.sleep(2) - clear_screen() - return user - else: - print_insufficient_clearance(username) - exit() - else: - print_incorrect_password(username, attempts) - attempts += 1 - else: - print_username_not_found() - - print_max_attempts_reached() - -def get_credentials(): - username = input("\nEnter your username: ") - password = getpass.getpass("Enter your password: ") - - if not username or not password: - print(Fore.RED + "\nUsername and password are required." + Style.RESET_ALL) - time.sleep(2) - clear_screen() - return None, None - - return username, password - -def print_insufficient_clearance(username): - print(Fore.RED + "\nYou do not have clearance to do this." + Style.RESET_ALL) - time.sleep(1) - print(Fore.RED + "\nADMIN user will be alerted." + Style.RESET_ALL) - time.sleep(1) - print(Fore.RED + "\nExiting..." + Style.RESET_ALL) - time.sleep(1) - log_action(username, "Tried to access without clearance") - -def print_incorrect_password(username, attempts): - print(Fore.RED + "\nIncorrect password." + Style.RESET_ALL) - time.sleep(2) - print(Fore.RED + f"\nRemaining attempts: {MAX_ATTEMPTS - attempts}" + Style.RESET_ALL) - log_action(username, "Failed attempted access via sudo") - time.sleep(2) - clear_screen() - -def print_username_not_found(): - print(Fore.RED + "\nUsername not found. Please try again." + Style.RESET_ALL) - time.sleep(2) - clear_screen() - -def print_max_attempts_reached(): - print(Fore.RED + "\nMaximum login attempts reached" + Style.RESET_ALL) - time.sleep(1) - print("\nExiting...") - time.sleep(2) - exit() \ No newline at end of file diff --git a/sudo_user_login.py b/sudo_user_login.py new file mode 100644 index 0000000..5904ea7 --- /dev/null +++ b/sudo_user_login.py @@ -0,0 +1,184 @@ +import time +import getpass +from common_functions import clear_screen, verify_password, log_action +from colorama import Fore, Style + +user_verified = "\nUser Verified..." +enter_credentials = "\nPlease enter your credentials" + +class SudoUser: + MAX_ATTEMPTS = 2 + + def __init__(self, db): + self.db = db + self.users_collection = db['users'] + + def login(self): + clear_screen() + MAX_ATTEMPTS = 2 + + for attempts in range(MAX_ATTEMPTS): + print(Fore.LIGHTMAGENTA_EX + "\nšŸ‘¤ Sudo Login šŸ‘¤" + Style.RESET_ALL) + print(enter_credentials) + + username, password = self.get_credentials() + if username is None or password is None: + continue + + user = self.attempt_login(username, password, attempts) + if user: + return user + + self.print_max_attempts_reached() + + def attempt_login(self, username, password, attempts): + user = self.users_collection.find_one({'username': username}) + + if user: + stored_password = user['hashed_password'] + + if verify_password(stored_password, password): + user_level = user['level'] + + if username == "ADMIN": + print("\nNot a valid username") + clear_screen() + return None + elif user_level >= 2: + print(Fore.GREEN + user_verified + Style.RESET_ALL) + time.sleep(2) + clear_screen() + return username + else: + self.print_insufficient_clearance(username) + exit() + else: + self.print_incorrect_password(username, attempts) + else: + self.print_username_not_found() + + return user + + def get_credentials(self): + username = input("\nEnter your username: ") + password = getpass.getpass("Enter your password: ") + + if not username or not password: + print(Fore.RED + "\nUsername and password are required." + Style.RESET_ALL) + time.sleep(2) + clear_screen() + return None, None + + return username, password + + def print_insufficient_clearance(self, username): + print(Fore.RED + "\nYou do not have clearance to do this." + Style.RESET_ALL) + time.sleep(1) + print(Fore.RED + "\nADMIN user will be alerted." + Style.RESET_ALL) + time.sleep(1) + print(Fore.RED + "\nExiting..." + Style.RESET_ALL) + time.sleep(1) + log_action(username, "Tried to access without clearance") + + def print_incorrect_password(self, username, attempts): + print(Fore.RED + "\nIncorrect password." + Style.RESET_ALL) + time.sleep(2) + print(Fore.RED + f"\nRemaining attempts: {self.MAX_ATTEMPTS - attempts}" + Style.RESET_ALL) + log_action(username, "Failed attempted access via sudo") + time.sleep(2) + clear_screen() + + def print_username_not_found(self): + print(Fore.RED + "\nUsername not found. Please try again." + Style.RESET_ALL) + time.sleep(2) + clear_screen() + + def print_max_attempts_reached(self): + print(Fore.RED + "\nMaximum login attempts reached" + Style.RESET_ALL) + time.sleep(1) + print("\nExiting...") + time.sleep(2) + exit() + + +class SudoUserLevel1(SudoUser): + def login(self): + for attempts in range(self.MAX_ATTEMPTS): + clear_screen() + print(Fore.LIGHTMAGENTA_EX + "\nšŸ‘¤ Sudo Login šŸ‘¤" + Style.RESET_ALL) + print(enter_credentials) + + username, password = self.get_credentials() + if username is None or password is None: + continue + + user = self.attempt_login(username, password, attempts) + if user: + return user + + self.print_max_attempts_reached() + + def attempt_login(self, username, password, attempts): + user = self.users_collection.find_one({'username': username}) + + if user: + stored_password = user['hashed_password'] + + if verify_password(stored_password, password): + user_level = user['level'] + + if username == "ADMIN": + print("\nNot a valid username") + clear_screen() + return username + elif user_level >= 1: + print(Fore.GREEN + user_verified + Style.RESET_ALL) + time.sleep(2) + clear_screen() + return user + else: + self.print_insufficient_clearance(username) + exit() + else: + self.print_incorrect_password(username, attempts) + else: + self.print_username_not_found() + + return user + +class SudoAdmin(SudoUser): + def login(self): + for attempts in range(self.MAX_ATTEMPTS): + clear_screen() + print(Fore.LIGHTMAGENTA_EX + "\nšŸ‘¤ ADMIN Sudo Login šŸ‘¤" + Style.RESET_ALL) + print(enter_credentials) + + username, password = self.get_credentials() + if username is None or password is None: + continue + + if self.attempt_login(username, password, attempts): + return username, + + self.print_max_attempts_reached() + + def attempt_login(self, username, password, attempts): + user = self.users_collection.find_one({'username': username}) + + if user: + stored_password = user['hashed_password'] + + if verify_password(stored_password, password): + if username == "ADMIN": + print(Fore.GREEN + user_verified + Style.RESET_ALL) + time.sleep(2) + return True + else: + self.print_insufficient_clearance(username) + exit() + else: + self.print_incorrect_password(username) + else: + self.print_username_not_found() + + return False \ No newline at end of file diff --git a/user_management.py b/user_management.py index b4c8fab..feee8b1 100644 --- a/user_management.py +++ b/user_management.py @@ -2,8 +2,7 @@ from colorama import Fore, Style from common_functions import clear_screen, hash_password, get_mongodb_uri from pymongo import MongoClient -from sudo_admin import sudo_admin - +from sudo_user_login import SudoAdmin # Connect to MongoDB uri = get_mongodb_uri() @@ -37,7 +36,7 @@ def user_management(): def reset_user_password(username): # Check if the user is ADMIN - sudo_admin() + SudoAdmin(users_collection.database).login() # Change password if the user exists and is not ADMIN user = users_collection.find_one({'username': username}) diff --git a/view_animal_profile.py b/view_animal_profile.py index 90bf169..0866c3a 100644 --- a/view_animal_profile.py +++ b/view_animal_profile.py @@ -4,7 +4,7 @@ from tkinter import filedialog from colorama import Fore, Style from common_functions import clear_screen, log_action, get_mongodb_uri -from sudo_user import sudo_user +from sudo_user_login import SudoUser from tables import print_animal_table_with_index from pymongo import MongoClient @@ -14,6 +14,7 @@ db = client['animal_rescue'] animals_collection = db['animals'] +users_collection = db['users'] invalid_input = "Invalid input! Please enter a valid index." @@ -135,7 +136,7 @@ def upload_image(): def view_animals_full(): clear_screen() - current_user = sudo_user() + current_user = SudoUser(users_collection.database).login() while True: # Continuous loop for viewing the animal options print(Fore.CYAN + "\nāš™ļø Options āš™ļø" + Style.RESET_ALL) diff --git a/view_animals.py b/view_animals.py index f215fad..4b90fbc 100644 --- a/view_animals.py +++ b/view_animals.py @@ -2,7 +2,7 @@ from colorama import Fore, Style from common_functions import clear_screen, load_animal_data, log_action, get_mongodb_uri from view_animal_profile import view_animals_full -from sudo_user_level_1 import sudo_user +from sudo_user_login import SudoUserLevel1, SudoUser from edit_animal_entries import modify_animal from add_animal import add_animal from tables import print_animal_table @@ -14,6 +14,7 @@ db = client['animal_rescue'] animals_collection = db['animals'] +users_collection = db['users'] select_option = "\nPlease select an option: " invalid_input = "\nInvalid input! Please enter a valid index." @@ -46,10 +47,10 @@ def filter_animals(animals): filtered_animals = [] # Iterate through animals and apply filters for animal in animals: - if (not species_query or any(species_query.lower() in animal['species'].lower() for species in species_query.split(','))) and \ - (not breed_query or any(breed_query.lower() in animal['breed'].lower() for breed in breed_query.split(','))) and \ - (not gender_query or any(gender_query.lower() in animal['gender'].lower() for gender in gender_query.split(','))) and \ - (not adopted_query or any(adopted_query.lower() in str(animal['adopted']).lower() for adopted in adopted_query.split(','))): + if (not species_query or any(species_query.lower() in animal['species'].lower() for species_query in species_query.split(','))) and \ + (not breed_query or any(breed_query.lower() in animal['breed'].lower() for breed_query in breed_query.split(','))) and \ + (not gender_query or gender_query.lower() == animal['gender'].lower()) and \ + (not adopted_query or any(adopted_query.lower() in str(animal['adopted']).lower() for adopted_query in adopted_query.split(','))): filtered_animals.append(animal) if filtered_animals: @@ -118,7 +119,6 @@ def handle_found_results(animals, found_results): return elif exit_input == '2': clear_screen_and_print_animals(animals) - return else: print_invalid_input(animals) @@ -256,38 +256,34 @@ def modify_animal_database(): # Delete Animal elif choice == '3': - current_user = sudo_user() + current_user = SudoUser(users_collection.database).login() clear_screen() print_animal_table(animals) animal_name = input("\nEnter the name of the animal to delete: ") if delete_animal(animal_name): log_action(current_user, f"Deleted {animal_name} from the database") - return + else: log_action(current_user, f"Failed to delete {animal_name} from the database") - return # Exit elif choice == '4': print("\nExiting Modify Database...") time.sleep(1) clear_screen() - return else: print(Fore.RED + invalid_input + Style.RESET_ALL) time.sleep(2) clear_screen() - print_animal_table(animals) - - + print_animal_table(animals) # Function to view animals and interact with options def view_animals(): animals = load_animal_data(animals_collection) - current_user = sudo_user() + current_user = SudoUserLevel1(users_collection.database).login() # Load animal data print_animal_table(animals) @@ -305,7 +301,8 @@ def view_animals(): elif user_input == '4' and current_user['level'] >= 2: modify_database(current_user) elif user_input == '5' and current_user['level'] >= 2: - exit_database(current_user) + if exit_database(current_user): + break else: handle_invalid_input(animals) @@ -379,7 +376,8 @@ def exit_database(current_user): print("\nExiting...") time.sleep(2) clear_screen() - + return True + # Handle invalid input def handle_invalid_input(animals): print(Fore.RED + invalid_input + Style.RESET_ALL)