1 from django import forms
2 from django.utils.safestring import mark_safe
3 from django.utils.translation import ugettext as _
4 from django.utils.translation import ugettext_lazy
5 from django.template.defaultfilters import filesizeformat
6 from flowspy.flowspec.models import *
8 from django.core.urlresolvers import reverse
9 from django.contrib.auth.models import User
14 class RouteForm(forms.ModelForm):
15 # name = forms.CharField(help_text=ugettext_lazy("A unique route name,"
16 # " e.g. uoa_block_p80"), label=ugettext_lazy("Route Name"), required=False)
17 # source = forms.CharField(help_text=ugettext_lazy("A qualified IP Network address. CIDR notation,"
18 # " e.g.10.10.0.1/32"), label=ugettext_lazy("Source Address"), required=False)
19 # source_ports = forms.ModelMultipleChoiceField(queryset=MatchPort.objects.all(), help_text=ugettext_lazy("A set of source ports to block"), label=ugettext_lazy("Source Ports"), required=False)
20 # destination = forms.CharField(help_text=ugettext_lazy("A qualified IP Network address. CIDR notation,"
21 # " e.g.10.10.0.1/32"), label=ugettext_lazy("Destination Address"), required=False)
22 # destination_ports = forms.ModelMultipleChoiceField(queryset=MatchPort.objects.all(), help_text=ugettext_lazy("A set of destination ports to block"), label=ugettext_lazy("Destination Ports"), required=False)
23 # ports = forms.ModelMultipleChoiceField(queryset=MatchPort.objects.all(), help_text=ugettext_lazy("A set of ports to block"), label=ugettext_lazy("Ports"), required=False)
27 def clean_source(self):
28 data = self.cleaned_data['source']
31 address = IPNetwork(data)
32 return self.cleaned_data["source"]
34 raise forms.ValidationError('Invalid network address format')
36 def clean_destination(self):
37 data = self.cleaned_data['destination']
40 address = IPNetwork(data)
41 return self.cleaned_data["destination"]
43 raise forms.ValidationError('Invalid network address format')
45 def clean_expires(self):
46 date = self.cleaned_data['expires']
48 range_days = (date - datetime.date.today()).days
49 if range_days > 0 and range_days < 11:
50 return self.cleaned_data["expires"]
52 raise forms.ValidationError('Invalid date range')
55 name = self.cleaned_data.get('name', None)
56 source = self.cleaned_data.get('source', None)
57 sourceports = self.cleaned_data.get('sourceport', None)
58 ports = self.cleaned_data.get('port', None)
59 then = self.cleaned_data.get('then', None)
60 destination = self.cleaned_data.get('destination', None)
61 destinationports = self.cleaned_data.get('destinationport', None)
62 user = self.cleaned_data.get('applier', None)
63 peer = user.get_profile().peer
64 networks = peer.networks.all()
69 for network in networks:
70 net = IPNetwork(network.network)
71 if IPNetwork(destination) in net:
74 raise forms.ValidationError('Destination address/network should belong to your administrative address space. Check My Profile to review your networks')
75 if (sourceports and ports):
76 raise forms.ValidationError('Cannot create rule for source ports and ports at the same time. Select either ports or source ports')
77 if (destinationports and ports):
78 raise forms.ValidationError('Cannot create rule for destination ports and ports at the same time. Select either ports or destination ports')
79 if sourceports and not source:
80 raise forms.ValidationError('Once source port is matched, source has to be filled as well. Either deselect source port or fill source address')
81 if destinationports and not destination:
82 raise forms.ValidationError('Once destination port is matched, destination has to be filled as well. Either deselect destination port or fill destination address')
83 if not (source or sourceports or ports or destination or destinationports):
84 raise forms.ValidationError('Fill at least a Route Match Condition')
85 existing_routes = Route.objects.exclude(status='EXPIRED').exclude(status='PENDING').exclude(status='ERROR').exclude(status='ADMININACTIVE')
86 existing_routes = existing_routes.filter(applier__userprofile__peer=peer)
88 source = IPNetwork(source).compressed
89 existing_routes = existing_routes.filter(source=source)
91 existing_routes = existing_routes.filter(source=None)
93 route_pk_list=get_matchingport_route_pks(sourceports, existing_routes)
95 existing_routes = existing_routes.filter(pk__in=route_pk_list)
97 existing_routes = existing_routes.filter(sourceport=None)
99 route_pk_list=get_matchingport_route_pks(destinationports, existing_routes)
101 existing_routes = existing_routes.filter(pk__in=route_pk_list)
103 existing_routes = existing_routes.filter(destinationport=None)
105 route_pk_list=get_matchingport_route_pks(ports, existing_routes)
107 existing_routes = existing_routes.filter(pk__in=route_pk_list)
109 existing_routes = existing_routes.filter(port=None)
111 for route in existing_routes:
112 if name != route.name:
113 existing_url = reverse('edit-route', args=[route.name])
114 if IPNetwork(destination) in IPNetwork(route.destination):
115 raise forms.ValidationError('There is an exact %s rule, %s whose destination (%s) is supernet of (or the same as) network (%s).<br>To avoid overlapping try editing rule <a href=\'%s\'>%s</a>' %(route.status, route.name, route.destination, destination, existing_url, route.name))
116 if IPNetwork(route.destination) in IPNetwork(destination):
117 raise forms.ValidationError('There is an exact %s rule, %s whose destination network (%s) belongs to the destination network %s.<br>To avoid overlapping try editing rule <a href=\'%s\'>%s</a>' %(route.status, route.name, route.destination, destination, existing_url, route.name))
120 return self.cleaned_data
122 class ThenPlainForm(forms.ModelForm):
123 # action = forms.CharField(initial='rate-limit')
127 def clean_action_value(self):
128 action_value = self.cleaned_data['action_value']
131 assert(int(action_value))
132 return "%s" %self.cleaned_data["action_value"]
134 raise forms.ValidationError('Rate-limiting should be an integer')
135 if int(action_value) < 50:
136 raise forms.ValidationError('Rate-limiting cannot be < 50kbps')
138 raise forms.ValidationError('Cannot be empty')
140 def clean_action(self):
141 action = self.cleaned_data['action']
142 if action != 'rate-limit':
143 raise forms.ValidationError('Cannot select something other than rate-limit')
145 return self.cleaned_data["action"]
147 class PortPlainForm(forms.ModelForm):
148 # action = forms.CharField(initial='rate-limit')
152 def clean_port(self):
153 port = self.cleaned_data['port']
157 return "%s" %self.cleaned_data["port"]
159 raise forms.ValidationError('Port should be an integer')
161 raise forms.ValidationError('Cannot be empty')
163 def value_list_to_list(valuelist):
165 for val in valuelist:
169 def get_matchingport_route_pks(portlist, routes):
171 ports_value_list = value_list_to_list(portlist.values_list('port').order_by('port'))
173 rsp = value_list_to_list(route.destinationport.all().values_list('port').order_by('port'))
174 if rsp and rsp == ports_value_list:
175 route_pk_list.append(route.pk)