add logging

This commit is contained in:
Lucas Mathews
2024-05-29 21:40:45 +02:00
parent 53f5eb49e2
commit c2812aa2c4
7 changed files with 38 additions and 26 deletions

1
.gitignore vendored
View File

@@ -3,6 +3,7 @@ application/__pycache__/
application/session_data.json
bank.db
test_database.db
log.txt
# Byte-compiled / optimized / DLL files
__pycache__/

View File

@@ -8,6 +8,6 @@ dark_theme = dark
theme = dark-blue
[client]
default_id = d18e5ae0
default_password = KFCKrusher1
default_id = 9ce7d233
default_password = Happymeal1

View File

@@ -1 +1 @@
{"session_cookie": {"session": "fhCFtlJIX2pSU0z4Cn4yMBZpKa4WAEBGJLu00aGXOtc"}, "client_id": "d18e5ae0"}
{"session_cookie": {"session": "m4rjEuzC595awmTv39qVOhjiiQYDcq3PT7ObB1_S6Bs"}, "client_id": "9ce7d233"}

View File

@@ -1,3 +1,6 @@
# Lucas Mathews - Fontys Student ID: 5023572
# Banking System Manager File
import smtplib
import ssl
from email.mime.text import MIMEText
@@ -30,10 +33,12 @@ def send_email(receiver_email, subject, body):
with smtplib.SMTP_SSL(CONFIG["smtp"]["host"], CONFIG["smtp"]["port"], context=context) as server:
server.login(CONFIG["smtp"]["username"], CONFIG["smtp"]["password"])
server.sendmail(sender_email, receiver_email, text)
print(f"Email sent to {receiver_email}.")
from manager import log_event
log_event(f"Email '{subject}' sent to {receiver_email}") # Log the message
except Exception as e:
error_message = f"Failed to send email to {receiver_email}: {e}"
print(error_message)
from manager import log_event
log_event(error_message) # Log the error
raise EmailSendingError(error_message)

View File

