Skip to content

Commit d43159c

Browse files
committed
Add support for incoming ADs with a new "pre-ad" role
- Legacy-Id: 3900
1 parent 5c66a91 commit d43159c

9 files changed

Lines changed: 57 additions & 16 deletions

File tree

ietf/idrfc/testsREDESIGN.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,22 @@ def test_edit_position_as_secretary(self):
500500
self.assertEquals(pos.discuss, "Test discuss text")
501501
self.assertTrue("New position" in pos.desc)
502502
self.assertTrue("by Sec" in pos.desc)
503+
504+
def test_cannot_edit_position_as_pre_ad(self):
505+
draft = make_test_data()
506+
url = urlreverse('doc_edit_position', kwargs=dict(name=draft.name))
507+
508+
# transform to pre-ad
509+
ad_role = Role.objects.filter(name="ad")[0]
510+
ad_role.name_id = "pre-ad"
511+
ad_role.save()
512+
513+
# we can see
514+
login_testing_unauthorized(self, ad_role.person.user.username, url)
515+
516+
# but not touch
517+
r = self.client.post(url, dict(position="discuss", discuss="Test discuss text"))
518+
self.assertEquals(r.status_code, 403)
503519

504520
def test_send_ballot_comment(self):
505521
draft = make_test_data()

ietf/idrfc/views_ballot.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import re, os
55
from datetime import datetime, date, time, timedelta
6-
from django.http import HttpResponse, HttpResponseRedirect, Http404
6+
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
77
from django.shortcuts import render_to_response, get_object_or_404
88
from django.core.urlresolvers import reverse as urlreverse
99
from django.template.loader import render_to_string
@@ -15,7 +15,7 @@
1515
from ietf.utils.mail import send_mail_text, send_mail_preformatted
1616
from ietf.ietfauth.decorators import group_required
1717
from ietf.idtracker.templatetags.ietf_filters import in_group
18-
from ietf.ietfauth.decorators import has_role
18+
from ietf.ietfauth.decorators import has_role, role_required
1919
from ietf.idtracker.models import *
2020
from ietf.iesg.models import *
2121
from ietf.ipr.models import IprDetail
@@ -222,7 +222,7 @@ def clean_discuss(self):
222222
raise forms.ValidationError("You must enter a non-empty discuss")
223223
return entered_discuss
224224

225-
@group_required('Area_Director','Secretariat')
225+
@role_required('Area Director','Secretariat')
226226
def edit_positionREDESIGN(request, name):
227227
"""Vote and edit discuss and comment on Internet Draft as Area Director."""
228228
doc = get_object_or_404(Document, docalias__name=name)
@@ -238,7 +238,7 @@ def edit_positionREDESIGN(request, name):
238238
return_to_url = doc.get_absolute_url()
239239

240240
# if we're in the Secretariat, we can select an AD to act as stand-in for
241-
if not has_role(request.user, "Area Director"):
241+
if has_role(request.user, "Secretariat"):
242242
ad_id = request.GET.get('ad')
243243
if not ad_id:
244244
raise Http404()
@@ -248,6 +248,10 @@ def edit_positionREDESIGN(request, name):
248248
old_pos = doc.latest_event(BallotPositionDocEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time)
249249

250250
if request.method == 'POST':
251+
if not has_role(request.user, "Secretariat") and not ad.role_set.filter(name="ad", group__type="area", group__state="active"):
252+
# prevent pre-ADs from voting
253+
return HttpResponseForbidden("Must be a proper Area Director in an active area to cast ballot")
254+
251255
form = EditPositionForm(request.POST)
252256
if form.is_valid():
253257

