Superuser can interact with all networks from all peers
[flowspy] / flowspec / forms.py
index f5741c6..79c0a4c 100644 (file)
@@ -4,6 +4,7 @@ from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext_lazy
 from django.template.defaultfilters import filesizeformat
 from flowspy.flowspec.models import *
+from flowspy.peers.models import *
 from ipaddr import *
 from django.core.urlresolvers import reverse
 from django.contrib.auth.models import User
@@ -42,10 +43,10 @@ class RouteForm(forms.ModelForm):
                         send_mail(settings.EMAIL_SUBJECT_PREFIX + "Caught an attempt to set a protected IP/network as a source address",
                               mail_body, settings.SERVER_EMAIL,
                               settings.NOTIFY_ADMIN_MAILS, fail_silently=True)
-                        raise forms.ValidationError("Not allowed")
+                        raise Exception
                 if address.is_private:
                     private_error = True
-                    raise forms.ValidationError('Private addresses not allowed')
+                    raise Exception
                 else:
                     return self.cleaned_data["source"]
             except Exception:
@@ -58,7 +59,7 @@ class RouteForm(forms.ModelForm):
 
     def clean_destination(self):
         user = User.objects.get(pk=self.data['applier'])
-        peer = user.get_profile().peer        
+        peer = user.get_profile().peer
         data = self.cleaned_data['destination']
         error = None
         protected_error = False
@@ -72,10 +73,10 @@ class RouteForm(forms.ModelForm):
                         send_mail(settings.EMAIL_SUBJECT_PREFIX + "Caught an attempt to set a protected IP/network as the destination address",
                               mail_body, settings.SERVER_EMAIL,
                               settings.NOTIFY_ADMIN_MAILS, fail_silently=True)
-                        raise forms.ValidationError("Not allowed")
+                        raise Exception
                 if address.prefixlen < settings.PREFIX_LENGTH:
                     error = "Currently no prefix lengths < %s are allowed" %settings.PREFIX_LENGTH
-                    raise forms.ValidationError('error')
+                    raise Exception
                 return self.cleaned_data["destination"]
             except Exception:
                 error_text = 'Invalid network address format'
@@ -95,6 +96,8 @@ class RouteForm(forms.ModelForm):
                 raise forms.ValidationError('Invalid date range')
 
     def clean(self):
+        if self.errors:
+             raise forms.ValidationError('Errors in form. Please review and fix them')
         name = self.cleaned_data.get('name', None)
         source = self.cleaned_data.get('source', None)
         sourceports = self.cleaned_data.get('sourceport', None)
@@ -102,9 +105,12 @@ class RouteForm(forms.ModelForm):
         then = self.cleaned_data.get('then', None)
         destination = self.cleaned_data.get('destination', None)
         destinationports = self.cleaned_data.get('destinationport', None)
+        protocols = self.cleaned_data.get('protocol', None)
         user = self.cleaned_data.get('applier', None)
         peer = user.get_profile().peer
         networks = peer.networks.all()
+        if user.is_superuser:
+            networks = PeerRange.objects.filter(peer__in=Peer.objects.all()).distinct()
         mynetwork = False
         route_pk_list = []
         if destination:
@@ -126,13 +132,21 @@ class RouteForm(forms.ModelForm):
             raise forms.ValidationError('Fill at least a Rule Match Condition')
         if not user.is_superuser and then[0].action not in settings.UI_USER_THEN_ACTIONS:
             raise forms.ValidationError('This action "%s" is not permitted' %(then[0].action))
-        existing_routes = Route.objects.exclude(status='EXPIRED').exclude(status='PENDING').exclude(status='ERROR').exclude(status='ADMININACTIVE')
+        existing_routes = Route.objects.exclude(status='EXPIRED').exclude(status='ERROR').exclude(status='ADMININACTIVE')
         existing_routes = existing_routes.filter(applier__userprofile__peer=peer)
         if source:
             source = IPNetwork(source).compressed
             existing_routes = existing_routes.filter(source=source)
         else:
             existing_routes = existing_routes.filter(source=None)
+        if protocols:
+            route_pk_list=get_matchingprotocol_route_pks(protocols, existing_routes)
+            if route_pk_list:
+                existing_routes = existing_routes.filter(pk__in=route_pk_list)
+            else:
+                existing_routes = existing_routes.filter(protocol=None)
+        else:
+            existing_routes = existing_routes.filter(protocol=None)
         if sourceports:
             route_pk_list=get_matchingport_route_pks(sourceports, existing_routes)
             if route_pk_list:
@@ -151,7 +165,6 @@ class RouteForm(forms.ModelForm):
                 existing_routes = existing_routes.filter(pk__in=route_pk_list)              
         else:
             existing_routes = existing_routes.filter(port=None)
-        
         for route in existing_routes:
             if name != route.name:
                 existing_url = reverse('edit-route', args=[route.name])
@@ -214,4 +227,13 @@ def get_matchingport_route_pks(portlist, routes):
         rsp = value_list_to_list(route.destinationport.all().values_list('port').order_by('port'))
         if rsp and rsp == ports_value_list:
             route_pk_list.append(route.pk)
+    return route_pk_list
+
+def get_matchingprotocol_route_pks(protocolist, routes):
+    route_pk_list = []
+    protocols_value_list = value_list_to_list(protocolist.values_list('protocol').order_by('protocol'))
+    for route in routes:
+        rsp = value_list_to_list(route.protocol.all().values_list('protocol').order_by('protocol'))
+        if rsp and rsp == protocols_value_list:
+            route_pk_list.append(route.pk)
     return route_pk_list
\ No newline at end of file