1
0
mirror of https://github.com/donaldzou/WGDashboard.git synced 2024-11-23 07:30:11 +01:00

Updated documentation, minor fixes

This commit is contained in:
theonlynexus 2022-07-20 15:25:01 +09:00
parent 305c23190c
commit 9e16619e56
9 changed files with 713 additions and 583 deletions

View File

@ -286,9 +286,9 @@ def update_peer_default_config():
config = g.conf
if (
len(request.form["peer_endpoint_allowed_ips"]) == 0
or len(request.form["peer_global_DNS"]) == 0
or len(request.form["peer_remote_endpoint"]) == 0
not (request.form["peer_endpoint_allowed_ips"])
or not (request.form["peer_global_DNS"])
or not (request.form["peer_remote_endpoint"])
):
session["message"] = "Please fill in all required boxes."
session["message_status"] = "danger"

View File

@ -3,7 +3,10 @@ from __main__ import app
import sqlite3
def get_net_stats(interface_name: str) -> list:
def get_net_stats(interface_name: str) -> list[sqlite3.Row]:
"""
Gets net stats for all peers of `interface_name` and returns a list of dicts
"""
app.logger.debug(f"db.get_net_stats({interface_name})")
data = g.cur.execute(
f"SELECT total_sent, total_receive, cumu_sent, cumu_receive FROM {interface_name}"
@ -12,6 +15,9 @@ def get_net_stats(interface_name: str) -> list:
def get_net_stats_and_peer_status(interface_name: str, id: str) -> sqlite3.Row | None:
"""
Gets net stats for a given peer of `interface_name` and the data as `dict`, `None` if not found.
"""
app.logger.debug(f"db.get_net_stats_and_peer_status({interface_name})")
data = g.cur.execute(
"""SELECT total_receive, total_sent, cumu_receive, cumu_sent, status
@ -21,7 +27,12 @@ def get_net_stats_and_peer_status(interface_name: str, id: str) -> sqlite3.Row |
return data.fetchone()
def get_peer_count_by_allowed_ips(interface_name: str, ip: str, id: str):
def get_peer_count_by_allowed_ips(
interface_name: str, ip: str, id: str
) -> sqlite3.Row | None:
"""
Gets and returns the number of peers of `interface_name` that have allowed_ips similar to `ip`.
"""
app.logger.debug(f"db.get_peer_count_by_allowed_ips({interface_name}, {ip}, {id})")
data = g.cur.execute(
f"""SELECT COUNT(*) FROM {interface_name}
@ -31,7 +42,7 @@ def get_peer_count_by_allowed_ips(interface_name: str, ip: str, id: str):
return data.fetchone()
def get_peers(interface_name: str, search: str = None) -> list:
def get_peers(interface_name: str, search: str = None) -> list[sqlite3.Row]:
"""Returns the list of records which name matches the search string, or all if no search is provided"""
app.logger.debug(f"db.get_peers({interface_name}, {search})")
@ -44,8 +55,10 @@ def get_peers(interface_name: str, search: str = None) -> list:
return data.fetchall()
def get_peer_by_id(interface_name: str, id: str) -> list:
"""Returns the record matching the pass id or None."""
def get_peer_by_id(interface_name: str, id: str) -> sqlite3.Row | None:
"""
Returns the peer of `interface_name` matching `id` or None.
"""
app.logger.debug(f"db.get_peer_by_id({interface_name}, {id})")
sql = "SELECT * FROM %s WHERE id='%s'" % (interface_name, id)
@ -53,21 +66,29 @@ def get_peer_by_id(interface_name: str, id: str) -> list:
return data.fetchone()
def get_peer_allowed_ips(interface_name: str) -> list:
def get_peer_allowed_ips(interface_name: str) -> list[sqlite3.Row]:
"""
Returns the `allowed_ips` of all peers of `interface_name`.
"""
app.logger.debug(f"db.get_peer_allowed_ips({interface_name})")
sql = f"SELECT allowed_ips FROM {interface_name}"
data = g.cur.execute(sql)
return data.fetchall()
def get_peer_ids(interface_name: str):
def get_peer_ids(interface_name: str) -> list[sqlite3.Row]:
"""
Returns the `id`s of all peers of `interface_name`.
"""
app.logger.debug(f"db.get_peer_ids({interface_name})")
data = g.cur.execute("SELECT id FROM %s" % interface_name)
return data.fetchall()
def remove_stale_peers(interface_name: str, peer_data: str):
"""Removes entries that which id is present in the db, but not in peer_data"""
def remove_stale_peers(interface_name: str, peer_data: dict):
"""
Removes from the DB entries that are present there, but not in `peer_data`
"""
app.logger.debug(f"db.remove_stale_peers({interface_name}, peer_data)")
db_key = set(map(lambda a: a[0], get_peer_ids(interface_name)))
@ -79,12 +100,18 @@ def remove_stale_peers(interface_name: str, peer_data: str):
def delete_peer(interface_name: str, id: str):
"""
Removes a peer of `interface_name` with the given `id`
"""
app.logger.debug(f"db.delete_peer({interface_name}, {id})")
sql = "DELETE FROM %s WHERE id = '%s'" % (interface_name, id)
g.cur.execute(sql)
def insert_peer(interface_name: str, data: dict):
"""
Inserts a peer of `interface_name` with the given `data`
"""
app.logger.debug(f"db.insert_peer({interface_name}, {data})")
sql = f"""
INSERT INTO {interface_name}
@ -95,10 +122,13 @@ def insert_peer(interface_name: str, data: dict):
g.cur.execute(sql, data)
def create_table_if_missing(table_name: str):
app.logger.debug(f"db.create_table_if_missing({table_name})")
def create_table_if_missing(interface_name: str):
"""
Creates a table for `interface_name`, if missing.
"""
app.logger.debug(f"db.create_table_if_missing({interface_name})")
create_table = f"""
CREATE TABLE IF NOT EXISTS {table_name} (
CREATE TABLE IF NOT EXISTS {interface_name} (
id VARCHAR NOT NULL PRIMARY KEY, private_key VARCHAR NULL UNIQUE, DNS VARCHAR NULL,
endpoint_allowed_ips VARCHAR NULL, name VARCHAR NULL, total_receive FLOAT NULL,
total_sent FLOAT NULL, total_data FLOAT NULL, endpoint VARCHAR NULL,
@ -111,6 +141,9 @@ def create_table_if_missing(table_name: str):
def update_peer(interface_name: str, data: dict):
"""
Updates the peer of `interface_name` with the given `data`, if the peer record exists.
"""
app.logger.debug(f"db.interface_name({data})")
id = data["id"]
db_peer = get_peer_by_id(interface_name, id)
@ -121,6 +154,10 @@ def update_peer(interface_name: str, data: dict):
def _update_peer(interface_name: str, data: dict):
"""
Updates the peer of `interface_name` with the given `data`.
`data` should contain the peer's `id` (public key), plus any other field to be updated.
"""
app.logger.debug(f"db.update_peer({interface_name}, {data})")
sql = f"""
UPDATE {interface_name} SET

View File

@ -322,7 +322,7 @@ def add_peer(interface_name):
data = request.get_json()
public_key = data["public_key"]
allowed_ips = data["allowed_ips"]
endpoint_allowed_ips = data["endpoint_allowed_ip"]
endpoint_allowed_ips = data["endpoint_allowed_ips"]
dns_addresses = data["DNS"]
enable_preshared_key = data["enable_preshared_key"]
preshared_key = data["preshared_key"]
@ -398,7 +398,7 @@ def save_peer_setting(interface_name):
private_key = data["private_key"]
dns_addresses = data["DNS"]
allowed_ips = data["allowed_ips"]
endpoint_allowed_ips = data["endpoint_allowed_ip"]
endpoint_allowed_ips = data["endpoint_allowed_ips"]
preshared_key = data["preshared_key"]
db_peer = db.get_peer_by_id(interface_name, id)
if db_peer:
@ -624,7 +624,7 @@ def add_peer_bulk(interface_name):
data = request.get_json()
keys = data["keys"]
endpoint_allowed_ips = data["endpoint_allowed_ip"]
endpoint_allowed_ips = data["endpoint_allowed_ips"]
dns_addresses = data["DNS"]
enable_preshared_key = data["enable_preshared_key"]
amount = data["amount"]

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,9 @@
<!-- configuration.html - < WGDashboard > - Copyright(C) 2021 Donald Zou [https://github.com/donaldzou]-->
<html lang="en">
{% with title=title%}
{% include "header.html"%}
{% include "header.html"%}
{% endwith %}
<body>
<div class="no-response">
<div class="container">
@ -30,7 +31,8 @@
<div class="col">
<small class="text-muted"><strong>SWITCH</strong></small><br>
<div id="conf_status_btn" class="info_loading"></div>
<div class="spinner-border text-primary" role="status" style="display: none; margin-top: 10px">
<div class="spinner-border text-primary" role="status"
style="display: none; margin-top: 10px">
<span class="sr-only">Loading...</span>
</div>
</div>
@ -49,7 +51,8 @@
</div>
<div class="col-sm">
<small class="text-muted"><strong>TOTAL RECEIVED</strong></small>
<h6 style="text-transform: uppercase;" id="conf_total_data_received" class="info_loading"></h6>
<h6 style="text-transform: uppercase;" id="conf_total_data_received" class="info_loading">
</h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>TOTAL SENT</strong></small>
@ -59,17 +62,20 @@
<div class="col-sm">
<small class="text-muted">
<strong>PUBLIC KEY</strong>
<strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong>
<strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out"
class="text-primary">CLICK TO COPY</strong>
</small>
<h6 class="info_loading"><samp class="key" id="conf_public_key"></samp></h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>LISTEN PORT</strong></small>
<h6 style="text-transform: uppercase;" class="info_loading"><samp id="conf_listen_port"></samp></h6>
<h6 style="text-transform: uppercase;" class="info_loading"><samp
id="conf_listen_port"></samp></h6>
</div>
<div class="col-sm">
<small class="text-muted"><strong>ADDRESS</strong></small>
<h6 style="text-transform: uppercase;" class="info_loading"><samp id="conf_address"></samp></h6>
<h6 style="text-transform: uppercase;" class="info_loading"><samp id="conf_address"></samp>
</h6>
</div>
</div>
</div>
@ -90,11 +96,22 @@
<div class="form-group">
<label><small class="text-muted">Refresh Interval</small></label><br>
<div class="btn-group interval-btn-group" role="group" style="width: 100%">
<button style="width: 20%" type="button" class="btn btn-outline-primary btn-group-label refresh" data-toggle="tooltip" data-placement="bottom" title="Refresh Peers"><i class="bi bi-arrow-repeat"></i></button>
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="5000">5s</button>
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="10000">10s</button>
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="30000">30s</button>
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="60000">1m</button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary btn-group-label refresh" data-toggle="tooltip"
data-placement="bottom" title="Refresh Peers"><i
class="bi bi-arrow-repeat"></i></button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="5000">5s</button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="10000">10s</button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="30000">30s</button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="60000">1m</button>
</div>
</div>
</div>
@ -102,17 +119,26 @@
<div class="form-group">
<label><small class="text-muted">Display Mode</small></label><br>
<div class="btn-group display-btn-group" role="group" style="width: 100%">
<button style="width: 20%" type="button" class="btn btn-outline-primary display_mode" data-display-mode="grid"><i class="bi bi-grid-fill" style="font-size: 1.5rem;"></i></button>
<button style="width: 20%" type="button" class="btn btn-outline-primary display_mode" data-display-mode="list"><i class="bi bi-list" style="font-size: 1.5rem;"></i></button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary display_mode" data-display-mode="grid"><i
class="bi bi-grid-fill" style="font-size: 1.5rem;"></i></button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary display_mode" data-display-mode="list"><i
class="bi bi-list" style="font-size: 1.5rem;"></i></button>
</div>
</div>
</div>
<div class="btn-manage-group">
<button type="button" class="btn btn-primary add_btn"><i class="bi bi-plus-circle-fill" style=""></i></button>
<button type="button" class="btn btn-secondary setting_btn"><i class="bi bi-three-dots"></i></button>
<button type="button" class="btn btn-primary add_btn"><i class="bi bi-plus-circle-fill"
style=""></i></button>
<button type="button" class="btn btn-secondary setting_btn"><i
class="bi bi-three-dots"></i></button>
<div class="setting_btn_menu">
<a class="text-danger" id="delete_peers_by_bulk_btn"><i class="bi bi-trash-fill"></i> Delete Peers</a>
<a class="text-info" id="download_all_peers" data-url="/download_all/{{conf_data['name']}}"><i class="bi bi-cloud-download-fill"></i> Download All Peers</a>
<a class="text-danger" id="delete_peers_by_bulk_btn"><i class="bi bi-trash-fill"></i>
Delete Peers</a>
<a class="text-info" id="download_all_peers"
data-url="/download_all/{{conf_data['name']}}"><i
class="bi bi-cloud-download-fill"></i> Download All Peers</a>
</div>
</div>
@ -138,11 +164,15 @@
<div>
<div class="custom-control custom-switch" style="margin-bottom: 1rem">
<input class="custom-control-input" type="checkbox" id="bulk_add">
<label class="custom-control-label" for="bulk_add"><strong>Add Peers by bulk</strong></label>
<i class="bi bi-question-circle-fill" style="cursor: pointer" data-container="body" data-toggle="popover" data-placement="right" data-trigger="click" data-content="By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP."></i>
<label class="custom-control-label" for="bulk_add"><strong>Add Peers by
bulk</strong></label>
<i class="bi bi-question-circle-fill" style="cursor: pointer" data-container="body"
data-toggle="popover" data-placement="right" data-trigger="click"
data-content="By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP."></i>
</div>
<div class="form-group" style="margin: 0">
<input type="number" class="form-control" id="new_add_amount" min="1" placeholder="Amount" disabled>
<input type="number" class="form-control" id="new_add_amount" min="1" placeholder="Amount"
disabled>
<div id="bulk_amount_validation" class="invalid-feedback"></div>
</div>
@ -161,13 +191,16 @@
<div class="input-group">
<input type="text" class="form-control" id="private_key" aria-describedby="private_key">
<div class="input-group-append">
<button type="button" class="btn btn-danger" id="re_generate_key" data-toggle="tooltip" data-placement="top" title="Regenerate Key"><i class="bi bi-arrow-repeat"></i></button>
<button type="button" class="btn btn-danger" id="re_generate_key"
data-toggle="tooltip" data-placement="top" title="Regenerate Key"><i
class="bi bi-arrow-repeat"></i></button>
</div>
</div>
</div>
<div class="form-group non-bulk">
<label for="public_key">Public Key <code>(Required)</code></label>
<input type="text" class="form-control" id="public_key" aria-describedby="public_key" disabled>
<input type="text" class="form-control" id="public_key" aria-describedby="public_key"
disabled>
</div>
<div class="row">
<div class="col-sm-6 non-bulk">
@ -182,12 +215,14 @@
<div class="input-group">
<input type="text" class="form-control" id="allowed_ips">
<div class="input-group-append">
<button type="button" class="btn btn-primary" id="search_available_ip" data-toggle="tooltip" data-placement="top" title="Search Available IPs">
<button type="button" class="btn btn-primary" id="search_available_ip"
data-toggle="tooltip" data-placement="top" title="Search Available IPs">
<i class="bi bi-search"></i>
</button>
</div>
</div>
<p style="position: absolute; top: 4px; right: 1rem;" class="text-success" id="allowed_ips_indicator"></p>
<p style="position: absolute; top: 4px; right: 1rem;" class="text-success"
id="allowed_ips_indicator"></p>
</div>
</div>
<div class="col-sm-6">
@ -198,8 +233,10 @@
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="new_add_endpoint_allowed_ip">Endpoint Allowed IPs <code>(Required)</code></label>
<input type="text" class="form-control" id="new_add_endpoint_allowed_ip" value="{{ endpoint_allowed_ip }}">
<label for="new_add_endpoint_allowed_ip">Endpoint Allowed IPs
<code>(Required)</code></label>
<input type="text" class="form-control" id="new_add_endpoint_allowed_ip"
value="{{ endpoint_allowed_ips }}">
</div>
</div>
<div class="col-sm-6">
@ -211,12 +248,14 @@
<div class="col-sm-6">
<div class="form-group">
<label for="new_add_keep_alive">Persistent keepalive</label>
<input type="text" class="form-control" id="new_add_keep_alive" value="{{ keep_alive }}">
<input type="text" class="form-control" id="new_add_keep_alive"
value="{{ keep_alive }}">
</div>
</div>
<div class="col-sm">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="enable_preshare_key" name="enable_preshare_key" value="enable_psk">
<input class="form-check-input" type="checkbox" id="enable_preshare_key"
name="enable_preshare_key" value="enable_psk">
<label class="form-check-label" for="enable_preshare_key">Use Pre-shared Key</label>
</div>
</div>
@ -225,7 +264,8 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="save_peer" conf_id={{conf_data['name']}}>Add</button>
<button type="button" class="btn btn-primary" id="save_peer"
conf_id={{conf_data['name']}}>Add</button>
</div>
</div>
</div>
@ -241,7 +281,8 @@
</button>
</div>
<div class="modal-body">
<div id="remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert">
<div id="remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none"
role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
@ -250,7 +291,8 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">No</button>
<button type="button" class="btn btn-danger" id="delete_peer" conf_id={{conf_data['name']}} peer_id="">Yes</button>
<button type="button" class="btn btn-danger" id="delete_peer" conf_id={{conf_data['name']}}
peer_id="">Yes</button>
</div>
</div>
</div>
@ -266,14 +308,17 @@
</button>
</div>
<div class="modal-body">
<div id="setting_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert">
<div id="setting_peer_alert" class="alert alert-danger alert-dismissible fade show d-none"
role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="mb-3">
<label for="peer_private_key_textbox" class="form-label">Private Key <code>(Required for QR Code and download)</code></label>
<input type="password" class="form-control" id="peer_private_key_textbox" style="padding-right: 40px">
<label for="peer_private_key_textbox" class="form-label">Private Key
<code>(Required for QR Code and download)</code></label>
<input type="password" class="form-control" id="peer_private_key_textbox"
style="padding-right: 40px">
<a class="peer_private_key_textbox_switch"><i class="bi bi-eye-fill"></i></a>
</div>
<div>
@ -291,7 +336,8 @@
</div>
<div class="col-sm-6">
<div class="mb-3">
<label for="peer_allowed_ip_textbox" class="form-label">Allowed IPs <code>(Required)</code></label>
<label for="peer_allowed_ip_textbox" class="form-label">Allowed IPs
<code>(Required)</code></label>
<input type="text" class="form-control" id="peer_allowed_ip_textbox">
</div>
</div>
@ -303,7 +349,8 @@
</div>
<div class="col-sm-6">
<div class="mb-3">
<label for="peer_endpoint_allowed_ips" class="form-label">Endpoint Allowed IPs <code>(Required)</code></label>
<label for="peer_endpoint_allowed_ips" class="form-label">Endpoint Allowed IPs
<code>(Required)</code></label>
<input type="text" class="form-control" id="peer_endpoint_allowed_ips">
</div>
</div>
@ -323,7 +370,8 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="save_peer_setting" conf_id={{conf_data['name']}} peer_id="">Save</button>
<button type="button" class="btn btn-primary" id="save_peer_setting" conf_id={{conf_data['name']}}
peer_id="">Save</button>
</div>
</div>
</div>
@ -360,7 +408,8 @@
<span aria-hidden="true">&times;</span>
</button>
</div>
<div id="bulk_remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert" style="margin: 1rem">
<div id="bulk_remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none"
role="alert" style="margin: 1rem">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
@ -373,8 +422,10 @@
<div class="list-group"></div>
</div>
<div class="modal-footer">
<a class="text-danger" id="select_all_delete_bulk_peers" style="cursor: pointer; margin-right: auto;"><small><strong>SELECT ALL</strong></small></a>
<button type="button" class="btn btn-danger" id="confirm_delete_bulk_peers" disabled data-conf="{{conf_data['name']}}">Delete</button>
<a class="text-danger" id="select_all_delete_bulk_peers"
style="cursor: pointer; margin-right: auto;"><small><strong>SELECT ALL</strong></small></a>
<button type="button" class="btn btn-danger" id="confirm_delete_bulk_peers" disabled
data-conf="{{conf_data['name']}}">Delete</button>
</div>
</div>
</div>
@ -418,9 +469,10 @@
let load_interval = 0;
let conf_name = "{{ conf_data['name'] }}"
let peers = [];
$(".sb-"+conf_name+"-url").addClass("active");
$(function(){
$(".sb-" + conf_name + "-url").addClass("active");
$(function () {
configurations.loadPeers($('#search_peer_textbox').val());
});
</script>
</html>

View File

@ -1,11 +1,12 @@
<html>
{% with %}
{% set title="Settings" %}
{% include "header.html" %}
{% set title="Settings" %}
{% include "header.html" %}
{% endwith %}
<body>
{% include "navbar.html" %}
<div class="container-fluid">
{% include "navbar.html" %}
<div class="container-fluid">
{% include "sidebar.html" %}
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<div class="setting-container mt-4">
@ -26,32 +27,30 @@
<div class="col-sm-6">
<label for="peer_global_DNS">DNS</label>
<input type="text" class="form-control mb-4" id="peer_global_DNS"
name="peer_global_DNS"
value="{{ peer_global_DNS }}" required>
name="peer_global_DNS" value="{{ peer_global_DNS }}" required>
</div>
<div class="col-sm-6">
<label for="peer_endpoint_allowed_ip">Peer Endpoint Allowed IPs</label>
<label for="peer_endpoint_allowed_ips">Peer Endpoint Allowed IPs</label>
<input type="text" class="form-control mb-4" id="peer_endpoint_allowed_ip"
name="peer_endpoint_allowed_ip"
value="{{ peer_endpoint_allowed_ip }}" required>
name="peer_endpoint_allowed_ips" value="{{ peer_endpoint_allowed_ips }}"
required>
</div>
<div class="col-sm-6">
<label for="peer_mtu">MTU</label>
<input type="text" class="form-control mb-4" id="peer_mtu"
name="peer_mtu"
<input type="text" class="form-control mb-4" id="peer_mtu" name="peer_mtu"
value="{{ peer_mtu }}">
</div>
<div class="col-sm-6">
<label for="peer_keep_alive">Persistent Keepalive</label>
<input type="text" class="form-control mb-4" id="peer_keep_alive"
name="peer_keep_alive"
value="{{ peer_keepalive }}">
name="peer_keep_alive" value="{{ peer_keepalive }}">
</div>
<div class="col-sm-12">
<label for="peer_remote_endpoint"><strong>Peer Remote Endpoint (This will be change globally, and will be apply to all peer's QR code and configuration file.)</strong></label>
<label for="peer_remote_endpoint"><strong>Peer Remote Endpoint (This will be
change globally, and will be apply to all peer's QR code and
configuration file.)</strong></label>
<input type="text" class="form-control mb-4" id="peer_remote_endpoint"
name="peer_remote_endpoint"
value="{{ peer_remote_endpoint }}" required>
name="peer_remote_endpoint" value="{{ peer_remote_endpoint }}" required>
</div>
</div>
<button class="btn btn-success" type="submit">Update Peer Default Settings</button>
@ -68,7 +67,8 @@
<label for="wg_conf_path">Path</label>
<input type="text" class="form-control mb-2" id="wg_conf_path" name="wg_conf_path"
value="{{ wg_conf_path }}">
<p class="text-muted">Remember to remove <code>/</code> at the end of your path. e.g <code>/etc/wireguard</code>
<p class="text-muted">Remember to remove <code>/</code> at the end of your path. e.g
<code>/etc/wireguard</code>
</p>
<button class="btn btn-danger change_path">Update Path & Restart Dashboard</button>
</div>
@ -115,8 +115,10 @@
<div class="row">
<div class="col-sm">
<label for="app_ip">Dashboard IP</label>
<input type="text" class="form-control mb-2" id="app_ip" name="app_ip" value="{{ app_ip }}">
<p><small class="text-danger mb-4">0.0.0.0 means it can be access by anyone with your server
<input type="text" class="form-control mb-2" id="app_ip" name="app_ip"
value="{{ app_ip }}">
<p><small class="text-danger mb-4">0.0.0.0 means it can be access by anyone with
your server
IP Address.</small></p>
</div>
<div class="col-sm">
@ -153,14 +155,16 @@
<p class="app_new_port text-bold text-danger" style="font-weight: bold"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary cancel_restart" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger confirm_restart">Confirm & Restart Dashboard</button>
<button type="button" class="btn btn-secondary cancel_restart"
data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger confirm_restart">Confirm & Restart
Dashboard</button>
</div>
</div>
</div>
</div>
</div>
{% include "tools.html" %}
</div>
{% include "tools.html" %}
</body>
{% include "footer.html" %}
@ -201,4 +205,5 @@
});
</script>
</html>

View File

@ -14,16 +14,21 @@ Helper Functions
"""
def adapt_for_rest(x):
x["allowed_ip"] = x.pop("allowed_ips")
x["endpoint_allowed_ip"] = x.pop("endpoint_allowed_ips")
for i in ["latest_handshake", "endpoint", "allowed_ip"]:
if not x[i]:
x[i] = "N/A"
return x
def get_interface_file_path(interface_name: str, base_dir: str) -> str:
return os.path.join(base_dir, f"{interface_name}.conf")
def connect_db(dashboard_configuration_dir):
def adapt_for_rest(peer_dict: dict) -> dict:
"""
Renames necessary entries and replaces falsy values. Returns the modified dict.
"""
for i in ["latest_handshake", "endpoint", "allowed_ips"]:
if not peer_dict[i]:
peer_dict[i] = "(None)"
return peer_dict
def connect_db(dashboard_configuration_dir: str):
"""
Connect to the database
@return: sqlite3.Connection
@ -35,7 +40,7 @@ def connect_db(dashboard_configuration_dir):
return con
def read_dashboard_conf(dashboard_conf_file_path):
def read_dashboard_conf(dashboard_conf_file_path: str):
"""
Get dashboard configuration
@return: configparser.ConfigParser
@ -45,7 +50,7 @@ def read_dashboard_conf(dashboard_conf_file_path):
return r_config
def write_dashboard_conf(config, dashboard_conf_file_path):
def write_dashboard_conf(config: str, dashboard_conf_file_path: str):
"""
Write to configuration
@param config: Input configuration
@ -54,7 +59,9 @@ def write_dashboard_conf(config, dashboard_conf_file_path):
config.write(conf_object)
def wg_peer_data_to_db(interface_name, wg_conf_dir, dashboard_conf_file_path):
def wg_peer_data_to_db(
interface_name: str, wg_conf_dir: str, dashboard_conf_file_path: str
):
"""
Look for new peers from WireGuard
@param interface_name: Configuration name
@ -110,9 +117,7 @@ def wg_peer_data_to_db(interface_name, wg_conf_dir, dashboard_conf_file_path):
handshakes = wg.get_interface_peers_latest_handshakes(interface_name)
transfers = wg.get_interface_peers_net_stats(interface_name)
endpoints = wg.get_interface_peers_endpoints(interface_name)
allowed_ips = wg.get_interface_peers_allowed_ips(
interface_and_peer_data, interface_name
)
allowed_ips = wg.get_interface_peers_allowed_ips(interface_and_peer_data)
keys = set()
for x in [handshakes, transfers, endpoints, allowed_ips]:
keys.update(x.keys())
@ -127,7 +132,11 @@ def wg_peer_data_to_db(interface_name, wg_conf_dir, dashboard_conf_file_path):
def update_db_and_get_peers(
interface_name, search, sort_t, wg_conf_dir, dashboard_conf_file_path
interface_name: str,
search: str,
sort_t: str,
wg_conf_dir: str,
dashboard_conf_file_path: str,
):
"""
Get all peers.
@ -162,7 +171,7 @@ def update_db_and_get_peers(
return result
def get_conf_list(wg_conf_dir):
def get_conf_list(wg_conf_dir: str):
"""Get all wireguard interfaces with status.
@return: Return a list of dicts with interfaces and its statuses
@rtype: list
@ -188,7 +197,7 @@ def get_conf_list(wg_conf_dir):
return conf
def f_check_key_match(private_key, public_key, interface_name):
def f_check_key_match(private_key: str, public_key: str, interface_name: str):
"""
Check if private key and public key match
@param private_key: Private key
@ -216,7 +225,7 @@ def f_check_key_match(private_key, public_key, interface_name):
return {"status": "success"}
def check_repeat_allowed_ips(public_key, ip, interface_name):
def check_repeat_allowed_ips(public_key: str, ip: str, interface_name: str):
"""
Check if there are repeated IPs
@param public_key: Public key of the peer
@ -238,7 +247,7 @@ def check_repeat_allowed_ips(public_key, ip, interface_name):
return {"status": "success"}
def f_available_ips(interface_name, wg_conf_dir):
def f_available_ips(interface_name: str, wg_conf_dir: str):
"""
Get a list of available IPs
@param interface_name: Configuration Name
@ -289,7 +298,7 @@ def ensure_subnet(ipv4: str, default_subnet: str = "24") -> str:
# Regex Match
def regex_match(regex, text):
def regex_match(regex: str, text: str):
pattern = re.compile(regex)
return pattern.search(text) is not None

View File

@ -7,15 +7,21 @@ import db
import os
import ifcfg
import re
import util
def _is_comment_line(line: str) -> bool:
"""Returns true if the passed string is a comment"""
"""
Returns true if the passed string is a comment in an INI style file.
"""
line = line.strip()
return line.startswith("#") or line.startswith(";")
def _parse_peer_or_interface(lines, i, limit):
def _parse_peer_or_interface(lines: list[str], i: int, limit: int) -> dict:
"""
Parses a [Peer] or [Interface] section of an interface config file into a `dict`.
"""
data = {}
while i < limit:
line = lines[i].strip()
@ -30,23 +36,32 @@ def _parse_peer_or_interface(lines, i, limit):
def set_peer_options(
interface_name, public_key, allowed_ips, preshared_key_filename=None
interface_name: str,
public_key: str,
allowed_ips: str,
preshared_key_filename: str = None,
):
"""
Sets the given options for the specified `interface_name` and peer (`public_key`)
"""
if preshared_key_filename:
status = subprocess.check_output(
subprocess.check_output(
f"wg set {interface_name} peer {public_key} allowed-ips {allowed_ips} preshared-key {preshared_key_filename}",
shell=True,
stderr=subprocess.STDOUT,
)
else:
status = subprocess.check_output(
subprocess.check_output(
f"wg set {interface_name} peer {public_key} allowed-ips {allowed_ips}",
shell=True,
stderr=subprocess.STDOUT,
)
def remove_peer_from_interface(interface_name, public_key):
def remove_peer_from_interface(interface_name: str, public_key: str):
"""
Removes the specified peer (`public_key`) from `interface_name`
"""
subprocess.check_output(
f"wg set {interface_name} peer {public_key} remove",
shell=True,
@ -54,7 +69,7 @@ def remove_peer_from_interface(interface_name, public_key):
)
def get_interface_listen_port(interface_name, base_dir):
def get_interface_listen_port(interface_name: str, base_dir: str) -> str:
"""
Get listen port number.
@param interface_name: Name of WG interface
@ -80,7 +95,7 @@ def get_interface_listen_port(interface_name, base_dir):
return port
def get_interface_public_key(interface_name, base_dir):
def get_interface_public_key(interface_name: str, base_dir: str) -> str:
"""
Get public key for configuration.
@param interface_name: Name of WG interface
@ -122,7 +137,7 @@ def get_interface_total_net_stats(interface_name):
return [total, upload_total, download_total]
def get_interface_status(interface_name):
def get_interface_status(interface_name: str) -> str:
"""
Check if the configuration is running or not
@param interface_name:
@ -206,7 +221,7 @@ def read_interface_config_file(interface_name: str, base_dir: str) -> dict:
"""
app.logger.debug(f"read_conf_file({interface_name})")
config_file = os.path.join(base_dir, f"{interface_name}.conf")
config_file = util.get_interface_file_path(interface_name, base_dir)
with open(config_file, "r", encoding="utf-8") as file_object:
file = list(file_object.readlines())
result = {"Interface": {}, "Peers": []}
@ -229,7 +244,10 @@ def read_interface_config_file(interface_name: str, base_dir: str) -> dict:
def switch_interface(interface_name: str, base_dir: str):
config_file = os.path.join(base_dir, f"{interface_name}.conf")
"""
Switches `interface_name` around (up if it is down, down if it is up)
"""
config_file = util.get_interface_file_path(interface_name, base_dir)
status = get_interface_status(interface_name)
if status == "running":
check = subprocess.check_output(
@ -242,14 +260,20 @@ def switch_interface(interface_name: str, base_dir: str):
def enable_interface(interface_name: str, base_dir: str):
config_file = os.path.join(base_dir, f"{interface_name}.conf")
"""
Brings `interface_name` up (enables it)
"""
config_file = util.get_interface_file_path(interface_name, base_dir)
check = subprocess.check_output(
"wg-quick up " + config_file, shell=True, stderr=subprocess.STDOUT
)
def disable_interface(interface_name: str, base_dir: str):
config_file = os.path.join(base_dir, f"{interface_name}.conf")
"""
Brings `interface_name` down (disables it)
"""
config_file = util.get_interface_file_path(interface_name, base_dir)
check = subprocess.check_output(
"wg-quick down " + config_file, shell=True, stderr=subprocess.STDOUT
)
@ -297,7 +321,7 @@ def get_interface_peers_latest_handshakes(interface_name) -> dict:
return result
def get_interface_peers_net_stats(interface_name) -> dict:
def get_interface_peers_net_stats(interface_name: str) -> dict:
"""
Get transfer from all peers of a configuration
@param interface_name: Configuration name
@ -354,14 +378,17 @@ def get_interface_peers_net_stats(interface_name) -> dict:
return result
def quick_save_interface_config(interface_name, base_dir):
config_file = os.path.join(base_dir, f"{interface_name}.conf")
def quick_save_interface_config(interface_name: str, base_dir: str):
"""
Executes `wg-quick save` for `interface_name`
"""
config_file = util.get_interface_file_path(interface_name, base_dir)
status = subprocess.check_output(
"wg-quick save " + config_file, shell=True, stderr=subprocess.STDOUT
)
def gen_public_key(private_key):
def gen_public_key(private_key: str):
"""Generate the public key.
@param private_key: Private key
@ -390,7 +417,7 @@ def gen_public_key(private_key):
}
def get_interface_peers_endpoints(interface_name) -> dict:
def get_interface_peers_endpoints(interface_name: str) -> dict:
"""
Get endpoint from all peers of a configuration
@param interface_name: Configuration name
@ -414,7 +441,7 @@ def get_interface_peers_endpoints(interface_name) -> dict:
return result
def get_interface_peers_allowed_ips(conf_peer_data, interface_name) -> dict:
def get_interface_peers_allowed_ips(conf_peer_data: str) -> dict:
"""
Get allowed ips from all peers of a configuration
@param conf_peer_data: Configuration peer data