mirror of
https://github.com/WGDashboard/WGDashboard-PRW.git
synced 2026-08-04 06:52:58 +00:00
feat: start working on Flask
This commit is contained in:
+1
-1
@@ -18,7 +18,7 @@ dashboard_refresh_interval = 60000
|
||||
dashboard_peer_list_display = grid
|
||||
dashboard_sort = status
|
||||
dashboard_theme = dark
|
||||
dashboard_api_key = false
|
||||
wgdashboard_apikey = false
|
||||
dashboard_language = en-US
|
||||
|
||||
[Account]
|
||||
|
||||
+17
-2
@@ -2,20 +2,35 @@
|
||||
|
||||
import logging as log
|
||||
|
||||
import flask
|
||||
import json
|
||||
import os
|
||||
|
||||
from modules.config.reader import reader
|
||||
from modules.database.database import database
|
||||
from modules.utilities.utilities import utilities as util
|
||||
|
||||
from modules.routes.routes import routes
|
||||
|
||||
if __name__ == '__main__':
|
||||
log.basicConfig(level=log.DEBUG)
|
||||
|
||||
config_contents = reader.read_config()
|
||||
ok, config_contents = reader.read_config()
|
||||
if not ok:
|
||||
exit(1)
|
||||
|
||||
found, config_database = util.filter_config(config_contents, 'DATABASE')
|
||||
if not found:
|
||||
exit(1)
|
||||
|
||||
ok, engine, session = database.create_session(config_database)
|
||||
ok = database.verify_contents(engine)
|
||||
ok = database.ensure_contents(engine)
|
||||
|
||||
app = flask.Flask("WGDashboard", template_folder=os.path.abspath("./static/dist/WGDashboardAdmin"))
|
||||
app.register_blueprint(routes)
|
||||
|
||||
app.wgdashboard_config = config_contents
|
||||
app.engine = engine
|
||||
app.db_session = session
|
||||
|
||||
app.run(debug=True, use_reloader=False)
|
||||
@@ -6,19 +6,19 @@ from .utilities import checks
|
||||
|
||||
class reader():
|
||||
@staticmethod
|
||||
def read_config() -> dict:
|
||||
def read_config() -> tuple[bool, dict]:
|
||||
'''
|
||||
check some basic things and then return the dict containing the config data
|
||||
'''
|
||||
|
||||
ok, candidate_path = checks.search_known_paths()
|
||||
if not ok:
|
||||
return {}
|
||||
return False, {}
|
||||
ok, config_contents = checks.verify_contents(candidate_path)
|
||||
if not ok:
|
||||
return {}
|
||||
return False, {}
|
||||
|
||||
return config_contents
|
||||
return True, config_contents
|
||||
|
||||
@staticmethod
|
||||
def refresh_config(config_contents: dict) -> dict:
|
||||
|
||||
@@ -55,7 +55,7 @@ class checks():
|
||||
log.debug(f'checking integrity of section: {section}')
|
||||
|
||||
if len(config.items(section)) == 0:
|
||||
log.warn('empty section, removing for runtime due to irrelevance')
|
||||
log.warn(f'empty section: {section}, removing at runtime due to irrelevance')
|
||||
config.remove_section(section)
|
||||
|
||||
config_dict = {}
|
||||
|
||||
@@ -15,8 +15,6 @@ class database():
|
||||
if not ok:
|
||||
return False, None, None
|
||||
|
||||
log.info(connection_string)
|
||||
|
||||
try:
|
||||
engine = sqlalchemy.create_engine(connection_string, echo=False)
|
||||
|
||||
@@ -30,7 +28,7 @@ class database():
|
||||
return False, None, None
|
||||
|
||||
@staticmethod
|
||||
def verify_contents(engine) -> bool:
|
||||
def ensure_contents(engine) -> bool:
|
||||
try:
|
||||
log.info('checking if all tables are present, and creating them if they are not')
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/bin/env python3
|
||||
|
||||
from datetime import datetime
|
||||
import sqlalchemy.orm
|
||||
|
||||
from .schema import Base
|
||||
from .schema import Apikeys
|
||||
|
||||
class functions():
|
||||
def retrieve_api_keys(session: sqlalchemy.orm.Session) -> dict:
|
||||
time_now = datetime.now()
|
||||
|
||||
api_keys = session.query(Apikeys).all()
|
||||
print(api_keys)
|
||||
|
||||
return {}
|
||||
@@ -21,5 +21,90 @@ class User(Base):
|
||||
|
||||
email = sqlalchemy.Column(sqlalchemy.String)
|
||||
|
||||
class Apikeys(Base):
|
||||
__tablename__ = 'apikeys'
|
||||
|
||||
apikey_id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, index=True)
|
||||
apikey_data = sqlalchemy.Column(sqlalchemy.String)
|
||||
|
||||
apikey_creation = sqlalchemy.Column(sqlalchemy.String)
|
||||
apikey_expiration = sqlalchemy.Column(sqlalchemy.String)
|
||||
|
||||
class Wireguard(Base):
|
||||
__tablename__ = 'wireguard_interfaces'
|
||||
|
||||
iface_status = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, index=True)
|
||||
|
||||
iface_name = sqlalchemy.Column(sqlalchemy.String, unique=True)
|
||||
iface_notes = sqlalchemy.Column(sqlalchemy.String)
|
||||
|
||||
iface_privkey = sqlalchemy.Column(sqlalchemy.String, unique=True)
|
||||
iface_pubkey = sqlalchemy.Column(sqlalchemy.String, unique=True)
|
||||
iface_address = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_listen_port = sqlalchemy.Column(sqlalchemy.Integer, unique=True)
|
||||
iface_mtu = sqlalchemy.Column(sqlalchemy.Integer)
|
||||
|
||||
iface_preup = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_predown = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_postup = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_predown = sqlalchemy.Column(sqlalchemy.String)
|
||||
|
||||
iface_save_config = sqlalchemy.Column(sqlalchemy.Boolean, default=True)
|
||||
|
||||
iface_total_rx = sqlalchemy.Column(sqlalchemy.Float)
|
||||
iface_total_tx = sqlalchemy.Column(sqlalchemy.Float)
|
||||
iface_total_data = sqlalchemy.Column(sqlalchemy.Float)
|
||||
|
||||
class Amnezia(Base):
|
||||
__tablename__ = 'amnezia_interfaces'
|
||||
|
||||
iface_status = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, index=True)
|
||||
|
||||
iface_name = sqlalchemy.Column(sqlalchemy.String, unique=True)
|
||||
iface_notes = sqlalchemy.Column(sqlalchemy.String)
|
||||
|
||||
iface_privkey = sqlalchemy.Column(sqlalchemy.String, unique=True)
|
||||
iface_pubkey = sqlalchemy.Column(sqlalchemy.String, unique=True)
|
||||
iface_address = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_listen_port = sqlalchemy.Column(sqlalchemy.Integer, unique=True)
|
||||
iface_mtu = sqlalchemy.Column(sqlalchemy.Integer)
|
||||
|
||||
iface_preup = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_predown = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_postup = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_predown = sqlalchemy.Column(sqlalchemy.String)
|
||||
|
||||
iface_jc = sqlalchemy.Column(sqlalchemy.Integer)
|
||||
iface_jmin = sqlalchemy.Column(sqlalchemy.Integer)
|
||||
iface_jmax = sqlalchemy.Column(sqlalchemy.Integer)
|
||||
|
||||
iface_s1 = sqlalchemy.Column(sqlalchemy.Integer)
|
||||
iface_s2 = sqlalchemy.Column(sqlalchemy.Integer)
|
||||
iface_s3 = sqlalchemy.Column(sqlalchemy.Integer)
|
||||
iface_s4 = sqlalchemy.Column(sqlalchemy.Integer)
|
||||
|
||||
iface_h1 = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_h2 = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_h3 = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_h4 = sqlalchemy.Column(sqlalchemy.String)
|
||||
|
||||
iface_i1 = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_i2 = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_i3 = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_i4 = sqlalchemy.Column(sqlalchemy.String)
|
||||
iface_i5 = sqlalchemy.Column(sqlalchemy.String)
|
||||
|
||||
iface_save_config = sqlalchemy.Column(sqlalchemy.Boolean, default=True)
|
||||
|
||||
iface_total_rx = sqlalchemy.Column(sqlalchemy.Float)
|
||||
iface_total_tx = sqlalchemy.Column(sqlalchemy.Float)
|
||||
iface_total_data = sqlalchemy.Column(sqlalchemy.Float)
|
||||
|
||||
class Peers(Base):
|
||||
__tablename__ = 'interface_peers'
|
||||
|
||||
peer_id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, index=True)
|
||||
|
||||
assigned_iface = sqlalchemy.Column(sqlalchemy.String)
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/bin/env python3
|
||||
|
||||
import flask
|
||||
|
||||
def make_resp_obj(success: bool = True, message: str = "", data: dict = {}, http_code: int = 200) -> flask.wrappers.Response:
|
||||
response = flask.make_response({
|
||||
"status": success,
|
||||
"message": message,
|
||||
"data": data
|
||||
}, http_code
|
||||
)
|
||||
|
||||
return response
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/bin/env python3
|
||||
|
||||
import flask
|
||||
|
||||
from .response import make_resp_obj
|
||||
from ..database.functions import functions
|
||||
from ..utilities.utilities import utilities
|
||||
|
||||
routes = flask.Blueprint("routes", __name__)
|
||||
|
||||
@routes.before_request
|
||||
def auth_required():
|
||||
if flask.request.method.lower() == "options":
|
||||
return make_resp_obj(True, "", flask.jsonify({"status": True}), 200)
|
||||
|
||||
ok, config_server = utilities.filter_config(flask.current_app.wgdashboard_config, 'SERVER')
|
||||
if not ok:
|
||||
return make_resp_obj(False, "Internal Error", {}, 500)
|
||||
|
||||
auth_required = config_server.get('auth_req', True) # Set to true for a safe default
|
||||
|
||||
if not auth_required:
|
||||
return
|
||||
|
||||
whiteList = [
|
||||
'/client',
|
||||
'/static/',
|
||||
'/fileDownload',
|
||||
'validateAuthentication',
|
||||
'authenticate',
|
||||
'getDashboardConfiguration',
|
||||
'getDashboardTheme',
|
||||
'getDashboardVersion',
|
||||
'sharePeer/get',
|
||||
'isTotpEnabled',
|
||||
'locale'
|
||||
]
|
||||
|
||||
request_path = flask.request.path
|
||||
http_headers = flask.request.headers
|
||||
api_key = http_headers.get("wgdashboard-apikey")
|
||||
|
||||
api_key_enabled = config_server.get("wgdashboard_apikey", False)
|
||||
registered_api_keys = functions.retrieve_api_keys(flask.current_app.db_session)
|
||||
|
||||
if not api_key:
|
||||
response = make_resp_obj()
|
||||
return response
|
||||
|
||||
@routes.route("/")
|
||||
def index():
|
||||
return make_resp_obj(True, "/ Endpoint", flask.jsonify({"message": "Hello from routes file!"}), 200)
|
||||
|
||||
@routes.route("/health")
|
||||
@routes.route("/healthz")
|
||||
def health():
|
||||
return make_resp_obj(True, "Health Endpoint", flask.jsonify({"status": "ok"}), 200)
|
||||
@@ -1 +1,2 @@
|
||||
#!/bin/env python3
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
configparser==7.2.0
|
||||
Flask==3.1.3
|
||||
sqlalchemy==2.0.47
|
||||
Reference in New Issue
Block a user