diff --git a/.gitignore b/.gitignore index a539470..5392b09 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -config.yaml \ No newline at end of file +config.yaml +__pycache__/ diff --git a/lib.py b/lib.py index d2c6f03..5d04a51 100644 --- a/lib.py +++ b/lib.py @@ -68,3 +68,6 @@ class Server: with open("config.yaml", "w") as file: yaml.safe_dump(config_file, file) log.info("Changed %s comment to '%s'", self.data["server_id"], config.get("comment")) + + def create_key(self, key_name): + return self.client.create_key(key_name) \ No newline at end of file diff --git a/main.py b/main.py index 38aac86..59fd151 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,8 @@ -from outline_vpn.outline_vpn import OutlineVPN import yaml import logging from datetime import datetime +import random +import string from flask import Flask, render_template, request, url_for, redirect @@ -14,16 +15,25 @@ logging.basicConfig( log = logging.getLogger('OutlineFleet') SERVERS = list() +CLIENTS = list() app = Flask(__name__) def format_timestamp(ts): - return datetime.fromtimestamp(ts//1000).strftime('%Y-%m-%d %H:%M:%S') + return datetime.fromtimestamp(ts // 1000).strftime('%Y-%m-%d %H:%M:%S') + + +def random_string(length=12): + letters = string.ascii_letters + string.digits + + return ''.join(random.choice(letters) for i in range(length)) def update_state(): global SERVERS + global CLIENTS SERVERS = list() + CLIENTS = list() config = dict() try: with open("config.yaml", "r") as file: @@ -33,12 +43,14 @@ def update_state(): pass if config: - servers = config.get('servers', None) - for server_id, config in servers.items(): - server = Server(url=config["url"], cert=config["cert"], comment=config["comment"]) + servers = config.get('servers', list()) + for server_id, server_config in servers.items(): + server = Server(url=server_config["url"], cert=server_config["cert"], comment=server_config["comment"]) SERVERS.append(server) log.info("Server found: %s", server.info()["name"]) + CLIENTS = config.get('clients', list()) + @app.route('/', methods=['GET', 'POST']) def index(): @@ -49,20 +61,42 @@ def index(): nt=request.args.get('nt'), nl=request.args.get('nl'), selected_server=request.args.get('selected_server'), + add_server=request.args.get('add_server', None), + format_timestamp=format_timestamp, + ) + else: + server = request.form['server_id'] + server = next((item for item in SERVERS if item.info()["server_id"] == server), None) + server.apply_config(request.form) + update_state() + return redirect( + url_for('index', nt="Updated Outline VPN Server", selected_server=request.args.get('selected_server'))) + + +@app.route('/clients', methods=['GET', 'POST']) +def clients(): + if request.method == 'GET': + return render_template( + 'clients.html', + SERVERS=SERVERS, + CLIENTS=CLIENTS, + nt=request.args.get('nt'), + nl=request.args.get('nl'), + selected_client=request.args.get('selected_client'), + add_client=request.args.get('add_client', None), format_timestamp=format_timestamp) else: server = request.form['server_id'] server = next((item for item in SERVERS if item.info()["server_id"] == server), None) server.apply_config(request.form) update_state() - return redirect(url_for('index', nt="Updated Outline VPN Server", selected_server=request.args.get('selected_server'))) + return redirect( + url_for('index', nt="Updated Outline VPN Server", selected_server=request.args.get('selected_server'))) -@app.route('/add_server', methods=['GET', 'POST']) +@app.route('/add_server', methods=['POST']) def add_server(): - if request.method == 'GET': - return render_template('add_server.html') - else: + if request.method == 'post': with open("config.yaml", "r") as file: config = yaml.safe_load(file) or {} @@ -86,6 +120,31 @@ def add_server(): return redirect(url_for('index', nt="Added Outline VPN Server")) +@app.route('/add_client', methods=['POST']) +def add_client(): + if request.method == 'POST': + with open("config.yaml", "r") as file: + config = yaml.safe_load(file) or {} + + clients = config.get('clients', dict()) + user_id = request.form.get('user_id', random_string()) + + clients[user_id] = { + 'name': request.form.get('name'), + 'comment': request.form.get('comment'), + 'servers': request.form.getlist('servers') + } + config["clients"] = clients + with open("config.yaml", "w") as file: + yaml.safe_dump(config, file) + + for server in SERVERS: + if server.data["server_id"] in request.form.getlist('servers'): + log.info("%s", server.create_key(request.form.get('name'))) + update_state() + return redirect(url_for('index', nt="User has been added")) + + if __name__ == '__main__': update_state() app.run() diff --git a/templates/add_server.html b/templates/add_server.html deleted file mode 100644 index df07c08..0000000 --- a/templates/add_server.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "base.html" %} -{% block title %}Add new server{% endblock %} -{% block content %} -
-
-
-
- -
-
- -
-
- -
-
- -
-
-{% endblock %} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index 06c9f88..438cc6b 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,7 +1,8 @@ - {% block title %}Dashboard{% endblock %} + + {% block title %}Dashboard{% endblock %} @@ -19,7 +20,7 @@
diff --git a/templates/clients.html b/templates/clients.html new file mode 100644 index 0000000..aa17b06 --- /dev/null +++ b/templates/clients.html @@ -0,0 +1,104 @@ +{% extends "base.html" %} + +{% block content %} + +
+
+

Clients

+
+ {% for client, values in CLIENTS.items() %} +
+
+
{{ values["name"] }}
+

Allowed {{ values["servers"]|length }} server{% if values["servers"]|length >1 %}s{%endif%}

+
+
+ {% endfor %} +
+
+ + +
+
+ +
+ +{% if add_client %} +
+
+
+

Add new client

+
+
+
+
+
+
+
+ +
+
+ +
+
+ {% for server in SERVERS %} + + + {% endfor %} + +
+ +
+ +
+
+
+
+{% endif %} + + +{% if selected_client and not add_client %} + {% set client = CLIENTS[selected_client] %} + +
+
+
+

{{client['name']}}

+

{{ client['comment'] }}

+

id {{ selected_client }}

+ +
+
+
+
+
+
+
+ +
+
+ +
+ + +
+ {% for server in SERVERS %} + + + {% endfor %} + +
+ +
+ +
+
+
+
+ +{% endif %} + +{% endblock %} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index f5e9770..13baf2e 100644 --- a/templates/index.html +++ b/templates/index.html @@ -20,7 +20,7 @@ {% endfor %} -
+
+
@@ -28,78 +28,109 @@
-{% if SERVERS %} - -{% if server is none %} - {% set server = SERVERS[0] %} -{% else %} - {% set server = SERVERS[selected_server|int] %} -{% endif %} -
-
+{% if add_server %} +
-

{{server.info()["name"]}}

-

- v.{{server.info()["version"]}} {{server.info()["server_id"]}} -

+

Add new server

- - - - - -
-
-

Clients: {{ server.info()['keys']|length }}

-
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
- -
-

Share anonymous metrics

- - + +
+
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+{% endif %} - - - + +{% if SERVERS|length != 0 and not add_server %} + + {% if selected_server is none %} + {% set server = SERVERS[0] %} + {% else %} + {% set server = SERVERS[selected_server|int] %} + {% endif %} +
+
+
+
+

{{server.info()["name"]}}

+

+ v.{{server.info()["version"]}} {{server.info()["server_id"]}} +

+
+ + + + + + +
+ +
+

Clients: {{ server.info()['keys']|length }}

+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+

Share anonymous metrics

+ + + + +
+
+
-
+ {% endif %} + {% endblock %} \ No newline at end of file