Skip to content

Commit cca4924

Browse files
committed
Create views skel for private area.
Create new decorators to test if user is nocom member News function in Group model to get the group members Move util functions to utils.py module Improve passes_test_decorator function so test_func accept more params. See ietf-tools#919 - Legacy-Id: 5161
1 parent 34cd150 commit cca4924

9 files changed

Lines changed: 113 additions & 12 deletions

File tree

ietf/group/models.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Copyright The IETF Trust 2007, All Rights Reserved
22

33
from django.db import models
4+
from django.db.models import Q
5+
46
from ietf.name.models import *
57
from ietf.person.models import Email, Person
68

@@ -53,10 +55,19 @@ def is_chair(self, user):
5355
else:
5456
return False
5557

58+
def is_member(self, user):
59+
members = self.get_members()
60+
users = [member.person.user for member in members]
61+
return user in users
62+
5663
def get_chair(self):
5764
chair = self.role_set.filter(name__slug='chair')[:1]
5865
return chair and chair[0] or None
5966

67+
def get_members(self):
68+
members = self.role_set.filter(Q(name__slug='member') | Q(name__slug='chair'))
69+
return members
70+
6071
class GroupHistory(GroupInfo):
6172
group = models.ForeignKey(Group, related_name='history_set')
6273
acronym = models.CharField(max_length=40)
@@ -68,8 +79,9 @@ class GroupURL(models.Model):
6879
group = models.ForeignKey(Group)
6980
name = models.CharField(max_length=255)
7081
url = models.URLField(verify_exists=False)
82+
7183
def __unicode__(self):
72-
return u"%s (%s)" % (self.url, self.name)
84+
return u"%s (%s)" % (self.url, self.name)
7385

7486
class GroupMilestone(models.Model):
7587
group = models.ForeignKey(Group)

