From cfcabed24473051756666ad6d0203122d8b369bc Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Sat, 17 Feb 2024 11:53:51 -0300 Subject: [PATCH] Peer list with details --- api/__init__.py | 0 api/admin.py | 3 + api/apps.py | 6 + api/migrations/__init__.py | 0 api/models.py | 3 + api/tests.py | 3 + api/views.py | 55 ++++++++ templates/base.html | 2 +- templates/wireguard/welcome.html | 5 +- templates/wireguard/wireguard_peer_list.html | 128 ++++++++++++++++++- wireguard_peer/forms.py | 3 + wireguard_peer/views.py | 4 +- wireguard_webadmin/urls.py | 3 + 13 files changed, 207 insertions(+), 8 deletions(-) create mode 100644 api/__init__.py create mode 100644 api/admin.py create mode 100644 api/apps.py create mode 100644 api/migrations/__init__.py create mode 100644 api/models.py create mode 100644 api/tests.py create mode 100644 api/views.py diff --git a/api/__init__.py b/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/admin.py b/api/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/api/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/api/apps.py b/api/apps.py new file mode 100644 index 0000000..66656fd --- /dev/null +++ b/api/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'api' diff --git a/api/migrations/__init__.py b/api/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/models.py b/api/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/api/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/api/tests.py b/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/api/views.py b/api/views.py new file mode 100644 index 0000000..733c927 --- /dev/null +++ b/api/views.py @@ -0,0 +1,55 @@ +from django.http import JsonResponse +from django.views.decorators.http import require_http_methods +from django.contrib.auth.decorators import login_required +import subprocess + +@login_required +@require_http_methods(["GET"]) +def wireguard_status(request): + commands = { + 'latest-handshakes': "wg show all latest-handshakes | expand | tr -s ' '", + 'allowed-ips': "wg show all allowed-ips | expand | tr -s ' '", + 'transfer': "wg show all transfer | expand | tr -s ' '", + 'endpoints': "wg show all endpoints | expand | tr -s ' '", + } + + output = {} + + for key, command in commands.items(): + process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + stdout, stderr = process.communicate() + + if process.returncode != 0: + return JsonResponse({'error': stderr}, status=400) + + current_interface = None + for line in stdout.strip().split('\n'): + parts = line.split() + if len(parts) >= 3: + interface, peer, value = parts[0], parts[1], " ".join(parts[2:]) + current_interface = interface + else: + continue + + if interface not in output: + output[interface] = {} + + if peer not in output[interface]: + output[interface][peer] = { + 'allowed-ips': [], + 'latest-handshakes': '', + 'transfer': {'tx': 0, 'rx': 0}, + 'endpoints': '', + } + + if key == 'allowed-ips': + output[interface][peer]['allowed-ips'].append(value) + elif key == 'transfer': + tx, rx = value.split()[-2:] + output[interface][peer]['transfer'] = {'tx': int(tx), 'rx': int(rx)} + elif key == 'endpoints': + output[interface][peer]['endpoints'] = value + else: + output[interface][peer][key] = value + + return JsonResponse(output) diff --git a/templates/base.html b/templates/base.html index 810fa7a..7831c89 100644 --- a/templates/base.html +++ b/templates/base.html @@ -192,7 +192,7 @@ diff --git a/templates/wireguard/welcome.html b/templates/wireguard/welcome.html index 19d1c6c..99b480c 100644 --- a/templates/wireguard/welcome.html +++ b/templates/wireguard/welcome.html @@ -7,10 +7,11 @@

If you encounter any issues or have suggestions, please open an issue on GitHub so I can review it.

TODO list

diff --git a/templates/wireguard/wireguard_peer_list.html b/templates/wireguard/wireguard_peer_list.html index dda9a2c..361703b 100644 --- a/templates/wireguard/wireguard_peer_list.html +++ b/templates/wireguard/wireguard_peer_list.html @@ -19,8 +19,8 @@
{% for peer in peer_list %} -
-
+
+
{% if peer.name %} @@ -34,6 +34,30 @@
{% comment %}This needs to be improved{% endcomment %} +

+ Transfer:
+ Latest Handshake:
+ Endpoints:
+ Allowed IPs: + {% for address in peer.peerallowedip_set.all %}{% if address.priority == 0 %} + {% if address.missing_from_wireguard %} + {{ address }} + {% else %} + {{ address }} + {% endif %} + {% endif %}{% endfor %} + + {% for address in peer.peerallowedip_set.all %}{% if address.priority >= 1 %} + {% if address.missing_from_wireguard %} + {{ address }} + {% else %} + {{ address }} + {% endif %} + {% endif %}{% endfor %} + +

+ + {% comment %}

{% for address in peer.peerallowedip_set.all %}{% if address.priority == 0 %} {% if address.missing_from_wireguard %} {{ address }} @@ -48,7 +72,10 @@ {% else %} {{ address }} {% endif %} - {% endif %}{% endfor %}

+ {% endif %}{% endfor %} +

+ {% endcomment %} +
@@ -95,10 +122,105 @@ {% block custom_page_scripts %} + + + + + + {% endblock %} \ No newline at end of file diff --git a/wireguard_peer/forms.py b/wireguard_peer/forms.py index 7f449e1..1213ac2 100644 --- a/wireguard_peer/forms.py +++ b/wireguard_peer/forms.py @@ -30,6 +30,9 @@ class PeerAllowedIPForm(forms.ModelForm): priority = cleaned_data.get('priority') allowed_ip = cleaned_data.get('allowed_ip') netmask = cleaned_data.get('netmask') + if allowed_ip is None: + raise forms.ValidationError("Please provide a valid IP address.") + wireguard_network = ipaddress.ip_network(f"{self.current_peer.wireguard_instance.address}/{self.current_peer.wireguard_instance.netmask}", strict=False) if priority == 0: diff --git a/wireguard_peer/views.py b/wireguard_peer/views.py index c976eb5..1205cc2 100644 --- a/wireguard_peer/views.py +++ b/wireguard_peer/views.py @@ -119,7 +119,7 @@ def view_wireguard_peer_manage(request): if current_peer.name: page_title += current_peer.name else: - page_title += current_peer.public_key + page_title += current_peer.public_key[:16] + ("..." if len(current_peer.public_key) > 16 else "") if request.method == 'POST': form = PeerForm(request.POST, instance=current_peer) if form.is_valid(): @@ -157,7 +157,7 @@ def view_manage_ip_address(request): if current_peer.name: page_title += current_peer.name else: - page_title += current_peer.public_key + page_title += current_peer.public_key[:10] + ("..." if len(current_peer.public_key) > 16 else "") if request.GET.get('action') == 'delete': if request.GET.get('confirmation') == 'delete': current_ip.delete() diff --git a/wireguard_webadmin/urls.py b/wireguard_webadmin/urls.py index 1d344df..88dcbb9 100644 --- a/wireguard_webadmin/urls.py +++ b/wireguard_webadmin/urls.py @@ -22,6 +22,7 @@ from console.views import view_console from user_manager.views import view_user_list, view_manage_user from accounts.views import view_create_first_user, view_login, view_logout from wireguard_tools.views import export_wireguard_configs, download_config_or_qrcode, restart_wireguard_interfaces +from api.views import wireguard_status urlpatterns = [ @@ -41,4 +42,6 @@ urlpatterns = [ path('accounts/create_first_user/', view_create_first_user, name='create_first_user'), path('accounts/login/', view_login, name='login'), path('accounts/logout/', view_logout, name='logout'), + path('api/wireguard_status/', wireguard_status, name='api_wireguard_status'), + ]