220 lines
8.2 KiB
Python
220 lines
8.2 KiB
Python
# Copyright The IETF Trust 2007, All Rights Reserved
|
|
import datetime
|
|
import json
|
|
from email.utils import parseaddr
|
|
|
|
from django.core.validators import validate_email, ValidationError
|
|
from django.http import HttpResponse, HttpResponseForbidden
|
|
from django.shortcuts import render_to_response, get_object_or_404, redirect
|
|
from django.template import RequestContext
|
|
|
|
from ietf.liaisons.models import LiaisonStatement
|
|
from ietf.liaisons.accounts import (get_person_for_user, can_add_outgoing_liaison,
|
|
can_add_incoming_liaison,
|
|
is_ietfchair, is_iabchair, is_iab_executive_director,
|
|
can_edit_liaison, is_secretariat)
|
|
from ietf.liaisons.forms import liaison_form_factory
|
|
from ietf.liaisons.utils import IETFHM, can_submit_liaison_required, approvable_liaison_statements
|
|
from ietf.liaisons.mails import notify_pending_by_email, send_liaison_by_email
|
|
from ietf.liaisons.fields import select2_id_liaison_json
|
|
|
|
|
|
|
|
@can_submit_liaison_required
|
|
def add_liaison(request, liaison=None):
|
|
if 'incoming' in request.GET.keys() and not can_add_incoming_liaison(request.user):
|
|
return HttpResponseForbidden("Restricted to users who are authorized to submit incoming liaison statements")
|
|
|
|
if request.method == 'POST':
|
|
form = liaison_form_factory(request, data=request.POST.copy(),
|
|
files = request.FILES, liaison=liaison)
|
|
if form.is_valid():
|
|
liaison = form.save()
|
|
if request.POST.get('send', False):
|
|
if not liaison.approved:
|
|
notify_pending_by_email(request, liaison)
|
|
else:
|
|
send_liaison_by_email(request, liaison)
|
|
return redirect('liaison_list')
|
|
else:
|
|
form = liaison_form_factory(request, liaison=liaison)
|
|
|
|
return render_to_response(
|
|
'liaisons/edit.html',
|
|
{'form': form,
|
|
'liaison': liaison},
|
|
context_instance=RequestContext(request),
|
|
)
|
|
|
|
|
|
@can_submit_liaison_required
|
|
def ajax_get_liaison_info(request):
|
|
person = get_person_for_user(request.user)
|
|
|
|
to_entity_id = request.GET.get('to_entity_id', None)
|
|
from_entity_id = request.GET.get('from_entity_id', None)
|
|
|
|
result = {'poc': [], 'cc': [], 'needs_approval': False, 'post_only': False, 'full_list': []}
|
|
|
|
to_error = 'Invalid TO entity id'
|
|
if to_entity_id:
|
|
to_entity = IETFHM.get_entity_by_key(to_entity_id)
|
|
if to_entity:
|
|
to_error = ''
|
|
|
|
from_error = 'Invalid FROM entity id'
|
|
if from_entity_id:
|
|
from_entity = IETFHM.get_entity_by_key(from_entity_id)
|
|
if from_entity:
|
|
from_error = ''
|
|
|
|
if to_error or from_error:
|
|
result.update({'error': '\n'.join([to_error, from_error])})
|
|
else:
|
|
result.update({'error': False,
|
|
'cc': ([i.email() for i in to_entity.get_cc(person=person)] +
|
|
[i.email() for i in from_entity.get_from_cc(person=person)]),
|
|
'poc': [i.email() for i in to_entity.get_poc()],
|
|
'needs_approval': from_entity.needs_approval(person=person),
|
|
'post_only': from_entity.post_only(person=person, user=request.user)})
|
|
if is_secretariat(request.user):
|
|
full_list = [(i.pk, i.email()) for i in set(from_entity.full_user_list())]
|
|
full_list.sort(key=lambda x: x[1])
|
|
full_list = [(person.pk, person.email())] + full_list
|
|
result.update({'full_list': full_list})
|
|
|
|
json_result = json.dumps(result)
|
|
return HttpResponse(json_result, content_type='text/javascript')
|
|
|
|
def normalize_sort(request):
|
|
sort = request.GET.get('sort', "")
|
|
if sort not in ('submitted', 'deadline', 'title', 'to_name', 'from_name'):
|
|
sort = "submitted"
|
|
|
|
# reverse dates
|
|
order_by = "-" + sort if sort in ("submitted", "deadline") else sort
|
|
|
|
return sort, order_by
|
|
|
|
def liaison_list(request):
|
|
sort, order_by = normalize_sort(request)
|
|
liaisons = LiaisonStatement.objects.exclude(approved=None).order_by(order_by).prefetch_related("attachments")
|
|
|
|
can_send_outgoing = can_add_outgoing_liaison(request.user)
|
|
can_send_incoming = can_add_incoming_liaison(request.user)
|
|
|
|
approvable = approvable_liaison_statements(request.user).count()
|
|
|
|
return render_to_response('liaisons/overview.html', {
|
|
"liaisons": liaisons,
|
|
"can_manage": approvable or can_send_incoming or can_send_outgoing,
|
|
"approvable": approvable,
|
|
"can_send_incoming": can_send_incoming,
|
|
"can_send_outgoing": can_send_outgoing,
|
|
"sort": sort,
|
|
}, context_instance=RequestContext(request))
|
|
|
|
def ajax_select2_search_liaison_statements(request):
|
|
q = [w.strip() for w in request.GET.get('q', '').split() if w.strip()]
|
|
|
|
if not q:
|
|
objs = LiaisonStatement.objects.none()
|
|
else:
|
|
qs = LiaisonStatement.objects.exclude(approved=None).all()
|
|
|
|
for t in q:
|
|
qs = qs.filter(title__icontains=t)
|
|
|
|
objs = qs.distinct().order_by("-id")[:20]
|
|
|
|
return HttpResponse(select2_id_liaison_json(objs), content_type='application/json')
|
|
|
|
@can_submit_liaison_required
|
|
def liaison_approval_list(request):
|
|
liaisons = approvable_liaison_statements(request.user).order_by("-submitted")
|
|
|
|
return render_to_response('liaisons/approval_list.html', {
|
|
"liaisons": liaisons,
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
@can_submit_liaison_required
|
|
def liaison_approval_detail(request, object_id):
|
|
liaison = get_object_or_404(approvable_liaison_statements(request.user), pk=object_id)
|
|
|
|
if request.method == 'POST' and request.POST.get('do_approval', False):
|
|
liaison.approved = datetime.datetime.now()
|
|
liaison.save()
|
|
|
|
send_liaison_by_email(request, liaison)
|
|
return redirect('liaison_list')
|
|
|
|
return render_to_response('liaisons/approval_detail.html', {
|
|
"liaison": liaison,
|
|
"is_approving": True,
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
def _can_take_care(liaison, user):
|
|
if not liaison.deadline or liaison.action_taken:
|
|
return False
|
|
|
|
if user.is_authenticated():
|
|
if is_secretariat(user):
|
|
return True
|
|
else:
|
|
return _find_person_in_emails(liaison, get_person_for_user(user))
|
|
return False
|
|
|
|
|
|
def _find_person_in_emails(liaison, person):
|
|
if not person:
|
|
return False
|
|
|
|
emails = ','.join(e for e in [liaison.cc, liaison.to_contact, liaison.to_name,
|
|
liaison.reply_to, liaison.response_contact,
|
|
liaison.technical_contact] if e)
|
|
for email in emails.split(','):
|
|
name, addr = parseaddr(email)
|
|
try:
|
|
validate_email(addr)
|
|
except ValidationError:
|
|
continue
|
|
|
|
if person.email_set.filter(address=addr):
|
|
return True
|
|
elif addr in ('chair@ietf.org', 'iesg@ietf.org') and is_ietfchair(person):
|
|
return True
|
|
elif addr in ('iab@iab.org', 'iab-chair@iab.org') and is_iabchair(person):
|
|
return True
|
|
elif addr in ('execd@iab.org', ) and is_iab_executive_director(person):
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def liaison_detail(request, object_id):
|
|
liaison = get_object_or_404(LiaisonStatement.objects.exclude(approved=None), pk=object_id)
|
|
can_edit = request.user.is_authenticated() and can_edit_liaison(request.user, liaison)
|
|
can_take_care = _can_take_care(liaison, request.user)
|
|
|
|
if request.method == 'POST' and request.POST.get('do_action_taken', None) and can_take_care:
|
|
liaison.action_taken = True
|
|
liaison.save()
|
|
can_take_care = False
|
|
|
|
relations = liaison.liaisonstatement_set.exclude(approved=None)
|
|
|
|
return render_to_response("liaisons/detail.html", {
|
|
"liaison": liaison,
|
|
"can_edit": can_edit,
|
|
"can_take_care": can_take_care,
|
|
"relations": relations,
|
|
}, context_instance=RequestContext(request))
|
|
|
|
def liaison_edit(request, object_id):
|
|
liaison = get_object_or_404(LiaisonStatement, pk=object_id)
|
|
if not (request.user.is_authenticated() and can_edit_liaison(request.user, liaison)):
|
|
return HttpResponseForbidden('You do not have permission to edit this liaison statement')
|
|
return add_liaison(request, liaison=liaison)
|