diff --git a/templates/wireguard/wireguard_manage_server.html b/templates/wireguard/wireguard_manage_server.html index 9d9a5ba..eb2bf3f 100644 --- a/templates/wireguard/wireguard_manage_server.html +++ b/templates/wireguard/wireguard_manage_server.html @@ -1,163 +1,68 @@ -{% extends "base.html" %} -{% load i18n %} +{% extends 'base.html' %} +{% load crispy_forms_tags %} {% block content %} - -
- -
-
-
-
- {% csrf_token %} -
-
- -
-
- - -
- -
- - 0 %}readonly{% endif %}> -
- - -
- -
-
- - -
-
- - -
- -
- - -
- -
- -
- {% comment %} -
- - -
- {% endcomment %} -
- -
- -
- -
-
-
- -
- - -
- -
- -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
- -
- - - - -
-
- -
- - -
- -
- - -
-
+
+
+
+ {% if page_title %} +
+

{{ page_title }}

-
-
-
- - - - {% endblock %} - {% block custom_page_scripts %} - - - + + +{% endblock %} diff --git a/wireguard/forms.py b/wireguard/forms.py index aadec0e..35f4fd8 100644 --- a/wireguard/forms.py +++ b/wireguard/forms.py @@ -1,6 +1,10 @@ import ipaddress +from crispy_forms.helper import FormHelper +from crispy_forms.layout import Column, HTML, Layout, Row, Submit from django import forms +from django.conf import settings +from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from wgwadmlibrary.tools import is_valid_ip_or_hostname @@ -16,8 +20,6 @@ class WireGuardInstanceForm(forms.ModelForm): listen_port = forms.IntegerField(label=_('Listen Port')) address = forms.GenericIPAddressField(label=_('Internal IP Address')) netmask = forms.ChoiceField(choices=NETMASK_CHOICES, label=_('Netmask')) - post_up = forms.CharField(label=_('Post Up'), required=False) - post_down = forms.CharField(label=_('Post Down'), required=False) peer_list_refresh_interval = forms.IntegerField(label=_('Web Refresh Interval'), initial=10) dns_primary = forms.GenericIPAddressField(label=_('Primary DNS'), initial='1.1.1.1', required=False) dns_secondary = forms.GenericIPAddressField(label=_('Secondary DNS'), initial='', required=False) @@ -26,40 +28,101 @@ class WireGuardInstanceForm(forms.ModelForm): model = WireGuardInstance fields = [ 'name', 'instance_id', 'private_key', 'public_key','hostname', 'listen_port', 'address', - 'netmask', 'post_up', 'post_down', 'peer_list_refresh_interval', 'dns_primary', 'dns_secondary' + 'netmask', 'peer_list_refresh_interval', 'dns_primary', 'dns_secondary' ] + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + force_cache_refresh = 0 + if hasattr(settings, 'WIREGUARD_STATUS_CACHE_ENABLED') and settings.WIREGUARD_STATUS_CACHE_ENABLED: + if hasattr(settings, 'WIREGUARD_STATUS_CACHE_REFRESH_INTERVAL'): + force_cache_refresh = settings.WIREGUARD_STATUS_CACHE_REFRESH_INTERVAL + + if force_cache_refresh > 0: + self.fields['peer_list_refresh_interval'].initial = force_cache_refresh + self.fields['peer_list_refresh_interval'].widget.attrs['readonly'] = True + self.fields['private_key'].widget = forms.PasswordInput(attrs={'class': 'form-control'}, render_value=True) + + self.helper = FormHelper() + self.helper.form_method = 'post' + + back_label = _("Back") + delete_label = _("Delete") + + if self.instance.pk and not self.instance._state.adding: + delete_html = f"{delete_label}" + else: + delete_html = '' + + + self.helper.layout = Layout( + + Row( + Column( + Row( + Column('name', css_class='form-group col-md-6 mb-0'), + Column('peer_list_refresh_interval', css_class='form-group col-md-6 mb-0'), + css_class='form-row' + ), + Row( + Column('hostname', css_class='form-group col-md-6 mb-0'), + Column('listen_port', css_class='form-group col-md-3 mb-0'), + Column('instance_id', css_class='form-group col-md-3 mb-0'), + css_class='form-row' + ), + Row( + Column('private_key', css_class='form-group col-md-6 mb-0'), + Column('public_key', css_class='form-group col-md-6 mb-0'), + css_class='form-row' + ), + Row( + Column('address', css_class='form-group col-md-6 mb-0'), + Column('netmask', css_class='form-group col-md-6 mb-0'), + css_class='form-row' + ), + Row( + Column('dns_primary', css_class='form-group col-md-6 mb-0'), + Column('dns_secondary', css_class='form-group col-md-6 mb-0'), + css_class='form-row' + ), + css_class='col-lg-12' + ), + css_class='row' + ), + Row( + Column( + Submit('submit', _('Save'), css_class='btn btn-success'), + HTML(f' {back_label} '), + HTML(delete_html), + css_class='col-12' + ), + css_class='row' + ), + ) + def clean(self): cleaned_data = super().clean() hostname = cleaned_data.get('hostname') address = cleaned_data.get('address') netmask = cleaned_data.get('netmask') - post_up = cleaned_data.get('post_up') - post_down = cleaned_data.get('post_down') peer_list_refresh_interval = cleaned_data.get('peer_list_refresh_interval') - if peer_list_refresh_interval < 5: + if peer_list_refresh_interval and peer_list_refresh_interval < 5: raise forms.ValidationError(_('Peer List Refresh Interval must be at least 5 seconds')) - if not is_valid_ip_or_hostname(hostname): + if hostname and not is_valid_ip_or_hostname(hostname): raise forms.ValidationError(_('Invalid hostname or IP Address')) - current_network = ipaddress.ip_network(f"{address}/{netmask}", strict=False) - all_other_instances = WireGuardInstance.objects.all() - if self.instance: - all_other_instances = all_other_instances.exclude(uuid=self.instance.uuid) - for instance in all_other_instances: - other_network = ipaddress.ip_network(f"{instance.address}/{instance.netmask}", strict=False) - if current_network.overlaps(other_network): - raise forms.ValidationError(_('The selected network range overlaps with another instance.')) + if address and netmask: + current_network = ipaddress.ip_network(f"{address}/{netmask}", strict=False) + all_other_instances = WireGuardInstance.objects.all() + if self.instance and self.instance.pk: + all_other_instances = all_other_instances.exclude(uuid=self.instance.uuid) + for instance in all_other_instances: + other_network = ipaddress.ip_network(f"{instance.address}/{instance.netmask}", strict=False) + if current_network.overlaps(other_network): + raise forms.ValidationError(_('The selected network range overlaps with another instance.')) - #if self.instance: - # if post_up or post_down: - # if self.instance.post_up != post_up or self.instance.post_down != post_down: - # raise forms.ValidationError('Post Up and Post Down cannot be changed, please go to Firewall page to make changes to the firewall.') - #else: - # if post_up or post_down: - # raise forms.ValidationError('Post Up and Post Down cannot be set, please go to Firewall page to make changes to the firewall.') - return cleaned_data diff --git a/wireguard/views.py b/wireguard/views.py index 011f71f..5365f82 100644 --- a/wireguard/views.py +++ b/wireguard/views.py @@ -139,7 +139,7 @@ def view_wireguard_manage_instance(request): return redirect('/server/manage/?uuid=' + str(current_instance.uuid)) current_instance.delete() messages.success(request, message_title + _('|WireGuard instance deleted: wg') + str(current_instance.instance_id)) - return redirect('/server/manage/') + return redirect('/server/list/') else: messages.warning(request, _('Invalid confirmation|Please confirm deletion of WireGuard instance: wg') + str(current_instance.instance_id)) return redirect('/server/manage/?uuid=' + str(current_instance.uuid)) @@ -165,7 +165,17 @@ def view_wireguard_manage_instance(request): force_cache_refresh = settings.WIREGUARD_STATUS_CACHE_REFRESH_INTERVAL else: force_cache_refresh = 0 - context = {'page_title': page_title, 'wireguard_instances': wireguard_instances, 'current_instance': current_instance, 'form': form, 'force_cache_refresh': force_cache_refresh} + + # Passing 'instance' and 'delete_confirmation_message' for generic_form compatibility + context = { + 'page_title': page_title, + 'wireguard_instances': wireguard_instances, + 'current_instance': current_instance, + 'instance': current_instance, + 'form': form, + 'force_cache_refresh': force_cache_refresh, + 'delete_confirmation_message': 'Please type delete wg' + str(current_instance.instance_id) + ' to remove the configuration.' if current_instance else None + } return render(request, 'wireguard/wireguard_manage_server.html', context)