@@ -86,6 +86,12 @@ def check_expired_otps():
for client_id in expired_otps:
delete_otp(client_id)
def log_event(data_to_log:str):
"""Logs an event to the log file."""
with open("log.txt", "a") as log_file:
log_file.write(f"{timestamp()} - {data_to_log}\n")
######################
### Authentication ###
######################
@@ -95,10 +101,10 @@ def login():
data = request.get_json()
client_id = data.get('client_id')
client_hash = data.get('client_hash')
client = session.query(Client).filter_by(client_id=client_id).first()
if client and client.hash == client_hash:
flask_session['client_id'] = client_id
log_event(f"{client_id} logged in successfully.")
return format_response(True, f"{flask_session['client_id']} logged in successfully."), 200
return format_response(False, "Invalid client_id or password."), 401
@@ -188,7 +194,6 @@ def update_client(client_id:str, otp_code:int, **kwargs):
return format_response(False, "Invalid OTP."), 400 # Changed to 400 Bad Request
if not is_admin and client_id != current_client_id:
return format_response(False, "You can only view your own client information."), 403
client = session.query(Client).filter_by(client_id=client_id).first()
if client:
for field in ['name', 'birthdate', 'address', 'phone_number', 'email', 'notes']:
@@ -196,7 +201,6 @@ def update_client(client_id:str, otp_code:int, **kwargs):
setattr(client, field, kwargs[field])
session.commit()
return format_response(True, f"Client ID: {client_id} has been updated."), 200
return format_response(False, "Client not found."), 404
@@ -208,37 +212,27 @@ def change_password():
hash_new_password = data.get('hash_new_password')
otp_code = data.get('otp_code')
current_client_id, is_admin = get_current_client()
# Verify if the OTP is correct
otp_verified = verify_otp(client_id, otp_code)
# Check if the client is authorized to change the password
if not is_admin and client_id != current_client_id:
otp_verified = verify_otp(client_id, otp_code) # Verify if the OTP is correct
if not is_admin and client_id != current_client_id: # Check if the client is authorized to change the password
return format_response(False, "You can only update your own client information."), 401
# Recheck OTP verification after authorisation check
if not otp_verified:
if not otp_verified: # Recheck OTP verification after authorisation check
return format_response(False, "Invalid OTP."), 400
# Validate new password format
hash_format = r'^[0-9a-f]{128}$'
hash_format = r'^[0-9a-f]{128}$' # Validate new password format
if not re.match(hash_format, hash_new_password):
return format_response(False, "Invalid new password format (must be provided as a hash)."), 400
# Check if the old password hash matches and update to the new password hash
client = session.query(Client).filter_by(client_id=client_id).first()
client = session.query(Client).filter_by(client_id=client_id).first() # Check if the old password hash matches and update to the new password hash
if client:
if client.hash == hash_old_password:
client.hash = hash_new_password
session.commit()
delete_otp(client_id)
return format_response(True, f"Password for client_id: {client_id} has been updated."), 200
log_event(f"Password for client_id {client_id} has been updated by {current_client_id}.")
return format_response(True, f"Password for client_id {client_id} has been updated."), 200
else:
return format_response(False, "Invalid old password."), 400
else:
return format_response(False, "Client not found."), 404
@login_required
def get_accounts(client_id: str):
"""Returns all accounts for a specific client in the database. If the client is not found, returns an error message."""
@@ -396,6 +390,7 @@ def delete_account(account_id:str):
if account.balance == 0:
session.delete(account)
session.commit()
log_event(f"Account ID: {account_id} has been removed by {flask_session['client_id']}.")
return format_response(True, f"account_id: {account_id} has been removed."), 200
else:
return format_response(False, "Account has a balance and can not be removed."), 400
@@ -405,18 +400,21 @@ def delete_account(account_id:str):
def get_all_clients():
"""Returns all clients in the database."""
clients = session.query(Client).all()
log_event(f"All clients have been retrieved by {flask_session['client_id']}.")
return format_response(True, "", [client.to_dict() for client in clients]), 200
@admin_required
def get_all_accounts():
"""Returns all accounts in the database."""
accounts = session.query(Account).all()
log_event(f"All accounts have been retrieved by {flask_session['client_id']}.")
return format_response(True, "", [account.to_dict() for account in accounts]), 200
@admin_required
def get_all_transactions():
"""Returns all transactions in the database."""
transactions = session.query(Transaction).all()
log_event(f"All transactions have been retrieved by {flask_session['client_id']}.")
return format_response(True, "", [transaction.to_dict() for transaction in transactions]), 200
@admin_required
@@ -427,6 +425,7 @@ def apply_interest(account_id:int, interest_rate:float):
interest = account.balance * interest_rate
account.balance += interest
session.commit()
log_event(f"Interest of €{interest} has been applied to Account ID: {account_id} by {flask_session['client_id']}.")
return format_response(True, f"{interest} in interest has been applied to Account ID: {account_id}."), 200
return format_response(False, "Account not found."), 404
@@ -437,6 +436,7 @@ def apply_fee(account_id:int, fee:float):
if account.account_id == account_id:
account.balance -= fee
session.commit()
log_event(f"Fee of €{fee} has been applied to Account ID: {account_id} by {flask_session['client_id']}.")
return format_response(True, f"{fee} in fees has been applied to Account ID: {account_id}."), 200
return format_response(False, "Account not found."), 404
@@ -447,6 +447,7 @@ def delete_transaction(transaction_id:int):
if transaction.transaction_id == transaction_id:
session.delete(transaction)
session.commit()
log_event(f"Transaction ID: {transaction_id} has been removed by {flask_session['client_id']}.")
return format_response(True, f"Transaction ID: {transaction_id} has been removed."), 200
return format_response(False, "Transaction not found."), 404
@@ -457,6 +458,7 @@ def modify_balance(transaction_id:int, amount:int):
if transaction.transaction_id == transaction_id:
transaction.amount = amount
session.commit()
log_event(f"Transaction ID: {transaction_id} has been modified by {flask_session['client_id']}.")
return format_response(True, f"Transaction ID: {transaction_id} has been modified."), 200
return format_response(False, "Transaction not found."), 404
@@ -498,6 +500,7 @@ def initialise_database(password:str, email:str):
admin_client = session.query(Client).filter_by(name='ADMINISTRATOR').one() # Retrieve the administrator client
admin_client.administrator = 1 # Set the new client as an administrator
session.commit()
log_event(f"Database initialised with administrator account with client_id {admin_client.client_id}.")
return format_response(True, f"Database initialised with administrator account with client_id {admin_client.client_id}"), 200
return format_response(False, "Database not empty."), 400
@@ -508,6 +511,7 @@ def promote_to_admin(client_id:str):
if client.client_id == client_id:
client.administrator = 1
session.commit()
log_event(f"Client ID: {client_id} has been promoted to administrator by {flask_session['client_id']}.")
return format_response(True, f"client_id: {client_id} has been promoted to administrator."), 200
return format_response(False, f"client_id: {client_id} is not found."), 404
@@ -518,6 +522,7 @@ def demote_from_admin(client_id:str):
if client.client_id == client_id:
client.administrator = 0
session.commit()
log_event(f"Client ID: {client_id} has been demoted from administrator by {flask_session['client_id']}.")
return format_response(True, f"client_id: {client_id} has been demoted from administrator."), 200
return format_response(False, f"client_id: {client_id} is not found."), 404

Binary file not shown.

View File

@@ -119,6 +119,7 @@ session.commit()
admin_client_id = session.query(Client.client_id).filter(Client.administrator == 1).first()[0]
# Print the client_id of the administrator account
print(f"The client_id of the administrator account of this test database is: {admin_client_id}. The password is: Happymeal1")
print(f"The client_id of the administrator account of this test database is: {admin_client_id}")
print("The password is: Happymeal1")
session.close()