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 #919
 - Legacy-Id: 5161
This commit is contained in:
Emilio Jiménez 2012-12-29 00:52:52 +00:00
parent 34cd15018e
commit cca4924597
9 changed files with 113 additions and 12 deletions

View file

@ -1,6 +1,8 @@
# Copyright The IETF Trust 2007, All Rights Reserved
from django.db import models
from django.db.models import Q
from ietf.name.models import *
from ietf.person.models import Email, Person
@ -53,10 +55,19 @@ class Group(GroupInfo):
else:
return False
def is_member(self, user):
members = self.get_members()
users = [member.person.user for member in members]
return user in users
def get_chair(self):
chair = self.role_set.filter(name__slug='chair')[:1]
return chair and chair[0] or None
def get_members(self):
members = self.role_set.filter(Q(name__slug='member') | Q(name__slug='chair'))
return members
class GroupHistory(GroupInfo):
group = models.ForeignKey(Group, related_name='history_set')
acronym = models.CharField(max_length=40)
@ -68,8 +79,9 @@ class GroupURL(models.Model):
group = models.ForeignKey(Group)
name = models.CharField(max_length=255)
url = models.URLField(verify_exists=False)
def __unicode__(self):
return u"%s (%s)" % (self.url, self.name)
return u"%s (%s)" % (self.url, self.name)
class GroupMilestone(models.Model):
group = models.ForeignKey(Group)

View file

@ -47,7 +47,7 @@ def passes_test_decorator(test_func, message):
def inner(request, *args, **kwargs):
if not request.user.is_authenticated():
return HttpResponseRedirect('%s?%s=%s' % (settings.LOGIN_URL, REDIRECT_FIELD_NAME, urlquote(request.get_full_path())))
elif test_func(request.user):
elif test_func(request.user, *args, **kwargs):
return view_func(request, *args, **kwargs)
else:
return HttpResponseForbidden(message)
@ -109,7 +109,7 @@ def role_required(*role_names):
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)))
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
# overwrite group_required
group_required = lambda *group_names: role_required(*[n.replace("Area_Director", "Area Director") for n in group_names])

16
ietf/nomcom/decorators.py Normal file
View file

@ -0,0 +1,16 @@
from ietf.ietfauth.decorators import passes_test_decorator
from ietf.nomcom.utils import get_nomcom_by_year
def member_required(role=None):
def _is_nomcom_member(user, *args, **kwargs):
year = kwargs.get('year', None)
if year:
nomcom = get_nomcom_by_year(year=year)
if role == 'chair':
return nomcom.group.is_chair(user)
else:
return nomcom.group.is_member(user)
return False
return passes_test_decorator(_is_nomcom_member, 'Restricted to NomCom %s' % role)

View file

@ -3,6 +3,8 @@ from ietf.nomcom.forms import EditChairForm, EditChairFormPreview, \
EditMembersForm, EditMembersFormPreview
urlpatterns = patterns('ietf.nomcom.views',
url(r'^(?P<year>\d{4})/private/$', 'private_index', name='nomcom_private_index'),
url(r'^(?P<year>\d{4})/private/merge/$', 'private_merge', name='nomcom_private_merge'),
url(r'^(?P<year>\d{4})/$', 'index', name='nomcom_index'),
url(r'^(?P<year>\d{4})/requirements/$', 'requirements', name='nomcom_requirements'),
url(r'^(?P<year>\d{4})/questionnaires/$', 'questionnaires', name='nomcom_questionnaires'),

View file

@ -1,4 +1,5 @@
from django.shortcuts import get_object_or_404
from django.core.exceptions import PermissionDenied
from ietf.dbtemplate.models import DBTemplate
@ -12,6 +13,25 @@ NOMINATION_EMAIL_TEMPLATE = 'email/new_nomination.txt'
DEFAULT_NOMCOM_TEMPLATES = [HOME_TEMPLATE, INEXISTENT_PERSON_TEMPLATE, NOMINATION_EMAIL_TEMPLATE, NOMINEE_EMAIL_TEMPLATE]
def get_nomcom_by_year(year):
from ietf.nomcom.models import NomCom
return get_object_or_404(NomCom,
group__acronym__icontains=year,
group__state__slug='active')
def is_nomcom_member(user, nomcom):
is_group_member = nomcom.group.is_member(user)
if not is_group_member:
raise PermissionDenied("Must be nomcom member")
def is_nomcom_chair(user, nomcom):
is_group_chair = nomcom.group.is_chair(user)
if not is_group_chair:
raise PermissionDenied("Must be nomcom chair")
def initialize_templates_for_group(group):
for template_name in DEFAULT_NOMCOM_TEMPLATES:
template_path = MAIN_NOMCOM_TEMPLATE_PATH + template_name
@ -47,10 +67,3 @@ def initialize_requirements_for_position(position):
variables=template.variables,
type_id=template.type_id,
content=template.content)
def get_nomcom_by_year(year):
from ietf.nomcom.models import NomCom
return get_object_or_404(NomCom,
group__acronym__icontains=year,
group__state__slug='active')

