diff --git a/flowspec/views.py b/flowspec/views.py index 29dd96c13f32d1ef45b2d252795279363c9a4625..987037f6b1a3db28b522db5a4c21d583cd93a405 100644 --- a/flowspec/views.py +++ b/flowspec/views.py @@ -479,6 +479,25 @@ def edit_route(request, route_slug): ) return HttpResponseRedirect(reverse("group-routes")) route_original = deepcopy(route_edit) + + critical_changed_values = ['source', 'destination', 'sourceport', 'destinationport', 'port', 'protocol', 'then', 'fragmenttype'] + + try: + setting_dup_routes_chk = settings.ROUTES_DUPLICATES_CHECKING + except: + setting_dup_routes_chk = False + try: + setting_dup_routes_chk__lazy0 = not settings.ROUTES_DUPLICATES_CHECKING__ENFORCED_FOR_ALREADY_EXISTING_RULES + except: + setting_dup_routes_chk__lazy0 = True + setting_dup_routes_chk__lazy = setting_dup_routes_chk and setting_dup_routes_chk__lazy0 + logger.info("setting_dup_routes_chk="+str(setting_dup_routes_chk)) + logger.info("setting_dup_routes_chk__lazy0="+str(setting_dup_routes_chk__lazy0)) + logger.info("setting_dup_routes_chk__lazy="+str(setting_dup_routes_chk__lazy)) + + add_error_msg='' + add_error_msg__overlapping_rule_already_existing_with_unchanged_flowspec = '(either solve the conflict by ensuring differing FlowSpec parameters for both rules, or as the rule already exists commit without changing any FlowSpec parameters)' + if request.POST: request_data = request.POST.copy() if request.user.is_superuser: @@ -493,7 +512,6 @@ def edit_route(request, route_slug): request_data, instance=route_edit ) - critical_changed_values = ['source', 'destination', 'sourceport', 'destinationport', 'port', 'protocol', 'then', 'fragmenttype'] form_is_valid = form.is_valid() changed_data = form.changed_data @@ -501,7 +519,7 @@ def edit_route(request, route_slug): logger.info("view::edit(): => changed_data="+str(changed_data)) flowspec_attributes_changed = bool(set(changed_data) & set(critical_changed_values)) logger.info("view::edit(): => flowspec_attributes_changed="+str(flowspec_attributes_changed)) - if not form_is_valid and not flowspec_attributes_changed: + if setting_dup_routes_chk__lazy and not form_is_valid and not flowspec_attributes_changed: logger.warn("view::edit(): WARNING, NOT form_is_valid, but not flowspec_attributes_changed, so trying with RouteForm_lightweight again") form2 = RouteForm_lightweight( request_data, @@ -512,6 +530,7 @@ def edit_route(request, route_slug): form = form2 form_is_valid = form.is_valid() changed_data = form.changed_data + add_error_msg = add_error_msg__overlapping_rule_already_existing_with_unchanged_flowspec else: logger.warn("view::edit(): WARNING, NOT form_is_valid, but not flowspec_attributes_changed: trying with RouteForm_lightweight failed") elif not form_is_valid: @@ -547,6 +566,7 @@ def edit_route(request, route_slug): { 'form': form, 'edit': True, + 'add_error' : add_error_msg, 'applier': applier, 'maxexpires': settings.MAX_RULE_EXPIRE_DAYS } @@ -563,6 +583,7 @@ def edit_route(request, route_slug): { 'form': form, 'edit': True, + 'add_error' : add_error_msg, 'applier': applier, 'maxexpires': settings.MAX_RULE_EXPIRE_DAYS } @@ -601,6 +622,7 @@ def edit_route(request, route_slug): 'form': form, 'edit': True, 'applier': applier, + 'add_error' : add_error_msg, 'maxexpires': settings.MAX_RULE_EXPIRE_DAYS }) else: @@ -616,7 +638,23 @@ def edit_route(request, route_slug): del dictionary['issuperuser'] except: pass + form = RouteForm(dictionary) + form_is_valid = form.is_valid() + logger.info("view::edit(): form_is_valid="+str(form_is_valid)) + #changed_data = form.changed_data + #flowspec_attributes_changed = bool(set(changed_data) & set(critical_changed_values)) + #if not form_is_valid and not flowspec_attributes_changed: + if setting_dup_routes_chk__lazy and not form_is_valid: + logger.warn("view::edit(): WARNING, NOT form_is_valid, so trying with RouteForm_lightweight again") + form2 = RouteForm_lightweight(dictionary) + if form2.is_valid(): + logger.warn("view::edit(): WARNING, NOT form_is_valid, RouteForm_lightweight is_valid") + add_error_msg = add_error_msg__overlapping_rule_already_existing_with_unchanged_flowspec + #form = form2 + #form_is_valid = form.is_valid() + #changed_data = form.changed_data + if not request.user.is_superuser: form.fields['then'] = forms.ModelMultipleChoiceField(queryset=ThenAction.objects.filter(action__in=settings.UI_USER_THEN_ACTIONS).order_by('action'), required=True) form.fields['protocol'] = forms.ModelMultipleChoiceField(queryset=MatchProtocol.objects.filter(protocol__in=settings.UI_USER_PROTOCOLS).order_by('protocol'), required=False) @@ -624,6 +662,7 @@ def edit_route(request, route_slug): { 'form': form, 'edit': True, + 'add_error' : add_error_msg, 'applier': applier, 'maxexpires': settings.MAX_RULE_EXPIRE_DAYS }) diff --git a/flowspy/settings.py.dist b/flowspy/settings.py.dist index 4555ec22d7b64e8d8cb206fcce7069d3f8a22896..3618e0d4d462086199eb0ce3b1a3d4a819ce382b 100644 --- a/flowspy/settings.py.dist +++ b/flowspy/settings.py.dist @@ -642,6 +642,7 @@ ALLOW_DELETE_FULL_FOR_USER_LIST = [ # with the same addresses). By default it is enabled (True). #DISABLE_RULE_OVERLAP_CHECK = False ROUTES_DUPLICATES_CHECKING = True +ROUTES_DUPLICATES_CHECKING__ENFORCED_FOR_ALREADY_EXISTING_RULES = False ############################################################################## ############################################################################## diff --git a/templates/apply.html b/templates/apply.html index 77569afd9c34eef4ba4800ec522bc0b8da06a1f8..a1ebb6de64113df724066d68352c7a7f94b7891f 100644 --- a/templates/apply.html +++ b/templates/apply.html @@ -282,11 +282,15 @@ {% if form.non_field_errors %} <div class="form-group {% if form.non_field_errors %} has-error {% endif %}" style="color: #A94442;" id="apply_rule_id"> {{ form.non_field_errors|unescape}} - </div> + {% if edit %}{% if add_error %}<ul class="errorlist nonfield"><li>{{ add_error | unescape }}</li></ul>{% endif %}{% endif %} + + </div> {% endif %} <fieldset {% if edit %} style="display:none;" {% endif %}> <div class="form-group {% if form.name.errors %} has-error {% endif %}"> + + <label for="id_name" class="col-md-2 control-label"><b>{% trans "Name" %}</b></label> <div class="col-md-8"> {% render_field form.name class+="form-control" placeholder="Eg. ntpattack. A unique identifier will be added as a suffix" %} @@ -299,6 +303,7 @@ <fieldset> <hr> <div class="form-group {% if form.applier.errors %} has-error {% endif %}"> + <label for="id_name" class="col-md-2 control-label"><b>{% trans "Applier" %}</b></label> <div class="col-md-8"> {% render_field form.applier class+="form-control" %}