mirror of
https://github.com/eduardogsilva/wireguard_webadmin.git
synced 2025-06-28 01:07:03 +00:00
FirewallRuleForm validations
This commit is contained in:
parent
2012c22973
commit
015d9b0927
@ -53,44 +53,68 @@ class RedirectRuleForm(forms.ModelForm):
|
||||
|
||||
|
||||
class FirewallRuleForm(forms.ModelForm):
|
||||
firewall_settings, firewall_settings_created = FirewallSettings.objects.get_or_create(name='global')
|
||||
interface_list = [('', '------'),]
|
||||
interface_list.append((firewall_settings.wan_interface, firewall_settings.wan_interface + ' (WAN)'))
|
||||
def __init__(self, *args, **kwargs):
|
||||
current_chain = kwargs.pop('current_chain', None)
|
||||
super(FirewallRuleForm, self).__init__(*args, **kwargs)
|
||||
|
||||
for wireguard_instance in WireGuardInstance.objects.all().order_by('instance_id'):
|
||||
wireguard_instance_interface = 'wg'+ str(wireguard_instance.instance_id)
|
||||
interface_list.append((wireguard_instance_interface, wireguard_instance_interface))
|
||||
firewall_settings, firewall_settings_created = FirewallSettings.objects.get_or_create(name='global')
|
||||
interface_list = [('', '------'),]
|
||||
interface_list.append((firewall_settings.wan_interface, firewall_settings.wan_interface + ' (WAN)'))
|
||||
|
||||
interface_list.append(('wg+', 'wg+ (Any WireGuard Interface)'))
|
||||
for wireguard_instance in WireGuardInstance.objects.all().order_by('instance_id'):
|
||||
wireguard_instance_interface = 'wg'+ str(wireguard_instance.instance_id)
|
||||
interface_list.append((wireguard_instance_interface, wireguard_instance_interface))
|
||||
|
||||
description = forms.CharField(label='Description', required=False)
|
||||
firewall_chain = forms.ChoiceField(label='Firewall Chain', choices=[('forward', 'FORWARD'), ('postrouting', 'POSTROUTING (nat)')], initial='forward')
|
||||
in_interface = forms.ChoiceField(label='In Interface', choices=interface_list, required=False)
|
||||
out_interface = forms.ChoiceField(label='Out Interface', choices=interface_list, required=False)
|
||||
source_ip = forms.GenericIPAddressField(label='Source IP', required=False)
|
||||
source_netmask = forms.IntegerField(label='Source Netmask', initial=32, min_value=0, max_value=32)
|
||||
source_peer = forms.ModelMultipleChoiceField(label='Source Peer', queryset=Peer.objects.all(), required=False)
|
||||
source_peer_include_networks = forms.BooleanField(label='Source Peer Include Networks', required=False)
|
||||
not_source = forms.BooleanField(label='Not Source', required=False)
|
||||
destination_ip = forms.GenericIPAddressField(label='Destination IP', required=False)
|
||||
destination_netmask = forms.IntegerField(label='Destination Netmask', initial=32, min_value=0, max_value=32)
|
||||
destination_peer = forms.ModelMultipleChoiceField(label='Destination Peer', queryset=Peer.objects.all(), required=False)
|
||||
destination_peer_include_networks = forms.BooleanField(label='Destination Peer Include Networks', required=False)
|
||||
not_destination = forms.BooleanField(label='Not Destination', required=False)
|
||||
protocol = forms.ChoiceField(label='Protocol', choices=[('', 'all'), ('tcp', 'TCP'), ('udp', 'UDP'), ('both', 'TCP+UDP'), ('icmp', 'ICMP')], required=False)
|
||||
destination_port = forms.CharField(label='Destination Port', required=False)
|
||||
state_new = forms.BooleanField(label='State NEW', required=False)
|
||||
state_related = forms.BooleanField(label='State RELATED', required=False)
|
||||
state_established = forms.BooleanField(label='State ESTABLISHED', required=False)
|
||||
state_invalid = forms.BooleanField(label='State INVALID', required=False)
|
||||
state_untracked = forms.BooleanField(label='State UNTRACKED', required=False)
|
||||
not_state = forms.BooleanField(label='Not State', required=False)
|
||||
rule_action = forms.ChoiceField(label='Rule Action', initial='accept', choices=[('accept', 'ACCEPT'), ('reject', 'REJECT'), ('drop', 'DROP'), ('masquerade', 'MASQUERADE')])
|
||||
sort_order = forms.IntegerField(label='Sort Order', initial=0, min_value=0)
|
||||
interface_list.append(('wg+', 'wg+ (Any WireGuard Interface)'))
|
||||
|
||||
description = forms.CharField(label='Description', required=False)
|
||||
firewall_chain = forms.ChoiceField(label='Firewall Chain', choices=[('forward', 'FORWARD'), ('postrouting', 'POSTROUTING (nat)')])
|
||||
in_interface = forms.ChoiceField(label='In Interface', required=False)
|
||||
out_interface = forms.ChoiceField(label='Out Interface', required=False)
|
||||
source_ip = forms.GenericIPAddressField(label='Source IP', required=False)
|
||||
source_netmask = forms.IntegerField(label='Source Netmask', initial=32, min_value=0, max_value=32)
|
||||
source_peer = forms.ModelMultipleChoiceField(label='Source Peer', queryset=Peer.objects.all(), required=False)
|
||||
source_peer_include_networks = forms.BooleanField(label='Source Peer Include Networks', required=False)
|
||||
not_source = forms.BooleanField(label='Not Source', required=False)
|
||||
destination_ip = forms.GenericIPAddressField(label='Destination IP', required=False)
|
||||
destination_netmask = forms.IntegerField(label='Destination Netmask', initial=32, min_value=0, max_value=32)
|
||||
destination_peer = forms.ModelMultipleChoiceField(label='Destination Peer', queryset=Peer.objects.all(), required=False)
|
||||
destination_peer_include_networks = forms.BooleanField(label='Destination Peer Include Networks', required=False)
|
||||
not_destination = forms.BooleanField(label='Not Destination', required=False)
|
||||
protocol = forms.ChoiceField(label='Protocol', choices=[('', 'all'), ('tcp', 'TCP'), ('udp', 'UDP'), ('both', 'TCP+UDP'), ('icmp', 'ICMP')], required=False)
|
||||
destination_port = forms.CharField(label='Destination Port', required=False)
|
||||
state_new = forms.BooleanField(label='State NEW', required=False)
|
||||
state_related = forms.BooleanField(label='State RELATED', required=False)
|
||||
state_established = forms.BooleanField(label='State ESTABLISHED', required=False)
|
||||
state_invalid = forms.BooleanField(label='State INVALID', required=False)
|
||||
state_untracked = forms.BooleanField(label='State UNTRACKED', required=False)
|
||||
not_state = forms.BooleanField(label='Not State', required=False)
|
||||
rule_action = forms.ChoiceField(label='Rule Action', initial='accept', choices=[('accept', 'ACCEPT'), ('reject', 'REJECT'), ('drop', 'DROP'), ('masquerade', 'MASQUERADE')])
|
||||
sort_order = forms.IntegerField(label='Sort Order', initial=0, min_value=0)
|
||||
self.fields['firewall_chain'].initial = current_chain
|
||||
self.fields['in_interface'].choices = interface_list
|
||||
self.fields['out_interface'].choices = interface_list
|
||||
|
||||
class Meta:
|
||||
model = FirewallRule
|
||||
fields = ['description', 'firewall_chain', 'in_interface', 'out_interface', 'source_ip', 'source_netmask', 'source_peer', 'source_peer_include_networks', 'not_source', 'destination_ip', 'destination_netmask', 'destination_peer', 'destination_peer_include_networks', 'not_destination', 'protocol', 'destination_port', 'state_new', 'state_related', 'state_established', 'state_invalid', 'state_untracked', 'not_state', 'rule_action', 'sort_order']
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
firewall_chain = cleaned_data.get('firewall_chain')
|
||||
rule_action = cleaned_data.get('rule_action')
|
||||
in_interface = cleaned_data.get('in_interface')
|
||||
|
||||
if firewall_chain == 'forward' and rule_action not in ['accept', 'drop', 'reject']:
|
||||
raise forms.ValidationError("Invalid rule action for firewall chain 'forward'. Allowed actions are 'accept', 'drop', and 'reject'.")
|
||||
|
||||
if firewall_chain == 'postrouting':
|
||||
if rule_action not in ['masquerade', 'accept']:
|
||||
raise forms.ValidationError("Invalid rule action for firewall chain 'postrouting'. Allowed actions are 'masquerade' and 'accept'.")
|
||||
if in_interface:
|
||||
raise forms.ValidationError("In Interface cannot be used with firewall chain 'postrouting'.")
|
||||
|
||||
return cleaned_data
|
||||
|
||||
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from django.db.models import Max
|
||||
from firewall.models import RedirectRule, FirewallRule, FirewallSettings
|
||||
from firewall.forms import RedirectRuleForm, FirewallRuleForm
|
||||
from django.contrib import messages
|
||||
@ -82,6 +83,7 @@ def manage_firewall_rule(request):
|
||||
uuid = request.GET.get('uuid', None)
|
||||
if uuid:
|
||||
instance = get_object_or_404(FirewallRule, uuid=uuid)
|
||||
current_chain = instance.firewall_chain
|
||||
if request.GET.get('action') == 'delete':
|
||||
if request.GET.get('confirmation') == 'delete':
|
||||
firewall_settings, firewall_settings_created = FirewallSettings.objects.get_or_create(name='global')
|
||||
@ -91,19 +93,32 @@ def manage_firewall_rule(request):
|
||||
else:
|
||||
messages.warning(request, 'Error deleting Firewall rule|Confirmation did not match. Firewall rule was not deleted.')
|
||||
return redirect('/firewall/rule_list/')
|
||||
else:
|
||||
current_chain = request.GET.get('chain', 'forward')
|
||||
|
||||
if request.method == 'POST':
|
||||
form = FirewallRuleForm(request.POST, instance=instance)
|
||||
form = FirewallRuleForm(request.POST, instance=instance, current_chain=current_chain)
|
||||
if form.is_valid():
|
||||
firewall_settings, firewall_settings_created = FirewallSettings.objects.get_or_create(name='global')
|
||||
firewall_settings.pending_changes = True
|
||||
firewall_settings.save()
|
||||
form.save()
|
||||
messages.success(request, 'Firewall rule saved successfully')
|
||||
return redirect('/firewall/rule_list/')
|
||||
return redirect('/firewall/rule_list/?chain=' + current_chain)
|
||||
else:
|
||||
form = FirewallRuleForm(instance=instance)
|
||||
form = FirewallRuleForm(instance=instance, current_chain=current_chain)
|
||||
context['form'] = form
|
||||
context['instance'] = instance
|
||||
|
||||
highest_forward_sort_order = FirewallRule.objects.filter(firewall_chain='forward').aggregate(Max('sort_order'))['sort_order__max']
|
||||
if highest_forward_sort_order is None:
|
||||
highest_forward_sort_order = 0
|
||||
|
||||
highest_postrouting_sort_order = FirewallRule.objects.filter(firewall_chain='postrouting').aggregate(Max('sort_order'))['sort_order__max']
|
||||
if highest_postrouting_sort_order is None:
|
||||
highest_postrouting_sort_order = 0
|
||||
|
||||
context['forward_sort_order'] = highest_forward_sort_order + 10
|
||||
context['postrouting_sort_order'] = highest_postrouting_sort_order + 10
|
||||
|
||||
return render(request, 'firewall/manage_firewall_rule.html', context=context)
|
||||
|
@ -87,7 +87,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="/firewall/manage_firewall_rule/" class='btn btn-primary'>Create Firewall Rule</a>
|
||||
<a href="/firewall/manage_firewall_rule/?chain={{ current_chain }}" class='btn btn-primary'>Create Firewall Rule</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -102,42 +102,6 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block custom_page_scripts %}
|
||||
{% comment %}
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
document.querySelectorAll('td').forEach(function(td) {
|
||||
// Conta o número de <br> na célula
|
||||
let brCount = (td.innerHTML.match(/<br>/g) || []).length;
|
||||
|
||||
// Aplica a lógica de mostrar/esconder apenas se houver 2 ou mais <br>
|
||||
if (brCount >= 2) {
|
||||
let contentParts = td.innerHTML.split('<br>');
|
||||
// Assume que queremos manter a primeira linha visível, adiciona explicitamente uma quebra de linha antes do conteúdo escondido
|
||||
td.innerHTML = contentParts[0] + '<br>' +
|
||||
'<span style="display: none;">' +
|
||||
contentParts.slice(1).join('<br>') + '</span>' +
|
||||
'<button class="more-btn">Mais</button>';
|
||||
}
|
||||
});
|
||||
|
||||
// Adiciona evento de clique para botões "Mais"
|
||||
document.querySelectorAll('.more-btn').forEach(function(button) {
|
||||
button.addEventListener('click', function() {
|
||||
let moreText = this.previousElementSibling; // O span com o texto extra
|
||||
if (moreText.style.display === "none") {
|
||||
moreText.style.display = "inline";
|
||||
this.textContent = "Menos";
|
||||
} else {
|
||||
moreText.style.display = "none";
|
||||
this.textContent = "Mais";
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
{% endcomment %}
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
document.querySelectorAll('td').forEach(function(td) {
|
||||
@ -168,8 +132,6 @@
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
@ -431,4 +431,29 @@
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
|
||||
var forward_sort_order = {{ forward_sort_order }};
|
||||
var postrouting_sort_order = {{ postrouting_sort_order }};
|
||||
|
||||
function updateSortOrder() {
|
||||
var chainSelected = document.getElementById('firewall_chain').value;
|
||||
var sortOrderField = document.getElementById('sort_order');
|
||||
|
||||
if (chainSelected === 'forward') {
|
||||
sortOrderField.value = forward_sort_order;
|
||||
} else if (chainSelected === 'postrouting') {
|
||||
sortOrderField.value = postrouting_sort_order;
|
||||
}
|
||||
}
|
||||
document.getElementById('firewall_chain').addEventListener('change', updateSortOrder);
|
||||
{% if not instance %}
|
||||
updateSortOrder();
|
||||
{% endif %}
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user