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:
parent
34cd15018e
commit
cca4924597
|
@ -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)
|
||||
|
|
|
@ -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
16
ietf/nomcom/decorators.py
Normal 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)
|
|
@ -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'),
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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")
|
||||
|
|
16
ietf/templates/nomcom/nomcom_private_base.html
Normal file
16
ietf/templates/nomcom/nomcom_private_base.html
Normal 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 %}
|
10
ietf/templates/nomcom/private_index.html
Normal file
10
ietf/templates/nomcom/private_index.html
Normal 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 %}
|
9
ietf/templates/nomcom/private_merge.html
Normal file
9
ietf/templates/nomcom/private_merge.html
Normal 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 %}
|
Loading…
Reference in a new issue