Beginning adding OTP verification to client shange screen
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -112,7 +112,7 @@ paths:
|
|||||||
'404':
|
'404':
|
||||||
description: client_id not found
|
description: client_id not found
|
||||||
/OTP/Generate:
|
/OTP/Generate:
|
||||||
get:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- auth
|
- auth
|
||||||
summary: Generate OTP
|
summary: Generate OTP
|
||||||
@@ -148,6 +148,13 @@ paths:
|
|||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
- name: otp_code
|
||||||
|
in: query
|
||||||
|
description: OTP to verify
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
- name: name
|
- name: name
|
||||||
in: query
|
in: query
|
||||||
description: Client Name
|
description: Client Name
|
||||||
@@ -187,8 +194,12 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Successful operation
|
description: Successful operation
|
||||||
'400':
|
'404':
|
||||||
description: Invalid Client ID supplied
|
description: Invalid Client ID supplied
|
||||||
|
'403':
|
||||||
|
description: Unauthorised
|
||||||
|
'405':
|
||||||
|
description: OTP not valid
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- client
|
- client
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -53,12 +53,12 @@ def get_client(client_id):
|
|||||||
print(f"RequestException: {e}")
|
print(f"RequestException: {e}")
|
||||||
return {'success': False, 'message': "Could not connect to the server. Please try again later."}
|
return {'success': False, 'message': "Could not connect to the server. Please try again later."}
|
||||||
|
|
||||||
def update_client(client_id, email=None, phone_number=None, address=None):
|
def update_client(client_id, otp_code, email=None, phone_number=None, address=None):
|
||||||
"""Updates the client details for the given client_id."""
|
"""Updates the client details for the given client_id."""
|
||||||
try:
|
try:
|
||||||
with open('application\\session_data.json', 'r') as f:
|
with open('application\\session_data.json', 'r') as f:
|
||||||
session_data = json.load(f)
|
session_data = json.load(f)
|
||||||
params = {'client_id': client_id}
|
params = {'client_id': client_id, 'otp_code': otp_code}
|
||||||
if email is not None:
|
if email is not None:
|
||||||
params['email'] = email
|
params['email'] = email
|
||||||
if phone_number is not None:
|
if phone_number is not None:
|
||||||
@@ -147,3 +147,16 @@ def new_transaction(account):
|
|||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
print(f"RequestException: {e}")
|
print(f"RequestException: {e}")
|
||||||
return {'success': False, 'message': "Could not connect to the server. Please try again later."}
|
return {'success': False, 'message': "Could not connect to the server. Please try again later."}
|
||||||
|
|
||||||
|
def generate_otp():
|
||||||
|
"""Generates a new OTP for the current client, which is sent by Email."""
|
||||||
|
try:
|
||||||
|
with open('application\\session_data.json', 'r') as f:
|
||||||
|
session_data = json.load(f)
|
||||||
|
client_id = session_data['client_id']
|
||||||
|
response = requests.post(CONFIG["server"]["url"] + "/OTP/Generate", cookies=session_data['session_cookie'], params={'client_id': client_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."}
|
||||||
+34
-20
@@ -3,12 +3,13 @@ import customtkinter
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from config import CONFIG
|
from config import CONFIG
|
||||||
from connection import logout_client, get_client, update_client, get_accounts, format_balance
|
from connection import logout_client, get_client, update_client, get_accounts, format_balance, generate_otp
|
||||||
|
|
||||||
# Global variables
|
# Global variables
|
||||||
email_entry = None
|
email_entry = None
|
||||||
phone_entry = None
|
phone_entry = None
|
||||||
address_entry = None
|
address_entry = None
|
||||||
|
otp_entry = None
|
||||||
frame = None
|
frame = None
|
||||||
|
|
||||||
#################
|
#################
|
||||||
@@ -66,10 +67,11 @@ def display_client_info():
|
|||||||
|
|
||||||
def edit_details():
|
def edit_details():
|
||||||
"""Opens a new window for editing client details."""
|
"""Opens a new window for editing client details."""
|
||||||
global edit_window, email_entry, phone_entry, address_entry
|
global edit_window, email_entry, phone_entry, address_entry, otp_entry
|
||||||
edit_window = customtkinter.CTkToplevel(root)
|
edit_window = customtkinter.CTkToplevel(root)
|
||||||
edit_window.title("Edit Details")
|
edit_window.title("Edit Details")
|
||||||
edit_window.geometry("300x200")
|
edit_window.geometry("300x300")
|
||||||
|
edit_window.iconbitmap("application/luxbank.ico")
|
||||||
edit_window.attributes('-topmost', True)
|
edit_window.attributes('-topmost', True)
|
||||||
|
|
||||||
email_label = customtkinter.CTkLabel(edit_window, text="Email: ")
|
email_label = customtkinter.CTkLabel(edit_window, text="Email: ")
|
||||||
@@ -87,31 +89,38 @@ def edit_details():
|
|||||||
address_label.pack()
|
address_label.pack()
|
||||||
address_entry.pack()
|
address_entry.pack()
|
||||||
|
|
||||||
save_button = customtkinter.CTkButton(edit_window, text="Save", command=save_details)
|
# Add MFA verify button and text box
|
||||||
|
mfa_button = customtkinter.CTkButton(edit_window, text="Get OTP Code", command=generate_otp)
|
||||||
|
mfa_button.pack()
|
||||||
|
|
||||||
|
mfa_label = customtkinter.CTkLabel(edit_window, text="OTP Code: ")
|
||||||
|
otp_entry = customtkinter.CTkEntry(edit_window)
|
||||||
|
mfa_label.pack()
|
||||||
|
otp_entry.pack()
|
||||||
|
|
||||||
|
save_button = customtkinter.CTkButton(edit_window, text="Verify MFA and Save", command=save_details)
|
||||||
save_button.pack()
|
save_button.pack()
|
||||||
edit_window.lift()
|
edit_window.lift()
|
||||||
|
|
||||||
def save_details():
|
def save_details():
|
||||||
"""Saves the updated client details."""
|
"""Saves the updated client details."""
|
||||||
global edit_window, email_entry, phone_entry, address_entry
|
global edit_window, otp_entry, email_entry, phone_entry, address_entry
|
||||||
new_email = email_entry.get() if email_entry.get() != '' else None
|
new_email = email_entry.get() if email_entry.get() != '' else None
|
||||||
new_phone = phone_entry.get() if phone_entry.get() != '' else None
|
new_phone = phone_entry.get() if phone_entry.get() != '' else None
|
||||||
new_address = address_entry.get() if address_entry.get() != '' else None
|
new_address = address_entry.get() if address_entry.get() != '' else None
|
||||||
try:
|
otp_code = otp_entry.get()
|
||||||
with open('application\\session_data.json', 'r') as f:
|
with open('application\\session_data.json', 'r') as f:
|
||||||
session_data = json.load(f)
|
session_data = json.load(f)
|
||||||
client_id = session_data['client_id']
|
client_id = session_data['client_id']
|
||||||
if not messagebox.askyesno("Confirmation", "Are you sure you want to update the details?"):
|
if not messagebox.askyesno("Confirmation", "Are you sure you want to update the details?"):
|
||||||
return
|
return
|
||||||
result = update_client(client_id, new_email, new_phone, new_address)
|
result = update_client(client_id, otp_code, new_email, new_phone, new_address)
|
||||||
if result['success']:
|
if result['success']:
|
||||||
display_client_info()
|
display_client_info()
|
||||||
else:
|
else:
|
||||||
messagebox.showerror("Update Failed", result.get('message', 'Unknown error'))
|
messagebox.showerror("Update Failed", result.get('message', 'Unknown error'))
|
||||||
edit_window.destroy()
|
edit_window.destroy()
|
||||||
except Exception as e:
|
|
||||||
messagebox.showerror("Error", f"Could not update details: {e}")
|
|
||||||
|
|
||||||
def populate_table():
|
def populate_table():
|
||||||
"""Populates the accounts table with client accounts."""
|
"""Populates the accounts table with client accounts."""
|
||||||
try:
|
try:
|
||||||
@@ -160,9 +169,14 @@ welcome_label.pack(pady=20)
|
|||||||
|
|
||||||
display_client_info()
|
display_client_info()
|
||||||
|
|
||||||
|
# Create a logout button
|
||||||
logout_button = customtkinter.CTkButton(root, text="Logout", command=logout)
|
logout_button = customtkinter.CTkButton(root, text="Logout", command=logout)
|
||||||
logout_button.pack(pady=15)
|
logout_button.pack(pady=15)
|
||||||
|
|
||||||
|
# Create the MFA button
|
||||||
|
mfa_button = customtkinter.CTkButton(root, text="MFA", command=generate_otp)
|
||||||
|
mfa_button.pack(pady=15, side='left')
|
||||||
|
|
||||||
# Create a frame for the table
|
# Create a frame for the table
|
||||||
table_frame = ttk.Frame(root)
|
table_frame = ttk.Frame(root)
|
||||||
table_frame.pack(side='right', fill='both', expand=True)
|
table_frame.pack(side='right', fill='both', expand=True)
|
||||||
|
|||||||
@@ -53,10 +53,13 @@ def change_dark_theme():
|
|||||||
##############
|
##############
|
||||||
|
|
||||||
# Set appearance mode based on configuration
|
# Set appearance mode based on configuration
|
||||||
if CONFIG["preferences"]["dark_theme"] == "dark":
|
if "preferences" in CONFIG and "dark_theme" in CONFIG["preferences"]:
|
||||||
customtkinter.set_appearance_mode("dark")
|
if CONFIG["preferences"]["dark_theme"] == "dark":
|
||||||
|
customtkinter.set_appearance_mode("dark")
|
||||||
|
else:
|
||||||
|
customtkinter.set_appearance_mode("light")
|
||||||
else:
|
else:
|
||||||
customtkinter.set_appearance_mode("light")
|
customtkinter.set_appearance_mode("dark")
|
||||||
|
|
||||||
# Initialize the main window
|
# Initialize the main window
|
||||||
root = customtkinter.CTk()
|
root = customtkinter.CTk()
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"session_cookie": {"session": "UHtXXDwzE9iVXmMpFHD9BYA-ztYORiBP-xfRImGQDJQ"}, "client_id": "31d90aad"}
|
{"session_cookie": {"session": "mMTYW-c_n0BE-l7MENT8A1h2Rg4UUrNRJYl7NvXTcS4"}, "client_id": "31d90aad"}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3
-1
@@ -162,9 +162,11 @@ def get_client(client_id:str):
|
|||||||
return format_response(False, "Client not found."), 404
|
return format_response(False, "Client not found."), 404
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def update_client(client_id:str, **kwargs):
|
def update_client(client_id:str, otp_code:int, **kwargs):
|
||||||
"""Updates a client in the database. If the client is not found, returns an error message."""
|
"""Updates a client in the database. If the client is not found, returns an error message."""
|
||||||
current_client_id, is_admin = get_current_client()
|
current_client_id, is_admin = get_current_client()
|
||||||
|
if not verify_otp(current_client_id, otp_code):
|
||||||
|
return format_response(False, "Invalid OTP."), 405
|
||||||
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
|
||||||
for client in session.query(Client).all():
|
for client in session.query(Client).all():
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user