mirror of
https://github.com/eduardogsilva/wireguard_webadmin.git
synced 2025-06-23 02:09:06 +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 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.views.decorators.http import require_http_methods
|
||||
from django.http import HttpResponseForbidden
|
||||
|
@ -10,7 +12,7 @@ from django.utils import timezone
|
|||
|
||||
from user_manager.models import UserAcl, AuthenticationToken
|
||||
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 subprocess
|
||||
import datetime
|
||||
|
@ -112,6 +114,22 @@ def routerfleet_get_user_token(request):
|
|||
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"])
|
||||
def wireguard_status(request):
|
||||
user_acl = None
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
{% block content %}
|
||||
{% if wireguard_instances %}
|
||||
<div class="card card-primary card-outline">
|
||||
|
||||
<div class="card-body">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
{% for wgconf in wireguard_instances %}
|
||||
|
@ -13,7 +12,6 @@
|
|||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
</ul>
|
||||
<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">
|
||||
|
@ -22,74 +20,96 @@
|
|||
<div class="col-md-6" id="peer-{{ peer.public_key }}">
|
||||
<div class="callout">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<h5>
|
||||
{% if peer.name %}
|
||||
{{ peer.name}}
|
||||
{% else %}
|
||||
{{ peer.public_key|slice:":16" }}{% if peer.public_key|length > 16 %}...{% endif %}
|
||||
{% endif %}
|
||||
</h5>
|
||||
<h5><a href="#" onclick="openPeerModal('{{ peer.uuid }}');" style="text-decoration: none">{{ peer }}</a></h5>
|
||||
<span>
|
||||
{% if user_acl.user_level >= 30 %}
|
||||
<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">
|
||||
<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>
|
||||
{% 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="/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>
|
||||
<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="/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>
|
||||
|
||||
</div>
|
||||
{% comment %}This needs to be improved{% endcomment %}
|
||||
<p>
|
||||
<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>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 %}
|
||||
{% if address.priority == 0 and address.config_file == 'server' %}{{ address }}{% endif %}
|
||||
{% if address.priority == 0 and address.config_file == 'server' %}
|
||||
{{ address }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% 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 %}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
{% if add_peer_enabled %}
|
||||
<a class="btn btn-primary" href="/peer/manage/?instance={{ current_instance.uuid }}">Create Peer</a>
|
||||
{% else %}
|
||||
<a class="btn btn-primary disabled" href="">Create Peer</a>
|
||||
{% 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>
|
||||
|
||||
<!-- 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>
|
||||
<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 %}
|
||||
|
||||
<div class="alert alert-warning" role="alert">
|
||||
<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>
|
||||
|
@ -98,14 +118,44 @@
|
|||
<a href="/server/manage/" class="btn btn-primary">Add WireGuard Instance</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% 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>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
//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 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, 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 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
|
||||
|
@ -55,6 +55,7 @@ urlpatterns = [
|
|||
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/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_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'),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue