add logging
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@ application/__pycache__/
|
|||||||
application/session_data.json
|
application/session_data.json
|
||||||
bank.db
|
bank.db
|
||||||
test_database.db
|
test_database.db
|
||||||
|
log.txt
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ dark_theme = dark
|
|||||||
theme = dark-blue
|
theme = dark-blue
|
||||||
|
|
||||||
[client]
|
[client]
|
||||||
default_id = d18e5ae0
|
default_id = 9ce7d233
|
||||||
default_password = KFCKrusher1
|
default_password = Happymeal1
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"session_cookie": {"session": "fhCFtlJIX2pSU0z4Cn4yMBZpKa4WAEBGJLu00aGXOtc"}, "client_id": "d18e5ae0"}
|
{"session_cookie": {"session": "m4rjEuzC595awmTv39qVOhjiiQYDcq3PT7ObB1_S6Bs"}, "client_id": "9ce7d233"}
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# Lucas Mathews - Fontys Student ID: 5023572
|
||||||
|
# Banking System Manager File
|
||||||
|
|
||||||
import smtplib
|
import smtplib
|
||||||
import ssl
|
import ssl
|
||||||
from email.mime.text import MIMEText
|
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:
|
with smtplib.SMTP_SSL(CONFIG["smtp"]["host"], CONFIG["smtp"]["port"], context=context) as server:
|
||||||
server.login(CONFIG["smtp"]["username"], CONFIG["smtp"]["password"])
|
server.login(CONFIG["smtp"]["username"], CONFIG["smtp"]["password"])
|
||||||
server.sendmail(sender_email, receiver_email, text)
|
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:
|
except Exception as e:
|
||||||
error_message = f"Failed to send email to {receiver_email}: {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)
|
raise EmailSendingError(error_message)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
45
manager.py
45
manager.py
@@ -86,6 +86,12 @@ def check_expired_otps():
|
|||||||
for client_id in expired_otps:
|
for client_id in expired_otps:
|
||||||
delete_otp(client_id)
|
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 ###
|
### Authentication ###
|
||||||
######################
|
######################
|
||||||
@@ -95,10 +101,10 @@ def login():
|
|||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
client_id = data.get('client_id')
|
client_id = data.get('client_id')
|
||||||
client_hash = data.get('client_hash')
|
client_hash = data.get('client_hash')
|
||||||
|
|
||||||
client = session.query(Client).filter_by(client_id=client_id).first()
|
client = session.query(Client).filter_by(client_id=client_id).first()
|
||||||
if client and client.hash == client_hash:
|
if client and client.hash == client_hash:
|
||||||
flask_session['client_id'] = client_id
|
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(True, f"{flask_session['client_id']} logged in successfully."), 200
|
||||||
return format_response(False, "Invalid client_id or password."), 401
|
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
|
return format_response(False, "Invalid OTP."), 400 # Changed to 400 Bad Request
|
||||||
if not is_admin and client_id != current_client_id:
|
if not is_admin and client_id != current_client_id:
|
||||||
return format_response(False, "You can only view your own client information."), 403
|
return format_response(False, "You can only view your own client information."), 403
|
||||||
|
|
||||||
client = session.query(Client).filter_by(client_id=client_id).first()
|
client = session.query(Client).filter_by(client_id=client_id).first()
|
||||||
if client:
|
if client:
|
||||||
for field in ['name', 'birthdate', 'address', 'phone_number', 'email', 'notes']:
|
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])
|
setattr(client, field, kwargs[field])
|
||||||
session.commit()
|
session.commit()
|
||||||
return format_response(True, f"Client ID: {client_id} has been updated."), 200
|
return format_response(True, f"Client ID: {client_id} has been updated."), 200
|
||||||
|
|
||||||
return format_response(False, "Client not found."), 404
|
return format_response(False, "Client not found."), 404
|
||||||
|
|
||||||
|
|
||||||
@@ -208,37 +212,27 @@ def change_password():
|
|||||||
hash_new_password = data.get('hash_new_password')
|
hash_new_password = data.get('hash_new_password')
|
||||||
otp_code = data.get('otp_code')
|
otp_code = data.get('otp_code')
|
||||||
current_client_id, is_admin = get_current_client()
|
current_client_id, is_admin = get_current_client()
|
||||||
|
otp_verified = verify_otp(client_id, otp_code) # Verify if the OTP is correct
|
||||||
# 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
|
||||||
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:
|
|
||||||
return format_response(False, "You can only update your own client information."), 401
|
return format_response(False, "You can only update your own client information."), 401
|
||||||
|
if not otp_verified: # Recheck OTP verification after authorisation check
|
||||||
# Recheck OTP verification after authorisation check
|
|
||||||
if not otp_verified:
|
|
||||||
return format_response(False, "Invalid OTP."), 400
|
return format_response(False, "Invalid OTP."), 400
|
||||||
|
hash_format = r'^[0-9a-f]{128}$' # Validate new password format
|
||||||
# Validate new password format
|
|
||||||
hash_format = r'^[0-9a-f]{128}$'
|
|
||||||
if not re.match(hash_format, hash_new_password):
|
if not re.match(hash_format, hash_new_password):
|
||||||
return format_response(False, "Invalid new password format (must be provided as a hash)."), 400
|
return format_response(False, "Invalid new password format (must be provided as a hash)."), 400
|
||||||
|
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
|
||||||
# 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()
|
|
||||||
if client:
|
if client:
|
||||||
if client.hash == hash_old_password:
|
if client.hash == hash_old_password:
|
||||||
client.hash = hash_new_password
|
client.hash = hash_new_password
|
||||||
session.commit()
|
session.commit()
|
||||||
delete_otp(client_id)
|
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:
|
else:
|
||||||
return format_response(False, "Invalid old password."), 400
|
return format_response(False, "Invalid old password."), 400
|
||||||
else:
|
else:
|
||||||
return format_response(False, "Client not found."), 404
|
return format_response(False, "Client not found."), 404
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def get_accounts(client_id: str):
|
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."""
|
"""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:
|
if account.balance == 0:
|
||||||
session.delete(account)
|
session.delete(account)
|
||||||
session.commit()
|
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
|
return format_response(True, f"account_id: {account_id} has been removed."), 200
|
||||||
else:
|
else:
|
||||||
return format_response(False, "Account has a balance and can not be removed."), 400
|
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():
|
def get_all_clients():
|
||||||
"""Returns all clients in the database."""
|
"""Returns all clients in the database."""
|
||||||
clients = session.query(Client).all()
|
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
|
return format_response(True, "", [client.to_dict() for client in clients]), 200
|
||||||
|
|
||||||
@admin_required
|
@admin_required
|
||||||
def get_all_accounts():
|
def get_all_accounts():
|
||||||
"""Returns all accounts in the database."""
|
"""Returns all accounts in the database."""
|
||||||
accounts = session.query(Account).all()
|
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
|
return format_response(True, "", [account.to_dict() for account in accounts]), 200
|
||||||
|
|
||||||
@admin_required
|
@admin_required
|
||||||
def get_all_transactions():
|
def get_all_transactions():
|
||||||
"""Returns all transactions in the database."""
|
"""Returns all transactions in the database."""
|
||||||
transactions = session.query(Transaction).all()
|
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
|
return format_response(True, "", [transaction.to_dict() for transaction in transactions]), 200
|
||||||
|
|
||||||
@admin_required
|
@admin_required
|
||||||
@@ -427,6 +425,7 @@ def apply_interest(account_id:int, interest_rate:float):
|
|||||||
interest = account.balance * interest_rate
|
interest = account.balance * interest_rate
|
||||||
account.balance += interest
|
account.balance += interest
|
||||||
session.commit()
|
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(True, f"€{interest} in interest has been applied to Account ID: {account_id}."), 200
|
||||||
return format_response(False, "Account not found."), 404
|
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:
|
if account.account_id == account_id:
|
||||||
account.balance -= fee
|
account.balance -= fee
|
||||||
session.commit()
|
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(True, f"€{fee} in fees has been applied to Account ID: {account_id}."), 200
|
||||||
return format_response(False, "Account not found."), 404
|
return format_response(False, "Account not found."), 404
|
||||||
|
|
||||||
@@ -447,6 +447,7 @@ def delete_transaction(transaction_id:int):
|
|||||||
if transaction.transaction_id == transaction_id:
|
if transaction.transaction_id == transaction_id:
|
||||||
session.delete(transaction)
|
session.delete(transaction)
|
||||||
session.commit()
|
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(True, f"Transaction ID: {transaction_id} has been removed."), 200
|
||||||
return format_response(False, "Transaction not found."), 404
|
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:
|
if transaction.transaction_id == transaction_id:
|
||||||
transaction.amount = amount
|
transaction.amount = amount
|
||||||
session.commit()
|
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(True, f"Transaction ID: {transaction_id} has been modified."), 200
|
||||||
return format_response(False, "Transaction not found."), 404
|
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 = session.query(Client).filter_by(name='ADMINISTRATOR').one() # Retrieve the administrator client
|
||||||
admin_client.administrator = 1 # Set the new client as an administrator
|
admin_client.administrator = 1 # Set the new client as an administrator
|
||||||
session.commit()
|
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(True, f"Database initialised with administrator account with client_id {admin_client.client_id}"), 200
|
||||||
return format_response(False, "Database not empty."), 400
|
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:
|
if client.client_id == client_id:
|
||||||
client.administrator = 1
|
client.administrator = 1
|
||||||
session.commit()
|
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(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
|
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:
|
if client.client_id == client_id:
|
||||||
client.administrator = 0
|
client.administrator = 0
|
||||||
session.commit()
|
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(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
|
return format_response(False, f"client_id: {client_id} is not found."), 404
|
||||||
|
|
||||||
|
|||||||
BIN
test_database.db
BIN
test_database.db
Binary file not shown.
@@ -119,6 +119,7 @@ session.commit()
|
|||||||
admin_client_id = session.query(Client.client_id).filter(Client.administrator == 1).first()[0]
|
admin_client_id = session.query(Client.client_id).filter(Client.administrator == 1).first()[0]
|
||||||
|
|
||||||
# Print the client_id of the administrator account
|
# 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()
|
session.close()
|
||||||
Reference in New Issue
Block a user