From c95937d08b6e2091ee18266b608e89e89817e8cb Mon Sep 17 00:00:00 2001 From: Donald Zou Date: Mon, 2 Jun 2025 12:04:01 +0800 Subject: [PATCH] Just commit --- src/client.py | 55 +++++++++++++++++------- src/dashboard.py | 7 ++-- src/modules/ConnectionString.py | 6 +-- src/modules/DashboardClient.py | 3 -- src/modules/DashboardClients.py | 58 ++++++++++++++++++++++++++ src/modules/DashboardLogger.py | 3 +- src/static/client/src/views/signup.vue | 6 +-- 7 files changed, 111 insertions(+), 27 deletions(-) delete mode 100644 src/modules/DashboardClient.py create mode 100644 src/modules/DashboardClients.py diff --git a/src/client.py b/src/client.py index 8b06e61..eece7e9 100644 --- a/src/client.py +++ b/src/client.py @@ -1,6 +1,10 @@ -from flask import Blueprint, render_template, abort, request, Flask, current_app +from functools import wraps + +from flask import Blueprint, render_template, abort, request, Flask, current_app, session import os -client = Blueprint('client', __name__, template_folder=os.path.abspath("./static/client/dist")) + +from modules.WireguardConfiguration import WireguardConfiguration +from modules.DashboardConfig import DashboardConfig def ResponseObject(status=True, message=None, data=None, status_code = 200) -> Flask.response_class: response = Flask.make_response(current_app, { @@ -12,16 +16,39 @@ def ResponseObject(status=True, message=None, data=None, status_code = 200) -> F response.content_type = "application/json" return response +def login_required(f): + @wraps(f) + def func(*args, **kwargs): + if session.get("username") is None or session.get("role") != "client": + return ResponseObject(False, "Unauthorized access.", data=None, status_code=401) + return f(*args, **kwargs) + return func -prefix = '/client' - - -@client.before_request -def clientBeforeRequest(): - if request.method.lower() == 'options': - return ResponseObject(True) - -@client.get(prefix) -def clientIndex(): - return render_template('client.html') - +def createClientBlueprint(wireguardConfigurations: dict[WireguardConfiguration], dashboardConfig: DashboardConfig): + from modules.DashboardClients import DashboardClients + DashboardClients = DashboardClients() + client = Blueprint('client', __name__, template_folder=os.path.abspath("./static/client/dist")) + prefix = f'{dashboardConfig.GetConfig("Server", "app_prefix")[1]}/client' + + + @client.before_request + def clientBeforeRequest(): + if request.method.lower() == 'options': + return ResponseObject(True) + + + + @client.get(prefix) + def ClientIndex(): + print(wireguardConfigurations.keys()) + return render_template('client.html') + + @client.post(f'{prefix}/api/signup') + def ClientAPI_SignUp(): + data = request.json + status, msg = DashboardClients.SignUp(**data) + + + return ResponseObject(status, msg) + + return client \ No newline at end of file diff --git a/src/dashboard.py b/src/dashboard.py index 583b17b..36edf79 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -28,13 +28,12 @@ from modules.DashboardConfig import DashboardConfig from modules.WireguardConfiguration import WireguardConfiguration from modules.AmneziaWireguardConfiguration import AmneziaWireguardConfiguration -from client import client +from client import createClientBlueprint SystemStatus = SystemStatus() CONFIGURATION_PATH = os.getenv('CONFIGURATION_PATH', '.') app = Flask("WGDashboard", template_folder=os.path.abspath("./static/app/dist")) -app.register_blueprint(client) app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 5206928 app.secret_key = secrets.token_urlsafe(32) @@ -115,7 +114,7 @@ def auth_req(): '/client' ] - if ("username" not in session + if (("username" not in session or session.get("role") != "admin") and (f"{(APP_PREFIX if len(APP_PREFIX) > 0 else '')}/" != request.path and f"{(APP_PREFIX if len(APP_PREFIX) > 0 else '')}" != request.path) and len(list(filter(lambda x : x not in request.path, whiteList))) == len(whiteList) @@ -1269,6 +1268,8 @@ DashboardLogger: DashboardLogger = DashboardLogger(DashboardConfig) InitWireguardConfigurationsList(startup=True) +app.register_blueprint(createClientBlueprint(WireguardConfigurations, DashboardConfig)) + def startThreads(): bgThread = threading.Thread(target=peerInformationBackgroundThread, daemon=True) bgThread.start() diff --git a/src/modules/ConnectionString.py b/src/modules/ConnectionString.py index c0b5930..17dd9ea 100644 --- a/src/modules/ConnectionString.py +++ b/src/modules/ConnectionString.py @@ -12,9 +12,9 @@ def ConnectionString(database) -> str or None: if not os.path.isdir(sqlitePath): os.mkdir(sqlitePath) if parser.get("Database", "type") == "postgresql": - cn = f'postgresql+psycopg2://{parser.get("Database", "username")}:{parser.get("Database", "password")[1]}@{parser.get("Database", "host")[1]}/{database}' - elif parser.get("Database", "type")[1] == "mysql": - cn = f'mysql+mysqldb://{parser.get("Database", "username")[1]}:{parser.get("Database", "password")[1]}@{parser.get("Database", "host")[1]}/{database}' + cn = f'postgresql+psycopg2://{parser.get("Database", "username")}:{parser.get("Database", "password")}@{parser.get("Database", "host")}/{database}' + elif parser.get("Database", "type") == "mysql": + cn = f'mysql+mysqldb://{parser.get("Database", "username")}:{parser.get("Database", "password")}@{parser.get("Database", "host")}/{database}' else: cn = f'sqlite:///{os.path.join(sqlitePath, f"{database}.db")}' if not database_exists(cn): diff --git a/src/modules/DashboardClient.py b/src/modules/DashboardClient.py deleted file mode 100644 index 946d820..0000000 --- a/src/modules/DashboardClient.py +++ /dev/null @@ -1,3 +0,0 @@ -class DashboardClient: - def __init__(self): - pass \ No newline at end of file diff --git a/src/modules/DashboardClients.py b/src/modules/DashboardClients.py new file mode 100644 index 0000000..4a66c7b --- /dev/null +++ b/src/modules/DashboardClients.py @@ -0,0 +1,58 @@ +import sqlalchemy as db +from sqlalchemy.orm import DeclarativeBase, Mapped +from sqlalchemy.testing.schema import mapped_column + +from .ConnectionString import ConnectionString + + +class DashboardClients: + def __init__(self): + self.engine = db.create_engine(ConnectionString("wgdashboard")) + self.metadata = db.MetaData() + + self.dashboardClientsTable = db.Table( + 'DashboardClients', self.metadata, + db.Column('ClientID', db.String(255), nullable=False, primary_key=True), + db.Column('Email', db.String(255), nullable=False, index=True), + db.Column('Password', db.String(500)), + db.Column('TotpKey', db.String(500)), + db.Column('TotpKeyVerified', db.Integer), + db.Column('CreatedDate', + (db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP), + server_default=db.func.now()), + db.Column('DeletedDate', + (db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP)), + extend_existing=True, + ) + + self.dashboardClientsInfoTable = db.Table( + 'DashboardClientsInfo', self.metadata, + db.Column('ClientID', db.String(255), nullable=False, primary_key=True), + db.Column('Firstname', db.String(500)), + db.Column('Lastname', db.String(500)), + extend_existing=True, + ) + + self.metadata.create_all(self.engine) + self.Clients = [] + self.__getClients() + print('hi') + print(self.Clients) + + def __getClients(self): + with self.engine.connect() as conn: + self.Clients = conn.execute( + db.select( + self.dashboardClientsTable.c.ClientID, + self.dashboardClientsTable.c.Email, + self.dashboardClientsTable.c.CreatedDate + ).where( + self.dashboardClientsTable.c.DeletedDate is None) + ).mappings().fetchall() + + + + def SignUp(self, Email, Password, ConfirmPassword) -> tuple[bool, str]: + pass + + \ No newline at end of file diff --git a/src/modules/DashboardLogger.py b/src/modules/DashboardLogger.py index b249ca6..d7b162c 100644 --- a/src/modules/DashboardLogger.py +++ b/src/modules/DashboardLogger.py @@ -12,6 +12,7 @@ class DashboardLogger: self.engine = db.create_engine(ConnectionString("wgdashboard_log")) self.metadata = db.MetaData() self.dashboardLoggerTable = db.Table('DashboardLog', self.metadata, + db.Column('LogID', db.String(255), nullable=False, primary_key=True), db.Column('LogDate', (db.DATETIME if DashboardConfig.GetConfig("Database", "type")[1] == 'sqlite' else db.TIMESTAMP), server_default=db.func.now()), @@ -19,7 +20,7 @@ class DashboardLogger: db.Column('IP', db.String(255)), db.Column('Status', db.String(255), nullable=False), - db.Column('Message', db.Text) + db.Column('Message', db.Text), extend_existing=True, ) self.metadata.create_all(self.engine) self.log(Message="WGDashboard started") diff --git a/src/static/client/src/views/signup.vue b/src/static/client/src/views/signup.vue index 90b528a..3c02667 100644 --- a/src/static/client/src/views/signup.vue +++ b/src/static/client/src/views/signup.vue @@ -2,9 +2,9 @@ import {reactive} from "vue"; const formData = reactive({ - email: "", - password: "", - confirmPassword: "" + Email: "", + Password: "", + ConfirmPassword: "" })