Skip to content

Commit 027a976

Browse files
committed
Summary: Fix problem with confirm checkbox for potentially dangerous
acronym choices on group edit/creation page, fixes the last remaining facelift test failure - Legacy-Id: 8720
1 parent 8e4459a commit 027a976

3 files changed

Lines changed: 48 additions & 26 deletions

File tree

ietf/group/edit.py

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from ietf.person.fields import SearchableEmailsField
2323
from ietf.person.models import Person, Email
2424
from ietf.group.mails import email_iesg_secretary_re_charter
25+
from ietf.utils.ordereddict import insert_after_in_ordered_dict
2526

2627
MAX_GROUP_DELEGATES = 3
2728

@@ -43,7 +44,6 @@ class GroupForm(forms.Form):
4344

4445
def __init__(self, *args, **kwargs):
4546
self.group = kwargs.pop('group', None)
46-
self.confirmed = kwargs.pop('confirmed', False)
4747
self.group_type = kwargs.pop('group_type', False)
4848

4949
super(self.__class__, self).__init__(*args, **kwargs)
@@ -57,8 +57,6 @@ def __init__(self, *args, **kwargs):
5757
if ad_pk and ad_pk not in [pk for pk, name in choices]:
5858
self.fields['ad'].choices = list(choices) + [("", "-------"), (ad_pk, Person.objects.get(pk=ad_pk).plain_name())]
5959

60-
self.confirm_msg = ""
61-
self.autoenable_confirm = False
6260
if self.group:
6361
self.fields['acronym'].widget.attrs['readonly'] = ""
6462

@@ -71,9 +69,6 @@ def __init__(self, *args, **kwargs):
7169
self.fields['parent'].label = "IETF Area"
7270

7371
def clean_acronym(self):
74-
self.confirm_msg = ""
75-
self.autoenable_confirm = False
76-
7772
# Changing the acronym of an already existing group will cause 404s all
7873
# over the place, loose history, and generally muck up a lot of
7974
# things, so we don't permit it
@@ -90,27 +85,41 @@ def clean_acronym(self):
9085
if existing:
9186
existing = existing[0]
9287

93-
if existing and existing.type_id == self.group_type:
94-
if self.confirmed:
95-
return acronym # take over confirmed
88+
confirmed = self.data.get("confirm_acronym", False)
89+
90+
def insert_confirm_field(label, initial):
91+
# set required to false, we don't need it since we do the
92+
# validation of the field in here, and otherwise the
93+
# browser and Django may barf
94+
insert_after_in_ordered_dict(self.fields, "confirm_acronym", forms.BooleanField(label=label, required=False), after="acronym")
95+
# we can't set initial, it's ignored since the form is bound, instead mutate the data
96+
self.data = self.data.copy()
97+
self.data["confirm_acronym"] = initial
9698

99+
if existing and existing.type_id == self.group_type:
97100
if existing.state_id == "bof":
98-
self.confirm_msg = "Turn BoF %s into proposed %s and start chartering it" % (existing.acronym, existing.type.name)
99-
self.autoenable_confirm = True
100-
raise forms.ValidationError("Warning: Acronym used for an existing BoF (%s)." % existing.name)
101+
insert_confirm_field(label="Turn BoF %s into proposed %s and start chartering it" % (existing.acronym, existing.type.name), initial=True)
102+
if confirmed:
103+
return acronym
104+
else:
105+
raise forms.ValidationError("Warning: Acronym used for an existing BoF (%s)." % existing.name)
101106
else:
102-
self.confirm_msg = "Set state of %s %s to proposed and start chartering it" % (existing.acronym, existing.type.name)
103-
self.autoenable_confirm = False
104-
raise forms.ValidationError("Warning: Acronym used for an existing %s (%s, %s)." % (existing.type.name, existing.name, existing.state.name if existing.state else "unknown state"))
107+
insert_confirm_field(label="Set state of %s %s to proposed and start chartering it" % (existing.acronym, existing.type.name), initial=False)
108+
if confirmed:
109+
return acronym
110+
else:
111+
raise forms.ValidationError("Warning: Acronym used for an existing %s (%s, %s)." % (existing.type.name, existing.name, existing.state.name if existing.state else "unknown state"))
105112

