mirror of
https://github.com/eduardogsilva/wireguard_webadmin.git
synced 2025-06-23 10:18:57 +02:00
Add peer info API endpoint and modal preview
This commit is contained in:
parent
d8c6bee57a
commit
1a68ad1344
3 changed files with 120 additions and 51 deletions
22
api/views.py
22
api/views.py
|
@ -1,6 +1,8 @@
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.http import JsonResponse
|
from django.core.exceptions import PermissionDenied
|
||||||
|
from django.http import JsonResponse, Http404
|
||||||
from django.shortcuts import get_object_or_404, redirect
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
from django.views.decorators.http import require_http_methods
|
from django.views.decorators.http import require_http_methods
|
||||||
from django.http import HttpResponseForbidden
|
from django.http import HttpResponseForbidden
|
||||||
|
@ -10,7 +12,7 @@ from django.utils import timezone
|
||||||
|
|
||||||
from user_manager.models import UserAcl, AuthenticationToken
|
from user_manager.models import UserAcl, AuthenticationToken
|
||||||
from wireguard.models import WebadminSettings, Peer, PeerStatus, WireGuardInstance
|
from wireguard.models import WebadminSettings, Peer, PeerStatus, WireGuardInstance
|
||||||
from wgwadmlibrary.tools import user_allowed_peers
|
from wgwadmlibrary.tools import user_allowed_peers, user_has_access_to_peer
|
||||||
import requests
|
import requests
|
||||||
import subprocess
|
import subprocess
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -112,6 +114,22 @@ def routerfleet_get_user_token(request):
|
||||||
return JsonResponse(data)
|
return JsonResponse(data)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def peer_info(request):
|
||||||
|
peer = get_object_or_404(Peer, uuid=request.GET.get('uuid'))
|
||||||
|
user_acl = get_object_or_404(UserAcl, user=request.user)
|
||||||
|
|
||||||
|
if not user_has_access_to_peer(user_acl, peer):
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'name': str(peer),
|
||||||
|
'public_key': str(peer.public_key),
|
||||||
|
'uuid': str(peer.uuid),
|
||||||
|
}
|
||||||
|
return JsonResponse(data)
|
||||||
|
|
||||||
|
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def wireguard_status(request):
|
def wireguard_status(request):
|
||||||
user_acl = None
|
user_acl = None
|
||||||
|
|
|
@ -3,17 +3,15 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if wireguard_instances %}
|
{% if wireguard_instances %}
|
||||||
<div class="card card-primary card-outline">
|
<div class="card card-primary card-outline">
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<ul class="nav nav-tabs" role="tablist">
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
{% for wgconf in wireguard_instances %}
|
{% for wgconf in wireguard_instances %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link {%if wgconf == current_instance%}active{%endif%}" href="/peer/list/?uuid={{wgconf.uuid}}" role="tab" >
|
<a class="nav-link {% if wgconf == current_instance %}active{% endif %}" href="/peer/list/?uuid={{ wgconf.uuid }}" role="tab">
|
||||||
wg{{wgconf.instance_id}} {%if wgconf.name %}({{wgconf.name}}){%endif%}
|
wg{{ wgconf.instance_id }} {% if wgconf.name %}({{ wgconf.name }}){% endif %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<div class="tab-content" id="custom-content-below-tabContent">
|
<div class="tab-content" id="custom-content-below-tabContent">
|
||||||
<div class="tab-pane fade show active" id="custom-content-below-home" role="tabpanel" aria-labelledby="custom-content-below-home-tab">
|
<div class="tab-pane fade show active" id="custom-content-below-home" role="tabpanel" aria-labelledby="custom-content-below-home-tab">
|
||||||
|
@ -22,74 +20,96 @@
|
||||||
<div class="col-md-6" id="peer-{{ peer.public_key }}">
|
<div class="col-md-6" id="peer-{{ peer.public_key }}">
|
||||||
<div class="callout">
|
<div class="callout">
|
||||||
<div class="d-flex justify-content-between align-items-start">
|
<div class="d-flex justify-content-between align-items-start">
|
||||||
<h5>
|
<h5><a href="#" onclick="openPeerModal('{{ peer.uuid }}');" style="text-decoration: none">{{ peer }}</a></h5>
|
||||||
{% if peer.name %}
|
|
||||||
{{ peer.name}}
|
|
||||||
{% else %}
|
|
||||||
{{ peer.public_key|slice:":16" }}{% if peer.public_key|length > 16 %}...{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
</h5>
|
|
||||||
<span>
|
<span>
|
||||||
{% if user_acl.user_level >= 30 %}
|
{% if user_acl.user_level >= 30 %}
|
||||||
<div class="d-inline-flex flex-column">
|
<div class="d-inline-flex flex-column">
|
||||||
<a href="/peer/sort/?peer={{ peer.uuid }}&direction=up" style="line-height:0px"><i class="fas fa-sort-up"></i></a>
|
<a href="/peer/sort/?peer={{ peer.uuid }}&direction=up" style="line-height:0px">
|
||||||
|
<i class="fas fa-sort-up"></i>
|
||||||
|
</a>
|
||||||
<div style="overflow:hidden;margin-top: -9px">
|
<div style="overflow:hidden;margin-top: -9px">
|
||||||
<a href="/peer/sort/?peer={{ peer.uuid }}&direction=down" style="position:relative;top:-11px"><i class="fas fa-sort-down"></i></a>
|
<a href="/peer/sort/?peer={{ peer.uuid }}&direction=down" style="position:relative;top:-11px">
|
||||||
|
<i class="fas fa-sort-down"></i>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="javascript:void(0);" onclick="openImageLightbox('/tools/download_peer_config/?uuid={{ peer.uuid }}&format=qrcode');"><i class="fas fa-qrcode"></i></a>
|
<a href="javascript:void(0);" onclick="openImageLightbox('/tools/download_peer_config/?uuid={{ peer.uuid }}&format=qrcode');">
|
||||||
<a href="/tools/download_peer_config/?uuid={{ peer.uuid }}"><i class="fas fa-download"></i></a>
|
<i class="fas fa-qrcode"></i>
|
||||||
<a href="/peer/manage/?peer={{ peer.uuid }}"><i class="far fa-edit"></i></a>
|
</a>
|
||||||
|
<a href="/tools/download_peer_config/?uuid={{ peer.uuid }}">
|
||||||
|
<i class="fas fa-download"></i>
|
||||||
|
</a>
|
||||||
|
<a href="/peer/manage/?peer={{ peer.uuid }}">
|
||||||
|
<i class="far fa-edit"></i>
|
||||||
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% comment %}This needs to be improved{% endcomment %}
|
|
||||||
<p>
|
<p>
|
||||||
<b>Transfer:</b> <span id="peer-transfer-{{ peer.public_key }}"></span><br>
|
<b>Transfer:</b> <span id="peer-transfer-{{ peer.public_key }}"></span><br>
|
||||||
<b>Latest Handshake:</b> <span id="peer-latest-handshake-{{ peer.public_key }}"></span> <span style="display: none;" id="peer-stored-latest-handshake-{{ peer.public_key }}">{% if peer.peerstatus.last_handshake %}{{ peer.peerstatus.last_handshake|date:"U" }}{% else %}0{% endif %}</span><br>
|
<b>Latest Handshake:</b> <span id="peer-latest-handshake-{{ peer.public_key }}"></span>
|
||||||
|
<span style="display: none;" id="peer-stored-latest-handshake-{{ peer.public_key }}">
|
||||||
|
{% if peer.peerstatus.last_handshake %}{{ peer.peerstatus.last_handshake|date:"U" }}{% else %}0{% endif %}
|
||||||
|
</span><br>
|
||||||
<b>Endpoints:</b> <span id="peer-endpoints-{{ peer.public_key }}"></span><br>
|
<b>Endpoints:</b> <span id="peer-endpoints-{{ peer.public_key }}"></span><br>
|
||||||
<b>Allowed IPs: </b><span id="peer-allowed-ips-{{ peer.public_key }}">
|
<b>Allowed IPs:</b>
|
||||||
|
<span id="peer-allowed-ips-{{ peer.public_key }}">
|
||||||
{% for address in peer.peerallowedip_set.all %}
|
{% for address in peer.peerallowedip_set.all %}
|
||||||
{% if address.priority == 0 and address.config_file == 'server' %}{{ address }}{% endif %}
|
{% if address.priority == 0 and address.config_file == 'server' %}
|
||||||
|
{{ address }}
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for address in peer.peerallowedip_set.all %}
|
{% for address in peer.peerallowedip_set.all %}
|
||||||
{% if address.priority >= 1 and address.config_file == 'server' %}{{ address }}{% endif %}
|
{% if address.priority >= 1 and address.config_file == 'server' %}
|
||||||
|
{{ address }}
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if add_peer_enabled %}
|
{% if add_peer_enabled %}
|
||||||
<a class="btn btn-primary" href="/peer/manage/?instance={{ current_instance.uuid}}">Create Peer</a>
|
<a class="btn btn-primary" href="/peer/manage/?instance={{ current_instance.uuid }}">Create Peer</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="btn btn-primary disabled" href="">Create Peer</a>
|
<a class="btn btn-primary disabled" href="">Create Peer</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% comment %}<a class="btn btn-outline-primary disabled" href="/peer/import_peers/?instance={{ current_instance.uuid}}" title='teste'>Import peers</a>{% endcomment %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
function openCommandDialog(element) {
|
|
||||||
var command = element.getAttribute('data-command');
|
|
||||||
var confirmation = prompt("Please type 'delete wg{{ current_instance.instance_id }}' to remove the configuration.");
|
|
||||||
if (confirmation) {
|
|
||||||
var url = "?uuid={{current_instance.uuid}}&action=delete&confirmation=" + encodeURIComponent(confirmation);
|
|
||||||
window.location.href = url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
{% else %}
|
|
||||||
|
|
||||||
|
<!-- Peer Preview Modal -->
|
||||||
|
<div class="modal fade" id="peerPreviewModal" tabindex="-1" aria-labelledby="peerPreviewModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="peerPreviewModalLabel">Peer Preview</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<!-- Peer Information -->
|
||||||
|
<h3 id="peerName">Peer Name Placeholder</h3>
|
||||||
|
<p><b>Transfer:</b> <span id="peerTransfer">--</span></p>
|
||||||
|
<p><b>Latest Handshake:</b> <span id="peerHandshake">--</span></p>
|
||||||
|
<p><b>Endpoints:</b> <span id="peerEndpoints">--</span></p>
|
||||||
|
<p><b>Allowed IPs:</b> <span id="peerAllowedIPs">--</span></p>
|
||||||
|
<!-- Consumption graph placeholder -->
|
||||||
|
<div>
|
||||||
|
<canvas id="peerGraph" width="400" height="200"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||||
|
<a href="#" class="btn btn-primary" id="editPeerButton">Edit</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
<div class="alert alert-warning" role="alert">
|
<div class="alert alert-warning" role="alert">
|
||||||
<h4 class="alert-heading">No WireGuard Instances Found</h4>
|
<h4 class="alert-heading">No WireGuard Instances Found</h4>
|
||||||
<p>There are no WireGuard instances configured. You can add a new instance by clicking the button below.</p>
|
<p>There are no WireGuard instances configured. You can add a new instance by clicking the button below.</p>
|
||||||
|
@ -98,14 +118,44 @@
|
||||||
<a href="/server/manage/" class="btn btn-primary">Add WireGuard Instance</a>
|
<a href="/server/manage/" class="btn btn-primary">Add WireGuard Instance</a>
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
{% block custom_page_scripts %}
|
{% block custom_page_scripts %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Function to open the peer preview modal and fetch its details
|
||||||
|
function openPeerModal(uuid) {
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/peer_info/',
|
||||||
|
data: { uuid: uuid },
|
||||||
|
type: 'GET',
|
||||||
|
dataType: 'json',
|
||||||
|
success: function(data) {
|
||||||
|
// Update modal placeholders with fetched data
|
||||||
|
$('#peerName').text(data.name || 'Unnamed Peer');
|
||||||
|
if (data.transfer) {
|
||||||
|
$('#peerTransfer').text(convertBytes(data.transfer.tx) + ' TX, ' + convertBytes(data.transfer.rx) + ' RX');
|
||||||
|
} else {
|
||||||
|
$('#peerTransfer').text('--');
|
||||||
|
}
|
||||||
|
$('#peerHandshake').text(data.latest_handshake ? new Date(parseInt(data.latest_handshake) * 1000).toLocaleString() : '--');
|
||||||
|
$('#peerEndpoints').text(data.endpoints || '--');
|
||||||
|
$('#peerAllowedIPs').text(data.allowed_ips || '--');
|
||||||
|
|
||||||
|
// Update the Edit button URL
|
||||||
|
$('#editPeerButton').attr('href', '/peer/manage/?peer=' + uuid);
|
||||||
|
|
||||||
|
// Open the modal
|
||||||
|
$('#peerPreviewModal').modal('show');
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.error("Error fetching peer info:", error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
//const fetchWireguardStatus = async () => {
|
//const fetchWireguardStatus = async () => {
|
||||||
|
|
|
@ -22,7 +22,7 @@ from console.views import view_console
|
||||||
from user_manager.views import view_user_list, view_manage_user, view_peer_group_list, view_peer_group_manage
|
from user_manager.views import view_user_list, view_manage_user, view_peer_group_list, view_peer_group_manage
|
||||||
from accounts.views import view_create_first_user, view_login, view_logout
|
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 wireguard_tools.views import export_wireguard_configs, download_config_or_qrcode, restart_wireguard_interfaces
|
||||||
from api.views import wireguard_status, cron_check_updates, cron_update_peer_latest_handshake, routerfleet_get_user_token, routerfleet_authenticate_session
|
from api.views import wireguard_status, cron_check_updates, cron_update_peer_latest_handshake, routerfleet_get_user_token, routerfleet_authenticate_session, peer_info
|
||||||
from firewall.views import view_redirect_rule_list, manage_redirect_rule, view_firewall_rule_list, manage_firewall_rule, view_manage_firewall_settings, view_generate_iptables_script, view_reset_firewall, view_firewall_migration_required
|
from firewall.views import view_redirect_rule_list, manage_redirect_rule, view_firewall_rule_list, manage_firewall_rule, view_manage_firewall_settings, view_generate_iptables_script, view_reset_firewall, view_firewall_migration_required
|
||||||
from dns.views import view_static_host_list, view_manage_static_host, view_manage_dns_settings, view_apply_dns_config
|
from dns.views import view_static_host_list, view_manage_static_host, view_manage_dns_settings, view_apply_dns_config
|
||||||
from wgrrd.views import view_rrd_graph
|
from wgrrd.views import view_rrd_graph
|
||||||
|
@ -55,6 +55,7 @@ urlpatterns = [
|
||||||
path('accounts/routerfleet_authenticate_session/', routerfleet_authenticate_session, name='routerfleet_authenticate_session'),
|
path('accounts/routerfleet_authenticate_session/', routerfleet_authenticate_session, name='routerfleet_authenticate_session'),
|
||||||
path('api/routerfleet_get_user_token/', routerfleet_get_user_token, name='routerfleet_get_user_token'),
|
path('api/routerfleet_get_user_token/', routerfleet_get_user_token, name='routerfleet_get_user_token'),
|
||||||
path('api/wireguard_status/', wireguard_status, name='api_wireguard_status'),
|
path('api/wireguard_status/', wireguard_status, name='api_wireguard_status'),
|
||||||
|
path('api/peer_info/', peer_info, name='api_peer_info'),
|
||||||
path('api/cron_check_updates/', cron_check_updates, name='cron_check_updates'),
|
path('api/cron_check_updates/', cron_check_updates, name='cron_check_updates'),
|
||||||
path('api/cron_update_peer_latest_handshake/', cron_update_peer_latest_handshake, name='cron_update_peer_latest_handshake'),
|
path('api/cron_update_peer_latest_handshake/', cron_update_peer_latest_handshake, name='cron_update_peer_latest_handshake'),
|
||||||
path('firewall/port_forward/', view_redirect_rule_list, name='redirect_rule_list'),
|
path('firewall/port_forward/', view_redirect_rule_list, name='redirect_rule_list'),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue