From 5b21f24b7c2b1091d726eaf2a27a77f2ca8c6525 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Mon, 26 Jan 2026 13:57:31 -0300 Subject: [PATCH] Update peer management view and forms. --- .../wireguard/wireguard_manage_peer.html | 160 +++++++----------- wireguard_peer/forms.py | 43 ++++- wireguard_peer/views.py | 72 +++++--- wireguard_webadmin/urls.py | 3 +- 4 files changed, 152 insertions(+), 126 deletions(-) diff --git a/templates/wireguard/wireguard_manage_peer.html b/templates/wireguard/wireguard_manage_peer.html index c2925c3..81f124d 100644 --- a/templates/wireguard/wireguard_manage_peer.html +++ b/templates/wireguard/wireguard_manage_peer.html @@ -7,43 +7,65 @@

{% trans 'Peer Configuration' %}

-
- {% csrf_token %} -
+
+
-
- - -
- - -
- - -
- - -
- - -
- - -
- -
- -
- -
+
+ +
+ {{ current_peer.name|default:"-" }} + + +
- + +
+ +
+ {{ current_peer.persistent_keepalive }} + + + +
+
+ +
- - +
+ + + + +
+ +
+
{% trans 'Public Key' %}
+
{{ current_peer.public_key }}
+ +
{% trans 'Private Key' %}
+
+ {% if current_peer.private_key %} + ******************************************** + {% else %} + {% trans 'Not set' %} + {% endif %} +
+ +
{% trans 'Pre-Shared Key' %}
+
+ {% if current_peer.pre_shared_key %} + ******************************************** + {% else %} + {% trans 'Not set' %} + {% endif %} +
+
@@ -197,45 +219,16 @@
- - +
+
{% endblock %} {% block custom_page_scripts %} - - - - - - - - - -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/wireguard_peer/forms.py b/wireguard_peer/forms.py index bdd914a..cce63d8 100644 --- a/wireguard_peer/forms.py +++ b/wireguard_peer/forms.py @@ -1,21 +1,56 @@ import ipaddress +from crispy_forms.bootstrap import FormActions +from crispy_forms.helper import FormHelper +from crispy_forms.layout import Layout, Submit, Button from django import forms +from django.core.validators import MinValueValidator, MaxValueValidator from django.utils.translation import gettext_lazy as _ from wireguard.models import NETMASK_CHOICES, Peer, PeerAllowedIP -class PeerForm(forms.ModelForm): +class PeerModelForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper() + self.helper.form_method = 'post' + self.helper.layout = Layout( + *self.Meta.fields, + FormActions( + Submit('save', _('Save'), css_class='btn-primary'), + Button('cancel', _('Back'), css_class='btn-outline-secondary', onclick='window.history.back()') + ) + ) + +class PeerNameForm(PeerModelForm): name = forms.CharField(label=_('Name'), required=False) + + class Meta: + model = Peer + fields = ['name'] + + +class PeerKeepaliveForm(PeerModelForm): + persistent_keepalive = forms.IntegerField( + label=_('Persistent Keepalive'), + required=True, + validators=[MinValueValidator(1), MaxValueValidator(3600)], + ) + + class Meta: + model = Peer + fields = ['persistent_keepalive'] + + +class PeerKeysForm(PeerModelForm): public_key = forms.CharField(label=_('Public Key'), required=True) private_key = forms.CharField(label=_('Private Key'), required=False) pre_shared_key = forms.CharField(label=_('Pre-Shared Key'), required=True) - persistent_keepalive = forms.IntegerField(label=_('Persistent Keepalive'), required=True) - + class Meta: model = Peer - fields = ['name', 'public_key', 'private_key', 'pre_shared_key', 'persistent_keepalive'] + fields = ['public_key', 'private_key', 'pre_shared_key'] class PeerAllowedIPForm(forms.ModelForm): diff --git a/wireguard_peer/views.py b/wireguard_peer/views.py index fdc88ed..6470c54 100644 --- a/wireguard_peer/views.py +++ b/wireguard_peer/views.py @@ -14,7 +14,7 @@ from user_manager.models import UserAcl from wgwadmlibrary.tools import check_sort_order_conflict, deduplicate_sort_order, default_sort_peers, \ user_allowed_instances, user_allowed_peers, user_has_access_to_instance, user_has_access_to_peer from wireguard.models import Peer, PeerAllowedIP, WireGuardInstance -from wireguard_peer.forms import PeerAllowedIPForm, PeerForm +from wireguard_peer.forms import PeerAllowedIPForm, PeerNameForm, PeerKeepaliveForm, PeerKeysForm def generate_peer_default(wireguard_instance): @@ -184,12 +184,8 @@ def view_wireguard_peer_create(request): @login_required def view_wireguard_peer_manage(request): - if request.method == 'POST': - if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=30).exists(): - return render(request, 'access_denied.html', {'page_title': 'Access Denied'}) - else: - if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=20).exists(): - return render(request, 'access_denied.html', {'page_title': 'Access Denied'}) + if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=20).exists(): + return render(request, 'access_denied.html', {'page_title': 'Access Denied'}) user_acl = get_object_or_404(UserAcl, user=request.user) current_peer = get_object_or_404(Peer, uuid=request.GET.get('peer')) @@ -197,6 +193,8 @@ def view_wireguard_peer_manage(request): raise Http404 current_instance = current_peer.wireguard_instance if request.GET.get('action') == 'delete': + if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=30).exists(): + return render(request, 'access_denied.html', {'page_title': 'Access Denied'}) if request.GET.get('confirmation') == 'delete': current_peer.wireguard_instance.pending_changes = True current_peer.wireguard_instance.save() @@ -206,28 +204,62 @@ def view_wireguard_peer_manage(request): else: messages.warning(request, _('Error deleting peer|Invalid confirmation message. Type "delete" to confirm.')) return redirect('/peer/manage/?peer=' + str(current_peer.uuid)) - page_title = _('Update Peer: ') + str(current_peer) + page_title = _('Peer Configuration: ') + str(current_peer) peer_ip_list = current_peer.peerallowedip_set.filter(config_file='server').order_by('priority') peer_client_ip_list = current_peer.peerallowedip_set.filter(config_file='client').order_by('priority') - if request.method == 'POST': - form = PeerForm(request.POST, instance=current_peer) - if form.is_valid(): - form.save() - messages.success(request, _('Peer updated|Peer updated successfully.')) - current_peer.wireguard_instance.pending_changes = True - current_peer.wireguard_instance.save() - return redirect('/peer/list/?uuid=' + str(current_peer.wireguard_instance.uuid)) - else: - form = PeerForm(instance=current_peer) - context = { - 'page_title': page_title, 'current_instance': current_instance, 'current_peer': current_peer, 'form': form, + 'page_title': page_title, 'current_instance': current_instance, 'current_peer': current_peer, 'peer_ip_list': peer_ip_list, 'peer_client_ip_list': peer_client_ip_list } return render(request, 'wireguard/wireguard_manage_peer.html', context) +@login_required +def view_wireguard_peer_edit_field(request): + if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=30).exists(): + return render(request, 'access_denied.html', {'page_title': 'Access Denied'}) + user_acl = get_object_or_404(UserAcl, user=request.user) + + current_peer = get_object_or_404(Peer, uuid=request.GET.get('peer')) + if not user_has_access_to_peer(user_acl, current_peer): + raise Http404 + + group = request.GET.get('group') + form_classes = { + 'name': PeerNameForm, + 'keepalive': PeerKeepaliveForm, + 'keys': PeerKeysForm + } + + if group not in form_classes: + raise Http404 + + FormClass = form_classes[group] + + form = FormClass(request.POST or None, instance=current_peer) + if form.is_valid(): + form.save() + current_peer.wireguard_instance.pending_changes = True + current_peer.wireguard_instance.save() + messages.success(request, _('Peer updated|Peer updated successfully.')) + return redirect('/peer/manage/?peer=' + str(current_peer.uuid)) + + page_title = _('Edit Peer') + if group == 'name': + page_title = _('Edit Peer Name') + elif group == 'keepalive': + page_title = _('Edit Keepalive') + elif group == 'keys': + page_title = _('Edit Keys') + + context = { + 'page_title': page_title, + 'form': form, + } + return render(request, 'generic_form.html', context) + + def view_manage_ip_address(request): if not UserAcl.objects.filter(user=request.user).filter(user_level__gte=30).exists(): return render(request, 'access_denied.html', {'page_title': 'Access Denied'}) diff --git a/wireguard_webadmin/urls.py b/wireguard_webadmin/urls.py index d627973..721b798 100644 --- a/wireguard_webadmin/urls.py +++ b/wireguard_webadmin/urls.py @@ -39,7 +39,7 @@ from wgrrd.views import view_rrd_graph from wireguard.views import view_apply_db_patches, view_wireguard_manage_instance, view_wireguard_status, \ view_server_list, view_server_detail from wireguard_peer.views import view_manage_ip_address, view_wireguard_peer_list, view_wireguard_peer_manage, \ - view_wireguard_peer_sort, view_apply_route_template, view_wireguard_peer_create + view_wireguard_peer_sort, view_apply_route_template, view_wireguard_peer_create, view_wireguard_peer_edit_field from wireguard_tools.views import download_config_or_qrcode, export_wireguard_configs, restart_wireguard_interfaces urlpatterns = [ @@ -57,6 +57,7 @@ urlpatterns = [ path('peer/sort/', view_wireguard_peer_sort, name='wireguard_peer_sort'), path('peer/manage/', view_wireguard_peer_manage, name='wireguard_peer_manage'), path('peer/create/', view_wireguard_peer_create, name='wireguard_peer_create'), + path('peer/edit/', view_wireguard_peer_edit_field, name='wireguard_peer_edit_field'), path('peer/apply_route_template/', view_apply_route_template, name='apply_route_template'), path('peer/manage_ip_address/', view_manage_ip_address, name='manage_ip_address'), path('rrd/graph/', view_rrd_graph, name='rrd_graph'),