Add support for incoming ADs with a new "pre-ad" role
- Legacy-Id: 3900
This commit is contained in:
parent
5c66a91c0e
commit
d43159cd90
|
@ -500,6 +500,22 @@ class EditPositionTestCase(django.test.TestCase):
|
|||
self.assertEquals(pos.discuss, "Test discuss text")
|
||||
self.assertTrue("New position" in pos.desc)
|
||||
self.assertTrue("by Sec" in pos.desc)
|
||||
|
||||
def test_cannot_edit_position_as_pre_ad(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_edit_position', kwargs=dict(name=draft.name))
|
||||
|
||||
# transform to pre-ad
|
||||
ad_role = Role.objects.filter(name="ad")[0]
|
||||
ad_role.name_id = "pre-ad"
|
||||
ad_role.save()
|
||||
|
||||
# we can see
|
||||
login_testing_unauthorized(self, ad_role.person.user.username, url)
|
||||
|
||||
# but not touch
|
||||
r = self.client.post(url, dict(position="discuss", discuss="Test discuss text"))
|
||||
self.assertEquals(r.status_code, 403)
|
||||
|
||||
def test_send_ballot_comment(self):
|
||||
draft = make_test_data()
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import re, os
|
||||
from datetime import datetime, date, time, timedelta
|
||||
from django.http import HttpResponse, HttpResponseRedirect, Http404
|
||||
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.core.urlresolvers import reverse as urlreverse
|
||||
from django.template.loader import render_to_string
|
||||
|
@ -15,7 +15,7 @@ from django.conf import settings
|
|||
from ietf.utils.mail import send_mail_text, send_mail_preformatted
|
||||
from ietf.ietfauth.decorators import group_required
|
||||
from ietf.idtracker.templatetags.ietf_filters import in_group
|
||||
from ietf.ietfauth.decorators import has_role
|
||||
from ietf.ietfauth.decorators import has_role, role_required
|
||||
from ietf.idtracker.models import *
|
||||
from ietf.iesg.models import *
|
||||
from ietf.ipr.models import IprDetail
|
||||
|
@ -222,7 +222,7 @@ class EditPositionFormREDESIGN(forms.Form):
|
|||
raise forms.ValidationError("You must enter a non-empty discuss")
|
||||
return entered_discuss
|
||||
|
||||
@group_required('Area_Director','Secretariat')
|
||||
@role_required('Area Director','Secretariat')
|
||||
def edit_positionREDESIGN(request, name):
|
||||
"""Vote and edit discuss and comment on Internet Draft as Area Director."""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
|
@ -238,7 +238,7 @@ def edit_positionREDESIGN(request, name):
|
|||
return_to_url = doc.get_absolute_url()
|
||||
|
||||
# if we're in the Secretariat, we can select an AD to act as stand-in for
|
||||
if not has_role(request.user, "Area Director"):
|
||||
if has_role(request.user, "Secretariat"):
|
||||
ad_id = request.GET.get('ad')
|
||||
if not ad_id:
|
||||
raise Http404()
|
||||
|
@ -248,6 +248,10 @@ def edit_positionREDESIGN(request, name):
|
|||
old_pos = doc.latest_event(BallotPositionDocEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time)
|
||||
|
||||
if request.method == 'POST':
|
||||
if not has_role(request.user, "Secretariat") and not ad.role_set.filter(name="ad", group__type="area", group__state="active"):
|
||||
# prevent pre-ADs from voting
|
||||
return HttpResponseForbidden("Must be a proper Area Director in an active area to cast ballot")
|
||||
|
||||
form = EditPositionForm(request.POST)
|
||||
if form.is_valid():
|
||||
|
||||
|
|
|
@ -301,7 +301,9 @@ if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
|||
active_ads = list(Person.objects.filter(role__name="ad",
|
||||
role__group__type="area",
|
||||
role__group__state="active").distinct())
|
||||
inactive_ads = list(Person.objects.filter(pk__in=responsible)
|
||||
inactive_ads = list((Person.objects.filter(pk__in=responsible) | Person.objects.filter(role__name="pre-ad",
|
||||
role__group__type="area",
|
||||
role__group__state="active"))
|
||||
.exclude(pk__in=[x.pk for x in active_ads]))
|
||||
extract_last_name = lambda x: x.name_parts()[3]
|
||||
active_ads.sort(key=extract_last_name)
|
||||
|
@ -568,10 +570,11 @@ def by_ad(request, name):
|
|||
ad_name = None
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
responsible = Document.objects.values_list('ad', flat=True).distinct()
|
||||
for p in Person.objects.filter(Q(role__name="ad",
|
||||
for p in Person.objects.filter(Q(role__name__in=("pre-ad", "ad"),
|
||||
role__group__type="area",
|
||||
role__group__state="active")
|
||||
| Q(pk__in=responsible)):
|
||||
| Q(pk__in=responsible)).distinct():
|
||||
print name, p.full_name_as_key()
|
||||
if name == p.full_name_as_key():
|
||||
ad_id = p.id
|
||||
ad_name = p.plain_name()
|
||||
|
|
|
@ -436,7 +436,7 @@ def stable_dictsort(value, arg):
|
|||
def ad_area(user):
|
||||
if user and user.is_authenticated():
|
||||
from ietf.group.models import Group
|
||||
g = Group.objects.filter(role__name="ad", role__person__user=user)
|
||||
g = Group.objects.filter(role__name__in=("pre-ad", "ad"), role__person__user=user)
|
||||
if g:
|
||||
return g[0].acronym
|
||||
return None
|
||||
|
|
|
@ -79,7 +79,7 @@ def has_role(user, role_names):
|
|||
return False
|
||||
|
||||
role_qs = {
|
||||
"Area Director": Q(person=person, name="ad", group__type="area", group__state="active"),
|
||||
"Area Director": Q(person=person, name__in=("pre-ad", "ad"), group__type="area", group__state="active"),
|
||||
"Secretariat": Q(person=person, name="secr", group__acronym="secretariat"),
|
||||
"IANA": Q(person=person, name="auth", group__acronym="iana"),
|
||||
"WG Chair": Q(person=person,name="chair", group__type="wg", group__state="active"),
|
||||
|
@ -97,7 +97,7 @@ def role_required(*role_names):
|
|||
"""View decorator for checking that the user is logged in and
|
||||
has one of the listed roles."""
|
||||
return passes_test_decorator(lambda u: has_role(u, role_names),
|
||||
"Restricted to role%s %s" % ("s" if len(role_names) != 1 else "", ",".join(role_names)))
|
||||
"Restricted to role%s %s" % ("s" if len(role_names) != 1 else "", ", ".join(role_names)))
|
||||
|
||||
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
|
||||
# overwrite group_required
|
||||
|
|
|
@ -58,7 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
<p>Area Director{{ forloop.revcounter|pluralize }}:</p>
|
||||
<table style="margin-left: 2em" class="ietf-wg-table">
|
||||
{% endif %}
|
||||
<tr><td><span class="square bgcolor{{forloop.counter}}"> </span></td> <td><a href="mailto:{{ ad.address }}">{{ ad.person.plain_name }} <{{ ad.address }}></a></td></tr>
|
||||
<tr><td><span class="square bgcolor{{forloop.counter}}"> </span></td> <td><a href="mailto:{{ ad.address }}">{{ ad.person.plain_name }} <{{ ad.address }}></a>{% if ad.incoming %} (Incoming AD){% endif %}</td></tr>
|
||||
{% if forloop.last %}
|
||||
</table>
|
||||
{% endif %}
|
||||
|
|
|
@ -11,7 +11,7 @@ def is_area_director_for_group(person, group):
|
|||
return bool(group.area.area.areadirector_set.filter(person=person).count())
|
||||
|
||||
def is_area_director_for_groupREDESIGN(person, group):
|
||||
return bool(Role.objects.filter(group=group.parent, person=person, name="ad"))
|
||||
return bool(Role.objects.filter(group=group.parent, person=person, name=("ad", "pre-ad")))
|
||||
|
||||
|
||||
def is_group_chair(person, group):
|
||||
|
|
|
@ -99,7 +99,16 @@ def wg_dirREDESIGN(request):
|
|||
|
||||
areas = Group.objects.filter(type="area", state="active").order_by("name")
|
||||
for area in areas:
|
||||
area.ads = sorted(Email.objects.filter(role__group=area, role__name="ad").select_related("person"), key=lambda e: e.person.name_parts()[3])
|
||||
area.ads = []
|
||||
for e in Email.objects.filter(role__group=area, role__name="ad").select_related("person"):
|
||||
e.incoming = False
|
||||
area.ads.append(e)
|
||||
|
||||
for e in Email.objects.filter(role__group=area, role__name="pre-ad").select_related("person"):
|
||||
e.incoming = True
|
||||
area.ads.append(e)
|
||||
|
||||
area.ads.sort(key=lambda e: (e.incoming, e.person.name_parts()[3]))
|
||||
area.wgs = Group.objects.filter(parent=area, type="wg", state="active").order_by("acronym")
|
||||
area.urls = area.groupurl_set.all().order_by("name")
|
||||
for wg in area.wgs:
|
||||
|
|
|
@ -33,6 +33,7 @@ from ietf.utils.history import *
|
|||
# SDOAuthorizedIndividual, WGDelegate
|
||||
|
||||
area_director_role = name(RoleName, "ad", "Area Director")
|
||||
pre_area_director_role = name(RoleName, "pre-ad", "Incoming Area Director")
|
||||
chair_role = name(RoleName, "chair", "Chair")
|
||||
editor_role = name(RoleName, "editor", "Editor")
|
||||
secretary_role = name(RoleName, "secr", "Secretary")
|
||||
|
@ -237,14 +238,22 @@ for o in AreaDirector.objects.all():
|
|||
|
||||
area = Group.objects.get(acronym=o.area.area_acronym.acronym)
|
||||
|
||||
r = Role.objects.filter(name=area_director_role,
|
||||
role_type = area_director_role
|
||||
|
||||
try:
|
||||
if IESGLogin.objects.get(person=o.person).user_level == 4:
|
||||
role_type = pre_area_director_role
|
||||
except IESGLogin.DoesNotExist:
|
||||
pass
|
||||
|
||||
r = Role.objects.filter(name=role_type,
|
||||
person=email.person)
|
||||
if r and r[0].group == "iesg":
|
||||
r[0].group = area
|
||||
r[0].name = area_director_role
|
||||
r[0].name = role_type
|
||||
r[0].save()
|
||||
else:
|
||||
Role.objects.get_or_create(name=area_director_role, group=area, person=email.person, email=email)
|
||||
Role.objects.get_or_create(name=role_type, group=area, person=email.person, email=email)
|
||||
|
||||
# IESGHistory
|
||||
emails_for_time = {}
|
||||
|
|
Loading…
Reference in a new issue