Started dashboard implementation
This commit is contained in:
27
api.yml
27
api.yml
@@ -134,7 +134,7 @@ paths:
|
|||||||
description: OTP not valid
|
description: OTP not valid
|
||||||
'404':
|
'404':
|
||||||
description: client_id not found
|
description: client_id not found
|
||||||
/Client/Client:
|
/Client:
|
||||||
put:
|
put:
|
||||||
tags:
|
tags:
|
||||||
- client
|
- client
|
||||||
@@ -213,6 +213,31 @@ paths:
|
|||||||
description: Invalid Client ID supplied
|
description: Invalid Client ID supplied
|
||||||
'404':
|
'404':
|
||||||
description: Client not found
|
description: Client not found
|
||||||
|
/Client/Accounts:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- client
|
||||||
|
summary: Get all accounts for a client
|
||||||
|
description: Get all accounts for a client
|
||||||
|
operationId: manager.get_accounts
|
||||||
|
parameters:
|
||||||
|
- name: client_id
|
||||||
|
in: query
|
||||||
|
description: ID of client to return accounts for
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Successful operation
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
'400':
|
||||||
|
description: Invalid input
|
||||||
|
'404':
|
||||||
|
description: No accounts found
|
||||||
/Account:
|
/Account:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ port=81
|
|||||||
url=http://127.0.0.1:81
|
url=http://127.0.0.1:81
|
||||||
|
|
||||||
[preferences]
|
[preferences]
|
||||||
dark_theme=system
|
dark_theme=dark
|
||||||
# Modes: system, light, dark
|
# Modes: light, dark
|
||||||
theme=dark-blue
|
theme=dark-blue
|
||||||
# Themes: blue, dark-blue, green
|
# Themes: blue, dark-blue, green
|
||||||
|
|||||||
@@ -9,16 +9,10 @@ import json
|
|||||||
|
|
||||||
def authenticate_client(client_id, client_password):
|
def authenticate_client(client_id, client_password):
|
||||||
try:
|
try:
|
||||||
# Send a POST request to the /Client/Login endpoint with the client_id and password
|
|
||||||
response = requests.post(CONFIG["server"]["url"] + "/Client/Login", params={'client_id': client_id, 'password': client_password})
|
response = requests.post(CONFIG["server"]["url"] + "/Client/Login", params={'client_id': client_id, 'password': client_password})
|
||||||
|
|
||||||
# Return the response from the API
|
|
||||||
return response
|
return response
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
# If a RequestException is raised, print the exception message
|
|
||||||
print(f"RequestException: {e}")
|
print(f"RequestException: {e}")
|
||||||
|
|
||||||
# Create a new Response object with a status code of 500 and the error message in the JSON body
|
|
||||||
response = Response()
|
response = Response()
|
||||||
response.status_code = 500
|
response.status_code = 500
|
||||||
response._content = b'{"success": false, "message": "Could not connect to the server. Please try again later."}'
|
response._content = b'{"success": false, "message": "Could not connect to the server. Please try again later."}'
|
||||||
@@ -26,21 +20,93 @@ def authenticate_client(client_id, client_password):
|
|||||||
|
|
||||||
def logout_client():
|
def logout_client():
|
||||||
try:
|
try:
|
||||||
# Load the session cookie from the file
|
with open('application\\session_data.json', 'r') as f: # Open the session_data.json file in read mode
|
||||||
with open('application\\session_cookie.json', 'r') as f:
|
session_data = json.load(f)
|
||||||
cookies = json.load(f)
|
response = requests.post(CONFIG["server"]["url"] + "/Client/Logout", cookies=session_data['session_cookie'])
|
||||||
|
|
||||||
# Send a POST request to the /Client/Logout endpoint
|
|
||||||
response = requests.post(CONFIG["server"]["url"] + "/Client/Logout", cookies=cookies)
|
|
||||||
|
|
||||||
# Return the response from the API
|
|
||||||
return response
|
return response
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
# If a RequestException is raised, print the exception message
|
|
||||||
print(f"RequestException: {e}")
|
print(f"RequestException: {e}")
|
||||||
|
|
||||||
# Create a new Response object with a status code of 500 and the error message in the JSON body
|
|
||||||
response = Response()
|
response = Response()
|
||||||
response.status_code = 500
|
response.status_code = 500
|
||||||
response._content = b'{"success": false, "message": "Could not connect to the server. Please try again later."}'
|
response._content = b'{"success": false, "message": "Could not connect to the server. Please try again later."}'
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
def get_client(client_id):
|
||||||
|
try:
|
||||||
|
with open('application\\session_data.json', 'r') as f: # Open the session_data.json file in read mode
|
||||||
|
session_data = json.load(f)
|
||||||
|
response = requests.get(CONFIG["server"]["url"] + "/Client", cookies=session_data['session_cookie'], params={'client_id': client_id})
|
||||||
|
return response.json()
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"RequestException: {e}")
|
||||||
|
response = Response()
|
||||||
|
response.status_code = 500
|
||||||
|
response._content = b'{"success": false, "message": "Could not connect to the server. Please try again later."}'
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
def update_client(client_id, email=None, phone_number=None, address=None):
|
||||||
|
try:
|
||||||
|
with open('application\\session_data.json', 'r') as f:
|
||||||
|
session_data = json.load(f)
|
||||||
|
|
||||||
|
# Create a dictionary of parameters to update
|
||||||
|
params = {'client_id': client_id}
|
||||||
|
if email is not None:
|
||||||
|
params['email'] = email
|
||||||
|
if phone_number is not None:
|
||||||
|
params['phone_number'] = phone_number
|
||||||
|
if address is not None:
|
||||||
|
params['address'] = address
|
||||||
|
|
||||||
|
response = requests.put(
|
||||||
|
CONFIG["server"]["url"] + "/Client",
|
||||||
|
cookies=session_data['session_cookie'],
|
||||||
|
params=params
|
||||||
|
)
|
||||||
|
response.raise_for_status() # Raise an exception if the request failed
|
||||||
|
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_accounts(client_id):
|
||||||
|
try:
|
||||||
|
with open('application\\session_data.json', 'r') as f:
|
||||||
|
session_data = json.load(f)
|
||||||
|
|
||||||
|
response = requests.get(
|
||||||
|
CONFIG["server"]["url"] + "/Client/Accounts",
|
||||||
|
cookies=session_data['session_cookie'],
|
||||||
|
params={'client_id': client_id}
|
||||||
|
)
|
||||||
|
response.raise_for_status() # Raise an exception if the request failed
|
||||||
|
accounts = response.json()
|
||||||
|
if isinstance(accounts, str): # If the response is a string, convert it to a list of dictionaries
|
||||||
|
accounts = json.loads(accounts)
|
||||||
|
return accounts
|
||||||
|
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 format_balance(balance): # Formats the balance as a currency string with comma seperator
|
||||||
|
return f"€{balance:,.2f}"
|
||||||
|
|
||||||
|
def get_transactions(account_id):
|
||||||
|
try:
|
||||||
|
with open('application\\session_data.json', 'r') as f:
|
||||||
|
session_data = json.load(f)
|
||||||
|
|
||||||
|
response = requests.get(
|
||||||
|
CONFIG["server"]["url"] + "/Account/Transactions",
|
||||||
|
cookies=session_data['session_cookie'],
|
||||||
|
params={'account_id': account_id}
|
||||||
|
)
|
||||||
|
response.raise_for_status() # Raise an exception if the request failed
|
||||||
|
transactions = response.json()
|
||||||
|
if isinstance(transactions, str): # If the response is a string, convert it to a list of dictionaries
|
||||||
|
transactions = json.loads(transactions)
|
||||||
|
return transactions
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"RequestException: {e}")
|
||||||
|
return {'success': False, 'message': "Could not connect to the server. Please try again later."}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,26 @@
|
|||||||
# Banking System Dashboard Page
|
# Banking System Dashboard Page
|
||||||
|
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import messagebox
|
from tkinter import messagebox, ttk
|
||||||
import customtkinter
|
import customtkinter
|
||||||
|
import json
|
||||||
|
from config import CONFIG
|
||||||
|
|
||||||
|
|
||||||
from connection import logout_client
|
from connection import logout_client, get_client, update_client, get_accounts, format_balance
|
||||||
|
|
||||||
|
|
||||||
|
email_entry = None
|
||||||
|
phone_entry = None
|
||||||
|
address_entry = None
|
||||||
|
frame = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#################
|
||||||
|
### Functions ###
|
||||||
|
#################
|
||||||
|
|
||||||
def logout():
|
def logout():
|
||||||
response = logout_client() # Call the logout_client function
|
response = logout_client() # Call the logout_client function
|
||||||
@@ -17,21 +32,174 @@ def logout():
|
|||||||
else:
|
else:
|
||||||
messagebox.showerror("Logout failed", json_response['message'])
|
messagebox.showerror("Logout failed", json_response['message'])
|
||||||
|
|
||||||
# Create the main window
|
def display_client_info():
|
||||||
|
global frame # Declare frame as global inside the function
|
||||||
|
if frame is not None:
|
||||||
|
for widget in frame.winfo_children(): # Destroy all widgets in the frame
|
||||||
|
widget.destroy()
|
||||||
|
else:
|
||||||
|
frame = customtkinter.CTkFrame(root)
|
||||||
|
frame.pack(anchor='w', side='left', padx=20, pady=20)
|
||||||
|
with open('application\\session_data.json', 'r') as f:
|
||||||
|
session_data = json.load(f)
|
||||||
|
client_id = session_data['client_id']
|
||||||
|
client_info = get_client(client_id)
|
||||||
|
if 'success' in client_info and client_info['success']:
|
||||||
|
client = client_info['data']
|
||||||
|
fields = [('Name', 'name'),
|
||||||
|
('Client ID', 'client_id'),
|
||||||
|
('Email', 'email'),
|
||||||
|
('Phone', 'phone_number'),
|
||||||
|
('Address', 'address'),
|
||||||
|
('Account Opened', 'opening_timestamp')]
|
||||||
|
for i, (display_name, key) in enumerate(fields):
|
||||||
|
value = client.get(key, 'N/A') # Use 'N/A' as the default value if the key is not found
|
||||||
|
label_key = customtkinter.CTkLabel(frame, text=f"{display_name}: ", font=("Helvetica", 14))
|
||||||
|
label_value = customtkinter.CTkLabel(frame, text=value, font=("Helvetica", 14))
|
||||||
|
label_key.grid(row=i, column=0, sticky='e')
|
||||||
|
label_value.grid(row=i, column=1, sticky='w')
|
||||||
|
else:
|
||||||
|
error_label = customtkinter.CTkLabel(root, text="Error: Could not retrieve client information", font=("Helvetica", 14))
|
||||||
|
error_label.pack(pady=20)
|
||||||
|
|
||||||
|
edit_button = customtkinter.CTkButton(frame, text="Edit Details", command=edit_details)
|
||||||
|
edit_button.grid(row=len(fields), column=0, columnspan=2)
|
||||||
|
|
||||||
|
|
||||||
|
def edit_details():
|
||||||
|
global edit_window, email_entry, phone_entry, address_entry # Declare the variables as global inside the function
|
||||||
|
edit_window = customtkinter.CTkToplevel(root)
|
||||||
|
edit_window.title("Edit Details")
|
||||||
|
edit_window.geometry("300x200")
|
||||||
|
edit_window.attributes('-topmost', True)
|
||||||
|
|
||||||
|
|
||||||
|
email_label = customtkinter.CTkLabel(edit_window, text="Email: ")
|
||||||
|
email_entry = customtkinter.CTkEntry(edit_window)
|
||||||
|
email_label.pack()
|
||||||
|
email_entry.pack()
|
||||||
|
|
||||||
|
phone_label = customtkinter.CTkLabel(edit_window, text="Phone: ")
|
||||||
|
phone_entry = customtkinter.CTkEntry(edit_window)
|
||||||
|
phone_label.pack()
|
||||||
|
phone_entry.pack()
|
||||||
|
|
||||||
|
address_label = customtkinter.CTkLabel(edit_window, text="Address: ")
|
||||||
|
address_entry = customtkinter.CTkEntry(edit_window)
|
||||||
|
address_label.pack()
|
||||||
|
address_entry.pack()
|
||||||
|
|
||||||
|
save_button = customtkinter.CTkButton(edit_window, text="Save", command=save_details)
|
||||||
|
save_button.pack()
|
||||||
|
edit_window.lift()
|
||||||
|
|
||||||
|
def save_details():
|
||||||
|
global edit_window, email_entry, phone_entry, address_entry
|
||||||
|
new_email = email_entry.get() if email_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
|
||||||
|
|
||||||
|
# Get the client_id from the session data
|
||||||
|
with open('application\\session_data.json', 'r') as f:
|
||||||
|
session_data = json.load(f)
|
||||||
|
client_id = session_data['client_id']
|
||||||
|
|
||||||
|
# Display a confirmation dialog box
|
||||||
|
if not messagebox.askyesno("Confirmation", "Are you sure you want to update the details?"):
|
||||||
|
return # If the user clicked 'No', exit the function
|
||||||
|
|
||||||
|
# Update the client details
|
||||||
|
result = update_client(client_id, new_email, new_phone, new_address)
|
||||||
|
# If the request was successful, update the client info displayed in the main window
|
||||||
|
if result['success']:
|
||||||
|
display_client_info()
|
||||||
|
|
||||||
|
# Destroy the window after updating the client info
|
||||||
|
edit_window.destroy()
|
||||||
|
|
||||||
|
def populate_table():
|
||||||
|
# Get the client_id from the session data
|
||||||
|
with open('application\\session_data.json', 'r') as f:
|
||||||
|
session_data = json.load(f)
|
||||||
|
client_id = session_data['client_id']
|
||||||
|
|
||||||
|
# Get the accounts for the client
|
||||||
|
response = get_accounts(client_id)
|
||||||
|
accounts = response['data'] if 'data' in response else []
|
||||||
|
|
||||||
|
# Check if accounts is a list
|
||||||
|
if not isinstance(accounts, list):
|
||||||
|
print(f"Error: Expected a list of accounts, but got {type(accounts)}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Populate the table with the accounts
|
||||||
|
for account in accounts:
|
||||||
|
formatted_balance = format_balance(account['balance'])
|
||||||
|
table.insert('', 'end', values=(account['description'], account['account_id'], formatted_balance, account['account_type']))
|
||||||
|
|
||||||
|
def on_account_double_click(event):
|
||||||
|
# Get the selected account
|
||||||
|
selected_account = table.item(table.selection())
|
||||||
|
|
||||||
|
# Open a new window
|
||||||
|
account_window = tk.Toplevel(root)
|
||||||
|
|
||||||
|
# Display the account details
|
||||||
|
display_account_details(account_window, selected_account)
|
||||||
|
|
||||||
|
##############
|
||||||
|
### Layout ###
|
||||||
|
##############
|
||||||
|
|
||||||
root = customtkinter.CTk()
|
root = customtkinter.CTk()
|
||||||
|
|
||||||
# Set the window title, icon, and size
|
|
||||||
root.title("Luxbank Dashboard")
|
root.title("Luxbank Dashboard")
|
||||||
root.iconbitmap("application/luxbank.ico")
|
root.iconbitmap("application/luxbank.ico")
|
||||||
root.geometry("800x600")
|
root.geometry("800x350")
|
||||||
|
|
||||||
# Create a label with a welcome message
|
# Check if dark mode is enabled
|
||||||
|
if CONFIG["preferences"]["dark_theme"] == "dark":
|
||||||
|
# Set the style for dark mode
|
||||||
|
customtkinter.set_appearance_mode("dark")
|
||||||
|
else:
|
||||||
|
# Set the style for light mode
|
||||||
|
customtkinter.set_appearance_mode("light")
|
||||||
|
|
||||||
|
# Create a label for the title
|
||||||
welcome_label = customtkinter.CTkLabel(root, text="Welcome to the Luxbank Dashboard!", font=("Helvetica", 24))
|
welcome_label = customtkinter.CTkLabel(root, text="Welcome to the Luxbank Dashboard!", font=("Helvetica", 24))
|
||||||
welcome_label.pack(pady=20)
|
welcome_label.pack(pady=20)
|
||||||
|
|
||||||
# Create a Logout button
|
display_client_info()
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
# Start the main loop
|
# Create a frame for the table
|
||||||
|
table_frame = ttk.Frame(root)
|
||||||
|
table_frame.pack(side='right', fill='both', expand=True)
|
||||||
|
|
||||||
|
# Create the table
|
||||||
|
table = ttk.Treeview(table_frame, columns=('Description', 'Account ID', 'Balance', 'Account Type'), show='headings')
|
||||||
|
table.heading('Description', text='Description')
|
||||||
|
table.heading('Account ID', text='Account ID')
|
||||||
|
table.heading('Balance', text='Balance')
|
||||||
|
table.heading('Account Type', text='Account Type')
|
||||||
|
|
||||||
|
# Set the column widths
|
||||||
|
table.column('Description', width=200)
|
||||||
|
table.column('Account ID', width=100)
|
||||||
|
table.column('Balance', width=100)
|
||||||
|
table.column('Account Type', width=100)
|
||||||
|
|
||||||
|
table.pack(fill='both', expand=True)
|
||||||
|
|
||||||
|
populate_table()
|
||||||
|
|
||||||
|
# Create a scrollbar for the table
|
||||||
|
scrollbar = ttk.Scrollbar(table_frame, orient='vertical', command=table.yview)
|
||||||
|
scrollbar.pack(side='right', fill='y')
|
||||||
|
table.configure(yscrollcommand=scrollbar.set)
|
||||||
|
|
||||||
|
table.bind("<Double-1>", on_account_double_click)
|
||||||
|
|
||||||
root.mainloop()
|
root.mainloop()
|
||||||
@@ -5,7 +5,9 @@ from tkinter import messagebox
|
|||||||
import customtkinter
|
import customtkinter
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from connection import *
|
import requests
|
||||||
|
from connection import authenticate_client
|
||||||
|
from config import CONFIG
|
||||||
|
|
||||||
#################
|
#################
|
||||||
### Functions ###
|
### Functions ###
|
||||||
@@ -18,18 +20,19 @@ def login():
|
|||||||
response = authenticate_client(client_id, client_password) # Authenticate the client
|
response = authenticate_client(client_id, client_password) # Authenticate the client
|
||||||
json_response = response.json() # Convert the response content to JSON
|
json_response = response.json() # Convert the response content to JSON
|
||||||
if json_response["success"] == True: # If the authentication is successful, open the dashboard
|
if json_response["success"] == True: # If the authentication is successful, open the dashboard
|
||||||
# Save the session cookie to a file
|
session_data = {
|
||||||
with open('application\\session_cookie.json', 'w') as f:
|
'session_cookie': response.cookies.get_dict(),
|
||||||
json.dump(response.cookies.get_dict(), f)
|
'client_id': client_id
|
||||||
|
}
|
||||||
|
with open('application\\session_data.json', 'w') as f: # Save the session data to a file
|
||||||
|
json.dump(session_data, f)
|
||||||
root.destroy()
|
root.destroy()
|
||||||
os.system("python application\\dashboard.py")
|
os.system("python application\\dashboard.py")
|
||||||
else:
|
else:
|
||||||
messagebox.showerror("Login failed", json_response["message"]) # If the authentication fails, show an error message
|
messagebox.showerror("Login failed", json_response["message"])
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
# If a RequestException is raised, show an error message that includes the exception message
|
|
||||||
messagebox.showerror("Login failed", "Could not connect to the server. Please try again later. Error: " + str(e))
|
messagebox.showerror("Login failed", "Could not connect to the server. Please try again later. Error: " + str(e))
|
||||||
|
|
||||||
|
|
||||||
##############
|
##############
|
||||||
### Layout ###
|
### Layout ###
|
||||||
##############
|
##############
|
||||||
@@ -54,6 +57,8 @@ entry_password.pack(pady=10)
|
|||||||
login_button= customtkinter.CTkButton(root, text="Login", command=login)
|
login_button= customtkinter.CTkButton(root, text="Login", command=login)
|
||||||
login_button.pack(pady=15)
|
login_button.pack(pady=15)
|
||||||
|
|
||||||
|
root.bind('<Return>', lambda event=None: login())
|
||||||
|
|
||||||
###########
|
###########
|
||||||
### Run ###
|
### Run ###
|
||||||
###########
|
###########
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"session": "rZS5tQOS4nXGJu-WXEg6_Ls5q8njy3GNiZ3s8N3YHEA"}
|
{"session": "ECxyI0rswhPqvD9bW2KiRsWLmRsVY8bhxDbK40X1_Ok"}
|
||||||
1
application/session_data.json
Normal file
1
application/session_data.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"session_cookie": {"session": "xC02SzGKn_a4_R2fhKuj8qNWFk1MIx9zjatqzyzpRBM"}, "client_id": "31d90aad"}
|
||||||
21
manager.py
21
manager.py
@@ -13,6 +13,8 @@ import time # For OTP generation
|
|||||||
from functools import wraps # For decorators / user login
|
from functools import wraps # For decorators / user login
|
||||||
from database import * # Importing the database connection
|
from database import * # Importing the database connection
|
||||||
from emailer import send_email # Importing the emailer function
|
from emailer import send_email # Importing the emailer function
|
||||||
|
from flask import session as flask_session
|
||||||
|
from database import session
|
||||||
|
|
||||||
otps = {} # Temporary dictionary to store OTPs and their creation time
|
otps = {} # Temporary dictionary to store OTPs and their creation time
|
||||||
|
|
||||||
@@ -47,10 +49,12 @@ def format_response(success: bool, message: str = '', data: dict = None): # Form
|
|||||||
response['data'] = data
|
response['data'] = data
|
||||||
return jsonify(response)
|
return jsonify(response)
|
||||||
|
|
||||||
def get_current_client(): # Returns the current client and if they are an administrator
|
def get_current_client():
|
||||||
client = flask_session['client_id']
|
client = flask_session['client_id']
|
||||||
is_admin = session.query(Client).filter_by(client_id=client).one_or_none().administrator
|
client_obj = session.query(Client).filter_by(client_id=client).one_or_none()
|
||||||
return client, is_admin
|
if client_obj is None:
|
||||||
|
return None, None
|
||||||
|
return client_obj.client_id, client_obj.administrator
|
||||||
|
|
||||||
def verify_otp(client_id:str, otp:int): # Verifies a one time password for a client
|
def verify_otp(client_id:str, otp:int): # Verifies a one time password for a client
|
||||||
if client_id in otps and otps[client_id][0] == otp:
|
if client_id in otps and otps[client_id][0] == otp:
|
||||||
@@ -186,6 +190,17 @@ def change_password(client_id:str, password:str, new_password:str, otp:int): # C
|
|||||||
return format_response(False, "Invalid password."), 400
|
return format_response(False, "Invalid password."), 400
|
||||||
return format_response(False, "Client not found."), 404
|
return format_response(False, "Client not found."), 404
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def get_accounts(client_id: str):
|
||||||
|
current_client_id, is_admin = get_current_client()
|
||||||
|
if current_client_id is None:
|
||||||
|
# return an appropriate response or raise an exception
|
||||||
|
raise Exception("No current client found")
|
||||||
|
if not is_admin and client_id != current_client_id:
|
||||||
|
return format_response(False, "You can only view your own client information."), 403
|
||||||
|
accounts = session.query(Account).filter(Account.client_id == client_id)
|
||||||
|
return format_response(True, "", [account.to_dict() for account in accounts]), 200
|
||||||
|
|
||||||
###############
|
###############
|
||||||
### Account ###
|
### Account ###
|
||||||
###############
|
###############
|
||||||
|
|||||||
BIN
test_database.db
BIN
test_database.db
Binary file not shown.
Reference in New Issue
Block a user