View file

@ -7,7 +7,9 @@ from django.template.loader import render_to_string
from django.utils import simplejson
from ietf.nomcom.utils import get_nomcom_by_year, HOME_TEMPLATE
from ietf.nomcom.utils import get_nomcom_by_year, is_nomcom_member, \
is_nomcom_chair, HOME_TEMPLATE
from ietf.nomcom.decorators import member_required
from ietf.nomcom.forms import EditPublicKeyForm, NominateForm
from ietf.nomcom.models import Position
@ -23,6 +25,26 @@ def index(request, year):
'template': template}, RequestContext(request))
@member_required(role='chair')
def private_index(request, year):
nomcom = get_nomcom_by_year(year)
is_nomcom_member(request.user, nomcom)
return render_to_response('nomcom/private_index.html',
{'nomcom': nomcom,
'year': year,
'selected': 'index'}, RequestContext(request))
@member_required(role='member')
def private_merge(request, year):
nomcom = get_nomcom_by_year(year)
is_nomcom_member(request.user, nomcom)
return render_to_response('nomcom/private_merge.html',
{'nomcom': nomcom,
'year': year,
'selected': 'merge'}, RequestContext(request))
def requirements(request, year):
nomcom = get_nomcom_by_year(year)
positions = nomcom.position_set.all()
@ -72,9 +94,10 @@ def comments(request, year):
'selected': 'comments'}, RequestContext(request))
@login_required
@member_required(role='chair')
def edit_publickey(request, year):
nomcom = get_nomcom_by_year(year)
is_nomcom_chair(request.user, nomcom)
is_group_chair = nomcom.group.is_chair(request.user)
if not is_group_chair:
return HttpResponseForbidden("Must be group chair")

View file

@ -0,0 +1,16 @@
{% extends "nomcom/nomcom_base.html" %}
{% block content %}
<h1>Nomcom {{ year }} Private Area</h1>
<div class="ietf-navset">
{% if selected == "index" %}<span class="selected">List of nominees</span>{% else %}<a href="{% url nomcom_private_index year %}">List of nominees</a>{% endif %} |
{% if selected == "merge" %}<span class="selected">Merge nominee email addr{% else %}<a href="{% url nomcom_private_merge year %}">Merge nominee email addr</a>{% endif %} |
</div>
{% block nomcom_content %}
{% endblock %}
{% endblock %}

View file

@ -0,0 +1,10 @@
{% extends "nomcom/nomcom_private_base.html" %}
{% block subtitle %} - Administration {% endblock %}
{% block nomcom_content %}
<h2>Nomine administration</h2>
<p>The following is a list of registered nominees. (You can <a href="#"> request confirmation<a> from nominees if they haven't
replied to the nomination notification they have received.)</p>
{% endblock %}

View file

@ -0,0 +1,9 @@
{% extends "nomcom/nomcom_private_base.html" %}
{% block subtitle %} - Merging nominee email addresses {% endblock %}
{% block nomcom_content %}
<h2>Merging nominee email addresses</h2>
<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>
{% endblock %}