2024-02-14 16:36:01 -03:00
import ipaddress
2025-04-15 14:22:40 -03:00
from django import forms
from django . utils . translation import gettext_lazy as _
from wireguard . models import NETMASK_CHOICES , Peer , PeerAllowedIP
2024-02-14 16:36:01 -03:00
class PeerForm ( forms . ModelForm ) :
2025-04-15 14:22:40 -03:00
name = forms . CharField ( label = _ ( ' Name ' ) , required = False )
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 )
2024-02-14 16:36:01 -03:00
class Meta :
model = Peer
fields = [ ' name ' , ' public_key ' , ' private_key ' , ' pre_shared_key ' , ' persistent_keepalive ' ]
class PeerAllowedIPForm ( forms . ModelForm ) :
def __init__ ( self , * args , * * kwargs ) :
current_peer = kwargs . pop ( ' current_peer ' , None )
2024-03-09 16:02:48 -03:00
config_file = kwargs . pop ( ' config_file ' , None )
2024-02-14 16:36:01 -03:00
super ( ) . __init__ ( * args , * * kwargs )
self . current_peer = current_peer
2024-03-09 16:02:48 -03:00
self . config_file = config_file
2024-02-14 16:36:01 -03:00
2025-04-15 14:22:40 -03:00
allowed_ip = forms . GenericIPAddressField ( label = _ ( ' Allowed IP or Network ' ) , required = True )
netmask = forms . ChoiceField ( choices = NETMASK_CHOICES , label = _ ( ' Netmask ' ) , initial = 24 , required = True )
priority = forms . IntegerField ( label = _ ( ' Priority ' ) , required = True , initial = 1 )
2024-02-14 16:36:01 -03:00
def clean ( self ) :
cleaned_data = super ( ) . clean ( )
priority = cleaned_data . get ( ' priority ' )
allowed_ip = cleaned_data . get ( ' allowed_ip ' )
netmask = cleaned_data . get ( ' netmask ' )
2024-02-17 11:53:51 -03:00
if allowed_ip is None :
2025-04-15 14:22:40 -03:00
raise forms . ValidationError ( _ ( " Please provide a valid IP address. " ) )
2024-02-17 11:53:51 -03:00
2024-03-09 16:02:48 -03:00
if self . config_file == ' server ' :
wireguard_network = ipaddress . ip_network ( f " { self . current_peer . wireguard_instance . address } / { self . current_peer . wireguard_instance . netmask } " , strict = False )
if priority == 0 :
zero_priority_ips_query = PeerAllowedIP . objects . filter ( peer = self . current_peer , config_file = ' server ' , priority = 0 )
if self . instance :
zero_priority_ips_query = zero_priority_ips_query . exclude ( uuid = self . instance . uuid )
if zero_priority_ips_query . exists ( ) :
2025-04-15 14:22:40 -03:00
raise forms . ValidationError ( _ ( " A peer can have only one IP with priority zero. " ) )
2024-02-14 16:36:01 -03:00
2024-03-09 16:02:48 -03:00
duplicated_ip = PeerAllowedIP . objects . filter ( config_file = ' server ' , allowed_ip = allowed_ip )
if self . instance :
duplicated_ip = duplicated_ip . exclude ( uuid = self . instance . uuid )
if duplicated_ip . exists ( ) :
2025-04-15 14:22:40 -03:00
raise forms . ValidationError ( _ ( " This IP is already in use by another peer. " ) )
2024-03-09 16:02:48 -03:00
if ipaddress . ip_address ( allowed_ip ) not in wireguard_network :
2025-04-15 14:22:40 -03:00
raise forms . ValidationError ( _ ( " The IP address does not belong to the Peer ' s WireGuard instance network range. Please check the IP address or change the priority. " ) )
2024-03-09 16:02:48 -03:00
if str ( netmask ) != str ( 32 ) :
2025-04-15 14:22:40 -03:00
raise forms . ValidationError ( _ ( " The netmask for priority 0 IP must be 32. " ) )
2024-03-09 16:02:48 -03:00
if self . current_peer . wireguard_instance . address == allowed_ip :
2025-04-15 14:22:40 -03:00
raise forms . ValidationError ( _ ( " The IP address is the same as the Peer ' s WireGuard instance address. " ) )
2024-03-09 16:02:48 -03:00
else :
if ipaddress . ip_address ( allowed_ip ) in wireguard_network :
2025-04-15 14:22:40 -03:00
raise forms . ValidationError ( _ ( " The IP address belongs to the Peer ' s WireGuard instance network range. Please check the IP address or change use priority 0 instead. " ) )
2024-03-09 16:02:48 -03:00
elif self . config_file == ' client ' :
if priority < 1 :
2025-04-15 14:22:40 -03:00
raise forms . ValidationError ( _ ( " Priority must be greater than or equal to 1 " ) )
2024-02-14 16:36:01 -03:00
else :
2025-04-15 14:22:40 -03:00
raise forms . ValidationError ( _ ( ' Invalid config file ' ) )
2024-02-14 16:36:01 -03:00
class Meta :
model = PeerAllowedIP
fields = [ ' allowed_ip ' , ' priority ' , ' netmask ' ]