diff --git a/cli/cli.ini b/cli/cli.ini index 56e8070..c9dfe03 100644 --- a/cli/cli.ini +++ b/cli/cli.ini @@ -4,5 +4,5 @@ port = 8066 url = http://127.0.0.1:8066 [client] -default_id = a9fa4899 +default_id = 4f0b6dce default_password = Happymeal1 \ No newline at end of file diff --git a/cli/cli.py b/cli/cli.py index 6b4e0b4..17ebb7f 100644 --- a/cli/cli.py +++ b/cli/cli.py @@ -6,16 +6,20 @@ import argparse import sys from config import CONFIG from getpass import getpass -from connection import login, logout, get_client +from connection import login, logout, get_client, add_client from test_database_generator import generate_test_database def show_menu(): print("\nAvailable options:") - print("1. Logout") - print("2. New user") - print("3. Add test users") - print("4. Exit") + print("1. Logout and exit") + print("2. New client") + print("3. Add test data to database (50 clients, 2 accounts each, 40 transactions each)") + print("4. Initialise Database") + #print("5. Promote to Admin") + #print("6. Demote from Admin") + #print("7. Delete user")S + print("\n") def main(): parser = argparse.ArgumentParser(description='Banking System CLI Utility') @@ -37,7 +41,6 @@ def main(): args.password = getpass("Enter password: ") response = login(args.username, args.password) - print(response) if response['success']: print(f"Login successful: {response['message']}") try: @@ -55,7 +58,7 @@ def main(): while True: show_menu() option = input("Choose an option: ") - if option == "1": + if option == "1": # Menu option 1 - Logout and exit response = logout() json_response = response.json() if json_response['success']: @@ -64,15 +67,33 @@ def main(): print(f"Logout failed: {json_response['message']}") args.username = None args.password = None - elif option == "2": + + elif option == "2": # Menu option 2 - New client print("New user option selected.") - # Implement new user functionality here - elif option == "3": + name = input("Enter name: ") + birthdate = input("Enter birthdate (YYYY-MM-DD): ") + address = input("Enter address: ") + phone_number = input("Enter phone number: ") + email = input("Enter email: ") + password = input("Enter password: ") + notes = input("Enter notes: ") + response = add_client(name, birthdate, address, phone_number, email, password, notes) + + elif option == "3": # Menu option 3 - Add test data to database print("Add test users option selected.") generate_test_database(args.username, args.password) - elif option == "4": - print("Exiting...") + elif option == "4": # Menu option 4 - Initialise Database + print("Not implemented yet, exiting...") + break + elif option == "5": # Menu option 5 - Promote to Admin + print("Not implemented yet, exiting...") + break + elif option == "6": # Menu option 6 - Demote from Admin + print("Not implemented yet, exiting...") + break + elif option == "7": # Menu option 7 - Delete user + print("Not implemented yet, exiting...") break else: print("Invalid option. Please try again.") diff --git a/cli/connection.py b/cli/connection.py index ac35478..6437ee2 100644 --- a/cli/connection.py +++ b/cli/connection.py @@ -68,8 +68,32 @@ def get_client(client_id): print(f"RequestException: {e}") return {'success': False, 'message': "Could not connect to the server. Please try again later."} +def get_account(account_id): + """Retrieves the account details for the current client.""" + try: + with open('session_data.json', 'r') as f: + session_data = json.load(f) + response = requests.get(CONFIG["server"]["url"] + "/Account", cookies=session_data['session_cookie'], params={'account_id': account_id}) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + print(f"RequestException: {e}") + return {'success': False, 'message': "Could not connect to the server. Please try again later."} + +def get_transaction(transaction_id): + """Retrieves the transaction details for the given transaction_id.""" + try: + with open('session_data.json', 'r') as f: + session_data = json.load(f) + response = requests.get(CONFIG["server"]["url"] + "/Transaction", cookies=session_data['session_cookie'], params={'transaction_id': transaction_id}) + response.raise_for_status() + return response.json() + except requests.exceptions.RequestException as e: + print(f"RequestException: {e}") + return {'success': False, 'message': "Could not connect to the server. Please try again later."} + def add_client(name, birthdate, address, phone_number, email, password, notes): - data = { + params = { "name": name, "birthdate": birthdate, "address": address, @@ -81,13 +105,53 @@ def add_client(name, birthdate, address, phone_number, email, password, notes): try: with open('session_data.json', 'r') as f: session_data = json.load(f) - response = requests.get(CONFIG["server"]["url"] + "/Client", cookies=session_data['session_cookie'], params=data) - response.raise_for_status() + response = requests.post(CONFIG["server"]["url"] + "/Admin/Client", cookies=session_data['session_cookie'], params=params) if response.status_code == 200: - print("Client retrieved successfully.") + return response.json() else: - print(f"Failed to retrieve client. Status code: {response.status_code}, message: {response.text}") + print(f"Failed to create client. Status code: {response.status_code}, message: {response.text}") except requests.exceptions.RequestException as e: print(f"RequestException: {e}") return {'success': False, 'message': "Could not connect to the server. Please try again later."} - \ No newline at end of file + +def add_account(client_id, description, account_type, notes): + """Adds an account with the given client_id, description, account_type, and notes.""" + params = { + "client_id": client_id, + "description": description, + "account_type": account_type, + "notes": notes + } + try: + with open('session_data.json', 'r') as f: + session_data = json.load(f) + response = requests.post(CONFIG["server"]["url"] + "/Account", cookies=session_data['session_cookie'], params=params) + response.raise_for_status() + if response.status_code == 200: + return response.json() + else: + print(f"Failed to create account. Status code: {response.status_code}, message: {response.text}") + except requests.exceptions.RequestException as e: + print(f"RequestException: {e}") + return {'success': False, 'message': "Could not connect to the server. Please try again later."} + +def add_transaction(amount, account_id, recipient_account_id, otp_code, description): + """Adds a transaction with the given amount, recipient_account_id, otp_code, and description.""" + params = { + "amount": amount, + "account_id": account_id, + "recipient_account_id": recipient_account_id, + "otp_code": otp_code, + "description": description} + try: + with open('session_data.json', 'r') as f: + session_data = json.load(f) + response = requests.post(CONFIG["server"]["url"] + "/Transaction", cookies=session_data['session_cookie'], params=params) + response.raise_for_status() + if response.status_code == 200: + print("Transaction created successfully.") + else: + print(f"Failed to create transaction. Status code: {response.status_code}, message: {response.text}") + except requests.exceptions.RequestException as e: + print(f"RequestException: {e}") + return {'success': False, 'message': "Could not connect to the server. Please try again later."} \ No newline at end of file diff --git a/cli/test_database_generator.py b/cli/test_database_generator.py index d115996..acf3382 100644 --- a/cli/test_database_generator.py +++ b/cli/test_database_generator.py @@ -1,21 +1,15 @@ # Lucas Mathews - Fontys Student ID: 5023572 # Banking System Test Database Generator -# This program generates a test database for the banking system. The database contains 50 clients, each with 2 accounts. Each account has 40 transactions. -# The first client is an administrator. The password for the administrator account is "Happymeal1". The program uses the Faker library to generate fake -# data for the clients, accounts, and transactions. The random library is used to generate random data for the accounts and transactions. The program -# creates a new SQLite database called test_database.db and writes the test data to the database. The client ID of the administrator account and the -# password for the administrator account. +# This program generates dumy data for the banking system. +# This adds 50 clients, each with 2 accounts. Each account has 40 transactions. from faker import Faker -from connection import login, add_client, logout +from connection import add_client, add_account, add_transaction import random import datetime import hashlib -import uuid - -ADMIN_EMAIL = "lmath56@hotmail.com" # Email address of the administrator account - +import time def generate_hash(): # Creates a hash for a password seed = str(random.random()).encode('utf-8') @@ -29,71 +23,50 @@ def generate_test_database(client_id, password): all_account_ids = [] # List to store all account IDs - # Log in as the admin using provided username and password - client_hash = hashlib.sha512(password.encode()).hexdigest() - client = login(client_id, client_hash) + for i in range(50): # Generate 50 clients + password = generate_hash() + name = fake.name() + birthdate = fake.date_of_birth(minimum_age=18, maximum_age=90) + address = fake.address() + phone_number = fake.phone_number() + email = fake.email() + notes = fake.text(max_nb_chars=50) - if client is not None: # Check if login was successful - print("Admin logged in successfully") + client_response = add_client(name, birthdate, address, phone_number, email, password, notes) + client_id = client_response['message'] + for j in range(2): # Each client has 2 accounts + balance = 1000 # Initialize balance to 1000 + account_type = random.choice(['Spending', 'Savings']) + account_notes = fake.text(max_nb_chars=50) + + account_response = add_account(client_id=client_id, description=fake.text(max_nb_chars=15), account_type=account_type, notes=account_notes) + + response_dict = account_response + account_id = response_dict['message'] - for i in range(50): # Generate 50 clients - is_administrator = 1 if i == 0 else 0 # Set the first client as an administrator - # Set the password hash for the first account so that the password is "Happymeal1" - password = "Happymeal1" if i == 0 else generate_hash() - name = "ADMIN" if i == 0 else fake.name() - birthdate = "ADMIN" if i == 0 else fake.date_of_birth(minimum_age=18, maximum_age=90) - address = "ADMIN" if i == 0 else fake.address() - phone_number = "ADMIN" if i == 0 else fake.phone_number() - email = ADMIN_EMAIL if i == 0 else fake.email() - notes = fake.text(max_nb_chars=50) - # Add client using add_client function - response = add_client(name, birthdate, address, phone_number, email, password, notes) - print(response) # Print the response message + for k in range(40): # Each account has 40 transactions + if not all_account_ids: # Skip creating a transaction if there are no accounts yet + continue - for j in range(2): # Each client has 2 accounts - balance = 1000 # Initialize balance to 1000 - account_type = random.choice(['Spending', 'Savings']) - account_notes = fake.text(max_nb_chars=50) + transaction_type = random.choice(['Deposit', 'Withdrawal']) + amount = random.randint(1, 200) - # Add account using add_account function - account_response = add_account( - client_id=client_id, - description=fake.text(max_nb_chars=200), - account_type=account_type, - notes=account_notes - ) - print(account_response[1]) # Print the response message + if transaction_type == 'Withdrawal' and balance - amount < 0: # Skip withdrawal if it would make balance negative + continue - for k in range(40): # Each account has 40 transactions - if not all_account_ids: # Skip creating a transaction if there are no accounts yet - continue + if transaction_type == 'Deposit': # Update balance based on transaction type + balance += amount + elif transaction_type == 'Withdrawal': + balance -= amount - transaction_type = random.choice(['Deposit', 'Withdrawal']) - amount = random.randint(1, 200) + transaction_description = fake.text(max_nb_chars=50) + recipient_account_id = random.choice(all_account_ids) + + transaction_response = add_transaction(amount=amount, account_id=account_id, recipient_account_id=recipient_account_id, otp_code=123456, description=transaction_description) + print(f"Transaction response: {transaction_response}") + time.sleep(1) - if transaction_type == 'Withdrawal' and balance - amount < 0: # Skip withdrawal if it would make balance negative - continue + all_account_ids.append(account_id) - if transaction_type == 'Deposit': # Update balance based on transaction type - balance += amount - elif transaction_type == 'Withdrawal': - balance -= amount - - transaction_description = fake.text(max_nb_chars=50) - recipient_account_id = random.choice(all_account_ids) - - # Add transaction using add_transaction function - transaction_response = add_transaction( - amount=amount, - recipient_account_id=recipient_account_id, - otp_code=123456, # Replace with actual OTP verification code - description=transaction_description - ) - print(transaction_response[1]) # Print the response message - - all_account_ids.append(account_id) - logout() # Log out of the admin account - print(f"The client_id of the administrator account of this test database is: {all_account_ids[0]}. The password is: Happymeal1") - else: - print("Admin login failed.") \ No newline at end of file + print("Test database generated successfully.") diff --git a/server/manager.py b/server/manager.py index f6b767d..f0f45d8 100644 --- a/server/manager.py +++ b/server/manager.py @@ -280,7 +280,7 @@ def add_account(client_id:str, description:str, account_type:str, **kwargs): new_account = Account(account_id, client_id, description, timestamp(), account_type, 0, 1, notes, None) # Create the new account session.add(new_account) session.commit() - return format_response(True, f"New account has been added: account_id: {account_id}"), 200 + return format_response(True, account_id), 200 @login_required def update_account(account_id: str, otp_code: str, **kwargs): @@ -345,7 +345,6 @@ def get_transaction(transaction_id:int): @login_required def add_transaction(amount: float, account_id: str, recipient_account_id: str, otp_code: int, description: str): """Adds a new transaction to the database. If the account is not found, returns an error message.""" - print(f"Adding transaction: amount: {amount}, account_id: {account_id}, recipient_account_id: {recipient_account_id}, otp_code: {otp_code}, description: {description}") current_client_id, is_admin = get_current_client() if not is_admin and account_id != current_client_id: return format_response(False, "You can only view your own client information."), 403 @@ -374,7 +373,7 @@ def add_transaction(amount: float, account_id: str, recipient_account_id: str, o session.add(new_transaction) session.commit() - return format_response(True, f"New transaction has been added: transaction_id: {transaction_id}"), 200 + return format_response(True, transaction_id), 200 @login_required def transaction_history(account_id:int): @@ -517,7 +516,7 @@ def add_client(name:str, birthdate:str, address:str, phone_number:str, email:str session.add(new_client) session.commit() event_logger(f"New client has been added: client_id: {client_id} by {flask_session['client_id']}.") - return format_response(True, f"New client has been added: client_id: {client_id}"), 200 + return format_response(True, client_id), 200 def initialise_database(password:str, email:str): """Initialises the database with an administrator client if no clients exist."""