ietf/idrfc/views_search.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,9 @@ def __init__(self, *args, **kwargs):
301301
active_ads = list(Person.objects.filter(role__name="ad",
302302
role__group__type="area",
303303
role__group__state="active").distinct())
304-
inactive_ads = list(Person.objects.filter(pk__in=responsible)
304+
inactive_ads = list((Person.objects.filter(pk__in=responsible) | Person.objects.filter(role__name="pre-ad",
305+
role__group__type="area",
306+
role__group__state="active"))
305307
.exclude(pk__in=[x.pk for x in active_ads]))
306308
extract_last_name = lambda x: x.name_parts()[3]
307309
active_ads.sort(key=extract_last_name)
@@ -568,10 +570,11 @@ def by_ad(request, name):
568570
ad_name = None
569571
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
570572
responsible = Document.objects.values_list('ad', flat=True).distinct()
571-
for p in Person.objects.filter(Q(role__name="ad",
573+
for p in Person.objects.filter(Q(role__name__in=("pre-ad", "ad"),
572574
role__group__type="area",
573575
role__group__state="active")
574-
| Q(pk__in=responsible)):
576+
| Q(pk__in=responsible)).distinct():
577+
print name, p.full_name_as_key()
575578
if name == p.full_name_as_key():
576579
ad_id = p.id
577580
ad_name = p.plain_name()

ietf/idtracker/templatetags/ietf_filters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ def stable_dictsort(value, arg):
436436
def ad_area(user):
437437
if user and user.is_authenticated():
438438
from ietf.group.models import Group
439-
g = Group.objects.filter(role__name="ad", role__person__user=user)
439+
g = Group.objects.filter(role__name__in=("pre-ad", "ad"), role__person__user=user)
440440
if g:
441441
return g[0].acronym
442442
return None

ietf/ietfauth/decorators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def has_role(user, role_names):
7979
return False
8080

8181
role_qs = {
82-
"Area Director": Q(person=person, name="ad", group__type="area", group__state="active"),
82+
"Area Director": Q(person=person, name__in=("pre-ad", "ad"), group__type="area", group__state="active"),
8383
"Secretariat": Q(person=person, name="secr", group__acronym="secretariat"),
8484
"IANA": Q(person=person, name="auth", group__acronym="iana"),
8585
"WG Chair": Q(person=person,name="chair", group__type="wg", group__state="active"),
@@ -97,7 +97,7 @@ def role_required(*role_names):
9797
"""View decorator for checking that the user is logged in and
9898
has one of the listed roles."""
9999
return passes_test_decorator(lambda u: has_role(u, role_names),
100-
"Restricted to role%s %s" % ("s" if len(role_names) != 1 else "", ",".join(role_names)))
100+
"Restricted to role%s %s" % ("s" if len(role_names) != 1 else "", ", ".join(role_names)))
101101

102102
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
103103
# overwrite group_required

ietf/templates/wginfo/wg-dirREDESIGN.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ <h2 class="ietf-divider" id="{{area.name|cut:" "}}">{{ area.name }}</h2>
5858
<p>Area Director{{ forloop.revcounter|pluralize }}:</p>
5959
<table style="margin-left: 2em" class="ietf-wg-table">
6060
{% endif %}
61-
<tr><td><span class="square bgcolor{{forloop.counter}}">&nbsp;</span></td> <td><a href="mailto:{{ ad.address }}">{{ ad.person.plain_name }} &lt;{{ ad.address }}&gt;</a></td></tr>
61+
<tr><td><span class="square bgcolor{{forloop.counter}}">&nbsp;</span></td> <td><a href="mailto:{{ ad.address }}">{{ ad.person.plain_name }} &lt;{{ ad.address }}&gt;</a>{% if ad.incoming %} (Incoming AD){% endif %}</td></tr>
6262
{% if forloop.last %}
6363
</table>
6464
{% endif %}

ietf/wgchairs/accounts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def is_area_director_for_group(person, group):
1111
return bool(group.area.area.areadirector_set.filter(person=person).count())
1212

1313
def is_area_director_for_groupREDESIGN(person, group):
14-
return bool(Role.objects.filter(group=group.parent, person=person, name="ad"))
14+
return bool(Role.objects.filter(group=group.parent, person=person, name=("ad", "pre-ad")))
1515

1616

1717
def is_group_chair(person, group):

ietf/wginfo/views.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,16 @@ def wg_dirREDESIGN(request):
9999

100100
areas = Group.objects.filter(type="area", state="active").order_by("name")
101101
for area in areas:
102-
area.ads = sorted(Email.objects.filter(role__group=area, role__name="ad").select_related("person"), key=lambda e: e.person.name_parts()[3])
102+
area.ads = []
103+
for e in Email.objects.filter(role__group=area, role__name="ad").select_related("person"):
104+
e.incoming = False
105+
area.ads.append(e)
106+
107+
for e in Email.objects.filter(role__group=area, role__name="pre-ad").select_related("person"):
108+
e.incoming = True
109+
area.ads.append(e)
110+
111+
area.ads.sort(key=lambda e: (e.incoming, e.person.name_parts()[3]))
103112
area.wgs = Group.objects.filter(parent=area, type="wg", state="active").order_by("acronym")
104113
area.urls = area.groupurl_set.all().order_by("name")
105114
for wg in area.wgs:

redesign/importing/import-roles.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
# SDOAuthorizedIndividual, WGDelegate
3434

3535
area_director_role = name(RoleName, "ad", "Area Director")
36+
pre_area_director_role = name(RoleName, "pre-ad", "Incoming Area Director")
3637
chair_role = name(RoleName, "chair", "Chair")
3738
editor_role = name(RoleName, "editor", "Editor")
3839
secretary_role = name(RoleName, "secr", "Secretary")
@@ -237,14 +238,22 @@
237238

238239
area = Group.objects.get(acronym=o.area.area_acronym.acronym)
239240

240-
r = Role.objects.filter(name=area_director_role,
241+
role_type = area_director_role
242+
243+
try:
244+
if IESGLogin.objects.get(person=o.person).user_level == 4:
245+
role_type = pre_area_director_role
246+
except IESGLogin.DoesNotExist:
247+
pass
248+
249+
r = Role.objects.filter(name=role_type,
241250
person=email.person)
242251
if r and r[0].group == "iesg":
243252
r[0].group = area
244-
r[0].name = area_director_role
253+
r[0].name = role_type
245254
r[0].save()
246255
else:
247-
Role.objects.get_or_create(name=area_director_role, group=area, person=email.person, email=email)
256+
Role.objects.get_or_create(name=role_type, group=area, person=email.person, email=email)
248257

249258
# IESGHistory
250259
emails_for_time = {}

0 commit comments

Comments
 (0)