106113
if existing:
107114
raise forms.ValidationError("Acronym used for an existing group (%s)." % existing.name)
108115

109116
old = GroupHistory.objects.filter(acronym__iexact=acronym, type__in=("wg", "rg"))
110-
if old and not self.confirmed:
111-
self.confirm_msg = "Confirm reusing acronym %s" % old[0].acronym
112-
self.autoenable_confirm = False
113-
raise forms.ValidationError("Warning: Acronym used for a historic group.")
117+
if old:
118+
insert_confirm_field(label="Confirm reusing acronym %s" % old[0].acronym, initial=False)
119+
if confirmed:
120+
return acronym
121+
else:
122+
raise forms.ValidationError("Warning: Acronym used for a historic group.")
114123

115124
return acronym
116125

@@ -190,7 +199,7 @@ def edit(request, group_type=None, acronym=None, action="edit"):
190199
group_type = group.type_id
191200

192201
if request.method == 'POST':
193-
form = GroupForm(request.POST, group=group, confirmed=request.POST.get("confirmed", False), group_type=group_type)
202+
form = GroupForm(request.POST, group=group, group_type=group_type)
194203
if form.is_valid():
195204
clean = form.cleaned_data
196205
if new_group:

ietf/group/tests_info.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ def test_create_based_on_existing_bof(self):
342342
self.assertEqual(r.status_code, 200)
343343
q = PyQuery(r.content)
344344
self.assertTrue(len(q('form .has-error')) > 0)
345-
self.assertEqual(len(q('form input[name="confirmed"]')), 0) # can't confirm us out of this
345+
self.assertEqual(len(q('form input[name="confirm_acronym"]')), 0) # can't confirm us out of this
346346

347347
# try elevating BoF to WG
348348
group.state_id = "bof"
@@ -352,13 +352,13 @@ def test_create_based_on_existing_bof(self):
352352
self.assertEqual(r.status_code, 200)
353353
q = PyQuery(r.content)
354354
self.assertTrue(len(q('form .has-error')) > 0)
355-
self.assertEqual(len(q('form input[name="confirmed"]')), 1)
355+
self.assertEqual(len(q('form input[name="confirm_acronym"]')), 1)
356356

357357
self.assertEqual(Group.objects.get(acronym=group.acronym).state_id, "bof")
358358

359359
# confirm elevation
360360
state = GroupStateName.objects.get(slug="proposed")
361-
r = self.client.post(url, dict(name="Test", acronym=group.acronym, confirmed="1",state=state.pk))
361+
r = self.client.post(url, dict(name="Test", acronym=group.acronym, confirm_acronym="1", state=state.pk))
362362
self.assertEqual(r.status_code, 302)
363363
self.assertEqual(Group.objects.get(acronym=group.acronym).state_id, "proposed")
364364
self.assertEqual(Group.objects.get(acronym=group.acronym).name, "Test")

ietf/templates/group/edit.html

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
{% endblock %}
1313

1414
{% block pagehead %}
15-
<link rel="stylesheet" href="/facelift/css/lib/select2.css">
16-
<link rel="stylesheet" href="/facelift/css/lib/select2-bootstrap.css">
15+
<link rel="stylesheet" href="/facelift/css/lib/select2.css">
16+
<link rel="stylesheet" href="/facelift/css/lib/select2-bootstrap.css">
1717
{% endblock %}
1818

1919
{% block content %}
@@ -51,5 +51,18 @@ <h1>
5151
{% endblock %}
5252

5353
{% block js %}
54-
<script src="/facelift/js/lib/select2-3.5.2.min.js"></script>
54+
<script src="/facelift/js/lib/select2-3.5.2.min.js"></script>
55+
<script>
56+
$(document).ready(function () {
57+
$("#id_acronym").closest(".form-group").each(function() {
58+
// fixup styling a bit in case the confirm checkbox is shown
59+
if ($(this).next().find("#id_confirm_acronym").length > 0) {
60+
$(this).css("margin-bottom", 0);
61+
$(this).find(".help-block").css("margin-bottom", 0);
62+
if ($(this).hasClass("has-error"))
63+
$(this).next().addClass("has-error");
64+
}
65+
});
66+
});
67+
</script>
5568
{% endblock %}

0 commit comments

Comments
 (0)