ietf/ietfauth/decorators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def decorate(view_func):
4747
def inner(request, *args, **kwargs):
4848
if not request.user.is_authenticated():
4949
return HttpResponseRedirect('%s?%s=%s' % (settings.LOGIN_URL, REDIRECT_FIELD_NAME, urlquote(request.get_full_path())))
50-
elif test_func(request.user):
50+
elif test_func(request.user, *args, **kwargs):
5151
return view_func(request, *args, **kwargs)
5252
else:
5353
return HttpResponseForbidden(message)
@@ -109,7 +109,7 @@ def role_required(*role_names):
109109
has one of the listed roles."""
110110
return passes_test_decorator(lambda u: has_role(u, role_names),
111111
"Restricted to role%s %s" % ("s" if len(role_names) != 1 else "", ", ".join(role_names)))
112-
112+
113113
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
114114
# overwrite group_required
115115
group_required = lambda *group_names: role_required(*[n.replace("Area_Director", "Area Director") for n in group_names])

ietf/nomcom/decorators.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from ietf.ietfauth.decorators import passes_test_decorator
2+
3+
from ietf.nomcom.utils import get_nomcom_by_year
4+
5+
6+
def member_required(role=None):
7+
def _is_nomcom_member(user, *args, **kwargs):
8+
year = kwargs.get('year', None)
9+
if year:
10+
nomcom = get_nomcom_by_year(year=year)
11+
if role == 'chair':
12+
return nomcom.group.is_chair(user)
13+
else:
14+
return nomcom.group.is_member(user)
15+
return False
16+
return passes_test_decorator(_is_nomcom_member, 'Restricted to NomCom %s' % role)

ietf/nomcom/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
EditMembersForm, EditMembersFormPreview
44

55
urlpatterns = patterns('ietf.nomcom.views',
6+
url(r'^(?P<year>\d{4})/private/$', 'private_index', name='nomcom_private_index'),
7+
url(r'^(?P<year>\d{4})/private/merge/$', 'private_merge', name='nomcom_private_merge'),
68
url(r'^(?P<year>\d{4})/$', 'index', name='nomcom_index'),
79
url(r'^(?P<year>\d{4})/requirements/$', 'requirements', name='nomcom_requirements'),
810
url(r'^(?P<year>\d{4})/questionnaires/$', 'questionnaires', name='nomcom_questionnaires'),

ietf/nomcom/utils.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from django.shortcuts import get_object_or_404
2+
from django.core.exceptions import PermissionDenied
23

34
from ietf.dbtemplate.models import DBTemplate
45

@@ -12,6 +13,25 @@
1213
DEFAULT_NOMCOM_TEMPLATES = [HOME_TEMPLATE, INEXISTENT_PERSON_TEMPLATE, NOMINATION_EMAIL_TEMPLATE, NOMINEE_EMAIL_TEMPLATE]
1314

1415

16+
def get_nomcom_by_year(year):
17+
from ietf.nomcom.models import NomCom
18+
return get_object_or_404(NomCom,
19+
group__acronym__icontains=year,
20+
group__state__slug='active')
21+
22+
23+
def is_nomcom_member(user, nomcom):
24+
is_group_member = nomcom.group.is_member(user)
25+
if not is_group_member:
26+
raise PermissionDenied("Must be nomcom member")
27+
28+
29+
def is_nomcom_chair(user, nomcom):
30+
is_group_chair = nomcom.group.is_chair(user)
31+
if not is_group_chair:
32+
raise PermissionDenied("Must be nomcom chair")
33+
34+
1535
def initialize_templates_for_group(group):
1636
for template_name in DEFAULT_NOMCOM_TEMPLATES:
1737
template_path = MAIN_NOMCOM_TEMPLATE_PATH + template_name
@@ -47,10 +67,3 @@ def initialize_requirements_for_position(position):
4767
variables=template.variables,
4868
type_id=template.type_id,
4969
content=template.content)
50-
51-
52-
def get_nomcom_by_year(year):
53-
from ietf.nomcom.models import NomCom
54-
return get_object_or_404(NomCom,
55-
group__acronym__icontains=year,
56-
group__state__slug='active')

ietf/nomcom/views.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
from django.utils import simplejson
88

99

10-
from ietf.nomcom.utils import get_nomcom_by_year, HOME_TEMPLATE
10+
from ietf.nomcom.utils import get_nomcom_by_year, is_nomcom_member, \
11+
is_nomcom_chair, HOME_TEMPLATE
12+
from ietf.nomcom.decorators import member_required
1113
from ietf.nomcom.forms import EditPublicKeyForm, NominateForm
1214
from ietf.nomcom.models import Position
1315

@@ -23,6 +25,26 @@ def index(request, year):
2325
'template': template}, RequestContext(request))
2426

2527

28+
@member_required(role='chair')
29+
def private_index(request, year):
30+
nomcom = get_nomcom_by_year(year)
31+
is_nomcom_member(request.user, nomcom)
32+
return render_to_response('nomcom/private_index.html',
33+
{'nomcom': nomcom,
34+
'year': year,
35+
'selected': 'index'}, RequestContext(request))
36+
37+
38+
@member_required(role='member')
39+
def private_merge(request, year):
40+
nomcom = get_nomcom_by_year(year)
41+
is_nomcom_member(request.user, nomcom)
42+
return render_to_response('nomcom/private_merge.html',
43+
{'nomcom': nomcom,
44+
'year': year,
45+
'selected': 'merge'}, RequestContext(request))
46+
47+
2648
def requirements(request, year):
2749
nomcom = get_nomcom_by_year(year)
2850
positions = nomcom.position_set.all()
@@ -72,9 +94,10 @@ def comments(request, year):
7294
'selected': 'comments'}, RequestContext(request))
7395

7496

75-
@login_required
97+
@member_required(role='chair')
7698
def edit_publickey(request, year):
7799
nomcom = get_nomcom_by_year(year)
100+
is_nomcom_chair(request.user, nomcom)
78101
is_group_chair = nomcom.group.is_chair(request.user)
79102
if not is_group_chair:
80103
return HttpResponseForbidden("Must be group chair")
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{% extends "nomcom/nomcom_base.html" %}
2+
3+
{% block content %}
4+
5+
<h1>Nomcom {{ year }} Private Area</h1>
6+
7+
<div class="ietf-navset">
8+
{% if selected == "index" %}<span class="selected">List of nominees</span>{% else %}<a href="{% url nomcom_private_index year %}">List of nominees</a>{% endif %} |
9+
{% if selected == "merge" %}<span class="selected">Merge nominee email addr{% else %}<a href="{% url nomcom_private_merge year %}">Merge nominee email addr</a>{% endif %} |
10+
</div>
11+
12+
13+
{% block nomcom_content %}
14+
{% endblock %}
15+
16+
{% endblock %}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{% extends "nomcom/nomcom_private_base.html" %}
2+
3+
{% block subtitle %} - Administration {% endblock %}
4+
5+
{% block nomcom_content %}
6+
7+
<h2>Nomine administration</h2>
8+
<p>The following is a list of registered nominees. (You can <a href="#"> request confirmation<a> from nominees if they haven't
9+
replied to the nomination notification they have received.)</p>
10+
{% endblock %}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% extends "nomcom/nomcom_private_base.html" %}
2+
3+
{% block subtitle %} - Merging nominee email addresses {% endblock %}
4+
5+
{% block nomcom_content %}
6+
7+
<h2>Merging nominee email addresses</h2>
8+
<p>If a nominee has been nominated with multiple email addresses, the nominee will appear multiple times in the nomination list, as the email address is used as the unique identifier for each nominee. In order to permit comments and nominations to be submitted under multiple email addresses, there is a list of secondary email addresses which needs to be kept up-to-date. When nominations of one particular nominee have already been made under different email addresses, the nomination comments from the secondary address also needs to be merged with those under the primary address. It doesn't matter particularly which email address is used as primary, as far as the nominee information maintenance goes, but it's probably handier for the nomcom if the primary address is the one which the nominee prefers at the time.</p>
9+
{% endblock %}

0 commit comments

Comments
 (0)