# Copyright The IETF Trust 2007, All Rights Reserved from django.conf import settings from django.core.urlresolvers import reverse from django.contrib.sites.models import Site from django.http import HttpResponseRedirect, Http404, HttpResponseForbidden, HttpResponseNotAllowed from django.shortcuts import get_object_or_404 from django.shortcuts import render_to_response from django.template import RequestContext from django.core.exceptions import ObjectDoesNotExist from ietf.submit.models import IdSubmissionDetail, Preapproval from ietf.submit.forms import UploadForm, AutoPostForm, MetaDataForm, PreapprovalForm from ietf.submit.utils import * from ietf.utils.mail import send_mail from ietf.ietfauth.decorators import has_role, role_required def submit_index(request): if request.method == 'POST': try: form = UploadForm(request=request, data=request.POST, files=request.FILES) if form.is_valid(): submit = form.save() return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': submit.submission_id, 'submission_hash': submit.get_hash()})) except IOError, e: if "Client read error" in str(e): # The server got an IOError when trying to read POST data form = UploadForm(request=request) form._errors = {} form._errors["__all__"] = form.error_class(["There was a failure receiving the complete form data -- please try again."]) else: raise else: form = UploadForm(request=request) return render_to_response('submit/submit_index.html', {'selected': 'index', 'form': form}, context_instance=RequestContext(request)) def submit_status(request): error = None filename = None if request.method == 'POST': filename = request.POST.get('filename', '') detail = IdSubmissionDetail.objects.filter(filename=filename).order_by('-pk') if detail: return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': detail[0].submission_id})) error = 'No valid history found for %s' % filename return render_to_response('submit/submit_status.html', {'selected': 'status', 'error': error, 'filename': filename}, context_instance=RequestContext(request)) def _can_approve(user, detail): person = get_person_for_user(user) if detail.status_id != INITIAL_VERSION_APPROVAL_REQUESTED or not detail.group_acronym: return None if person in [i.person for i in detail.group_acronym.wgchair_set.all()] or is_secretariat(user): return True return False def _can_force_post(user, detail): if detail.status_id not in [MANUAL_POST_REQUESTED, WAITING_AUTHENTICATION, INITIAL_VERSION_APPROVAL_REQUESTED]: return None if is_secretariat(user): return True return False def _can_cancel(user, detail, submission_hash): if detail.status_id in [CANCELED, POSTED]: return None if is_secretariat(user): return True if submission_hash and detail.get_hash() == submission_hash: return True return False def _can_edit(user, detail, submission_hash): if detail.status_id != UPLOADED: return None if is_secretariat(user): return True if submission_hash and detail.get_hash() == submission_hash: return True return False def draft_status(request, submission_id, submission_hash=None, message=None): detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id) if submission_hash and not detail.get_hash() == submission_hash: raise Http404 validation = DraftValidation(detail) is_valid = validation.is_valid() status = None allow_edit = _can_edit(request.user, detail, submission_hash) can_force_post = _can_force_post(request.user, detail) can_approve = _can_approve(request.user, detail) can_cancel = _can_cancel(request.user, detail, submission_hash) if detail.status_id != UPLOADED: if detail.status_id == CANCELED: message = ('error', 'This submission has been canceled, modification is no longer possible') status = detail.status allow_edit = None if request.method == 'POST' and allow_edit: if request.POST.get('autopost', False): auto_post_form = AutoPostForm(draft=detail, validation=validation, data=request.POST) if auto_post_form.is_valid(): try: preapproval = Preapproval.objects.get(name=detail.filename) except Preapproval.DoesNotExist: preapproval = None if detail.revision == '00' and detail.group_acronym and not preapproval: detail.status_id = INITIAL_VERSION_APPROVAL_REQUESTED detail.save() submitter = auto_post_form.save_submitter_info() subject = 'New draft waiting for approval: %s' % detail.filename from_email = settings.IDSUBMIT_FROM_EMAIL to_email = list(set(i.person.email()[1] for i in detail.group_acronym.wgchair_set.all())) if to_email: authors = detail.tempidauthors_set.exclude(author_order=0).order_by('author_order') send_mail(request, to_email, from_email, subject, 'submit/submission_approval.txt', {'submitter': submitter, 'authors': authors, 'draft': detail, 'domain': Site.objects.get_current().domain}) return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': detail.submission_id})) else: auto_post_form.save(request) detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id) validation = DraftValidation(detail) is_valid = validation.is_valid() status = detail.status can_force_post = _can_force_post(request.user, detail) can_approve = _can_approve(request.user, detail) can_cancel = _can_cancel(request.user, detail, submission_hash) allow_edit = None message = ('success', 'Your submission is pending email authentication. An email has been sent you with instructions.') else: submission_hash = detail.get_hash() if submission_hash: return HttpResponseRedirect(reverse('draft_edit_by_hash', None, kwargs={'submission_id': detail.submission_id, 'submission_hash': submission_hash})) else: return HttpResponseRedirect(reverse(draft_edit, None, kwargs={'submission_id': detail.submission_id })) else: auto_post_form = AutoPostForm(draft=detail, validation=validation) show_notify_button = False if allow_edit == False or can_cancel == False: show_notify_button = True if submission_hash is None and is_secretariat(request.user): submission_hash = detail.get_hash() # we'll need this when rendering the cancel button in the form return render_to_response('submit/draft_status.html', {'selected': 'status', 'detail': detail, 'validation': validation, 'auto_post_form': auto_post_form, 'is_valid': is_valid, 'status': status, 'message': message, 'allow_edit': allow_edit, 'can_force_post': can_force_post, 'can_approve': can_approve, 'can_cancel': can_cancel, 'submission_hash': submission_hash, 'show_notify_button': show_notify_button, }, context_instance=RequestContext(request)) def draft_cancel(request, submission_id, submission_hash=None): if request.method!='POST': return HttpResponseNotAllowed(['POST']) detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id) can_cancel = _can_cancel(request.user, detail, submission_hash) if not can_cancel: if can_cancel == None: raise Http404 return HttpResponseForbidden('You have no permission to perform this action') detail.status_id = CANCELED detail.save() remove_docs(detail) return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': submission_id})) def draft_edit(request, submission_id, submission_hash=None): detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id) can_edit = _can_edit(request.user, detail, submission_hash) if not can_edit: if can_edit == None: raise Http404 return HttpResponseForbidden('You have no permission to perform this action') validation = DraftValidation(detail) validation.validate_wg() if request.method == 'POST': form = MetaDataForm(draft=detail, validation=validation, data=request.POST) if form.is_valid(): form.save(request) return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': detail.submission_id})) else: form = MetaDataForm(draft=detail, validation=validation) return render_to_response('submit/draft_edit.html', {'selected': 'status', 'detail': detail, 'validation': validation, 'form': form, 'settings': settings }, context_instance=RequestContext(request)) def draft_confirm(request, submission_id, auth_key): detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id) message = None if auth_key != detail.auth_key: message = ('error', 'Incorrect authorization key') elif detail.status_id != WAITING_AUTHENTICATION: message = ('error', 'The submission can not be autoposted because it is in state: %s' % detail.status.status_value) else: if request.method=='POST': message = ('success', 'Authorization key accepted. Auto-Post complete') perform_post(request, detail) else: return render_to_response('submit/last_confirmation_step.html', {'detail': detail, }, context_instance=RequestContext(request)) return draft_status(request, submission_id, message=message) def draft_approve(request, submission_id, check_function=_can_approve): if request.method!='POST': return HttpResponseNotAllowed(['POST']) detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id) can_perform = check_function(request.user, detail) if not can_perform: if can_perform == None: raise Http404 return HttpResponseForbidden('You have no permission to perform this action') perform_post(request, detail) return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': submission_id})) def draft_force(request, submission_id): if request.method!='POST': return HttpResponseNotAllowed(['POST']) return draft_approve(request, submission_id, check_function=_can_force_post) def full_url_request(request, submission_id): if request.method!='POST': return HttpResponseNotAllowed(['POST']) detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id) request_full_url(request, detail) message = ('success', 'An email has been sent to draft authors to inform them of the full access url') return draft_status(request, submission_id, message=message) def approvals(request): approvals = get_approvable_submissions(request.user) preapprovals = get_preapprovals(request.user) days = 30 recently_approved = get_recently_approved(request.user, datetime.date.today() - datetime.timedelta(days=days)) return render_to_response('submit/approvals.html', {'selected': 'approvals', 'approvals': approvals, 'preapprovals': preapprovals, 'recently_approved': recently_approved, 'days': days }, context_instance=RequestContext(request)) @role_required("Secretariat", "WG Chair") def add_preapproval(request): groups = Group.objects.filter(type="wg").exclude(state="conclude").order_by("acronym").distinct() if not has_role(request.user, "Secretariat"): groups = groups.filter(role__person=request.user.get_profile()) if request.method == "POST": form = PreapprovalForm(request.POST) form.groups = groups if form.is_valid(): p = Preapproval() p.name = form.cleaned_data["name"] p.by = request.user.get_profile() p.save() return HttpResponseRedirect(urlreverse("submit_approvals") + "#preapprovals") else: form = PreapprovalForm() return render_to_response('submit/add_preapproval.html', {'selected': 'approvals', 'groups': groups, 'form': form }, context_instance=RequestContext(request)) @role_required("Secretariat", "WG Chair") def cancel_preapproval(request, preapproval_id): preapproval = get_object_or_404(Preapproval, pk=preapproval_id) if not preapproval in get_preapprovals(request.user): raise HttpResponseForbidden("You do not have permission to cancel this preapproval.") if request.method == "POST" and request.POST.get("action", "") == "cancel": preapproval.delete() return HttpResponseRedirect(urlreverse("submit_approvals") + "#preapprovals") return render_to_response('submit/cancel_preapproval.html', {'selected': 'approvals', 'preapproval': preapproval }, context_instance=RequestContext(request))