diff --git a/ietf/submit/forms.py b/ietf/submit/forms.py
index 7f58623b2..7b4cf25c6 100644
--- a/ietf/submit/forms.py
+++ b/ietf/submit/forms.py
@@ -416,7 +416,7 @@ class MetaDataForm(AutoPostForm):
if existing_revisions:
expected = max(existing_revisions) + 1
if version_int != expected:
- raise forms.ValidationError('Invalid Version Number (Version %00d is expected)' % expected)
+ raise forms.ValidationError('Invalid Version Number (Version %02d is expected)' % expected)
return version
def clean(self):
diff --git a/ietf/submit/urls.py b/ietf/submit/urls.py
index 4afee3f09..7e39c6d92 100644
--- a/ietf/submit/urls.py
+++ b/ietf/submit/urls.py
@@ -9,6 +9,7 @@ urlpatterns = patterns('ietf.submit.views',
url(r'^status/(?P\d+)/confirm/(?P[a-f\d]+)/$', 'draft_confirm', name='draft_confirm'),
url(r'^status/(?P\d+)/cancel/$', 'draft_cancel', name='draft_cancel'),
url(r'^status/(?P\d+)/approve/$', 'draft_approve', name='draft_approve'),
+ url(r'^status/(?P\d+)/force/$', 'draft_force', name='draft_force'),
)
urlpatterns += patterns('django.views.generic.simple',
diff --git a/ietf/submit/utils.py b/ietf/submit/utils.py
index 7f88ecbf6..3d578b701 100644
--- a/ietf/submit/utils.py
+++ b/ietf/submit/utils.py
@@ -3,7 +3,7 @@ import re
import datetime
from django.conf import settings
-from ietf.idtracker.models import InternetDraft, EmailAddress, PersonOrOrgInfo
+from ietf.idtracker.models import InternetDraft, PersonOrOrgInfo
# Some usefull states
@@ -38,23 +38,37 @@ def perform_post(submission):
updated = True
except InternetDraft.DoesNotExist:
draft = InternetDraft.objects.create(
- title = submission.id_document_name,
- group_id = group_id,
- filename = submission.filename,
- revision = submission.revision,
- revision_date = submission.creation_date,
- file_type = submission.file_type,
- txt_page_count = submission.txt_page_count,
- start_date = datetime.date.today(),
- last_modified_date = datetime.date.today(),
- abstract = submission.abstract,
- status_id = 1, # Active
- intended_status_id = 8, # None
+ title=submission.id_document_name,
+ group_id=group_id,
+ filename=submission.filename,
+ revision=submission.revision,
+ revision_date=submission.creation_date,
+ file_type=submission.file_type,
+ txt_page_count=submission.txt_page_count,
+ start_date=datetime.date.today(),
+ last_modified_date=datetime.date.today(),
+ abstract=submission.abstract,
+ status_id=1, # Active
+ intended_status_id=8, # None
)
move_docs(submission)
submission.status_id = POSTED
submission.save()
+
+def get_person_for_user(user):
+ try:
+ return user.get_profile().person()
+ except:
+ return None
+
+
+def is_secretariat(user):
+ if not user or not user.is_authenticated():
+ return False
+ return bool(user.groups.filter(name='Secretariat'))
+
+
def move_docs(submission):
for ext in submission.file_type.split(','):
source = os.path.join(settings.STAGING_PATH, '%s-%s%s' % (submission.filename, submission.revision, ext))
@@ -118,7 +132,7 @@ class DraftValidation(object):
if existing_revisions:
expected = max(existing_revisions) + 1
if int(revision) != expected:
- self.add_warning('revision', 'Invalid Version Number (Version %00d is expected)' % expected)
+ self.add_warning('revision', 'Invalid Version Number (Version %02d is expected)' % expected)
def validate_authors(self):
if not self.authors:
diff --git a/ietf/submit/views.py b/ietf/submit/views.py
index d0d207f25..0adb2b8e1 100644
--- a/ietf/submit/views.py
+++ b/ietf/submit/views.py
@@ -1,7 +1,7 @@
# Copyright The IETF Trust 2007, All Rights Reserved
from django.conf import settings
from django.core.urlresolvers import reverse
-from django.http import HttpResponseRedirect, Http404
+from django.http import HttpResponseRedirect, Http404, HttpResponseForbidden
from django.shortcuts import get_object_or_404
from django.shortcuts import render_to_response
from django.template import RequestContext
@@ -10,7 +10,10 @@ from django.core.exceptions import ObjectDoesNotExist
from ietf.submit.models import IdSubmissionDetail, IdApprovedDetail
from ietf.submit.forms import UploadForm, AutoPostForm, MetaDataForm
from ietf.submit.utils import (DraftValidation, perform_post,
- UPLOADED, WAITING_AUTHENTICATION, CANCELED, INITIAL_VERSION_APPROVAL_REQUESTED)
+ get_person_for_user, is_secretariat,
+ UPLOADED, WAITING_AUTHENTICATION, CANCELED,
+ INITIAL_VERSION_APPROVAL_REQUESTED,
+ MANUAL_POST_REQUESTED)
from ietf.utils.mail import send_mail
@@ -46,12 +49,30 @@ def submit_status(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):
+ person = get_person_for_user(user)
+ if detail.status_id != MANUAL_POST_REQUESTED:
+ return None
+ if is_secretariat(user):
+ return True
+ return False
+
def draft_status(request, submission_id, message=None):
detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id)
validation = DraftValidation(detail)
is_valid = validation.is_valid()
status = None
allow_edit = True
+ can_force_post = _can_force_post(request.user, detail)
+ can_approve = _can_approve(request.user, detail)
if detail.status_id != UPLOADED:
if detail.status_id == CANCELED:
message=('error', 'This submission has been canceled, modification is no longer possible')
@@ -60,30 +81,29 @@ def draft_status(request, submission_id, message=None):
if request.method=='POST' and allow_edit:
if request.POST.get('autopost', False):
- try:
- approved_detail = IdApprovedDetail.objects.get(filename=detail.filename)
- except ObjectDoesNotExist:
- approved_detail = None
- detail.status_id = INITIAL_VERSION_APPROVAL_REQUESTED
- detail.save()
+ auto_post_form = AutoPostForm(draft=detail, validation=validation, data=request.POST)
+ if auto_post_form.is_valid():
+ try:
+ approved_detail = IdApprovedDetail.objects.get(filename=detail.filename)
+ except ObjectDoesNotExist:
+ approved_detail = None
+ detail.status_id = INITIAL_VERSION_APPROVAL_REQUESTED
+ detail.save()
- if detail.revision == '00' and not approved_detail:
- subject = 'New draft waiting for approval: %s' % detail.filename
- from_email = settings.IDST_FROM_EMAIL
- to_email = []
- if detail.group_acronym:
- to_email += [i.person.email()[1] for i in detail.group_acronym.wgchair_set.all()]
- to_email = list(set(to_email))
- if to_email:
- metadata_form = MetaDataForm(draft=detail, validation=validation)
- send_mail(request, to_email, from_email, subject, 'submit/manual_post_mail.txt',
- {'form': metadata_form, 'draft': detail})
- else:
- auto_post_form = AutoPostForm(draft=detail, validation=validation, data=request.POST)
- if auto_post_form.is_valid():
+ if detail.revision == '00' and not approved_detail:
+ subject = 'New draft waiting for approval: %s' % detail.filename
+ from_email = settings.IDST_FROM_EMAIL
+ to_email = []
+ if detail.group_acronym:
+ to_email += [i.person.email()[1] for i in detail.group_acronym.wgchair_set.all()]
+ to_email = list(set(to_email))
+ if to_email:
+ metadata_form = MetaDataForm(draft=detail, validation=validation)
+ send_mail(request, to_email, from_email, subject, 'submit/manual_post_mail.txt',
+ {'form': metadata_form, 'draft': detail})
+ return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': detail.submission_id}))
+ else:
auto_post_form.save(request)
- return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': detail.submission_id}))
-
else:
return HttpResponseRedirect(reverse(draft_edit, None, kwargs={'submission_id': detail.submission_id}))
else:
@@ -97,6 +117,8 @@ def draft_status(request, submission_id, message=None):
'status': status,
'message': message,
'allow_edit': allow_edit,
+ 'can_force_post': can_force_post,
+ 'can_approve': can_approve,
},
context_instance=RequestContext(request))
@@ -117,6 +139,7 @@ def draft_edit(request, submission_id):
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',
@@ -141,10 +164,17 @@ def draft_confirm(request, submission_id, auth_key):
return draft_status(request, submission_id, message)
-def draft_approve(request, submission_id):
+def draft_approve(request, submission_id, check_function=_can_approve):
detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id)
- if detail.status_id == INITIAL_VERSION_APPROVAL_REQUESTED:
- validation = DraftValidation(detail)
- approved_detail = IdApprovedDetail()
- perform_post(detail)
+ person = get_person_for_user(request.user)
+ 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(detail)
return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': submission_id}))
+
+
+def draft_force(request, submission_id):
+ return draft_approve(request, submission_id, check_function=_can_force_post)
diff --git a/ietf/templates/submit/draft_status.html b/ietf/templates/submit/draft_status.html
index 2612b1c99..942b581e4 100644
--- a/ietf/templates/submit/draft_status.html
+++ b/ietf/templates/submit/draft_status.html
@@ -76,6 +76,10 @@ function confirmCancelation(){
{{ message.1 }}
{% endif %}
+{% if auto_post_form.errors %}
+Please fix errors in the form below
+{% endif %}
+
Check Page
{% if validation.passes_idnits %}
@@ -146,7 +150,7 @@ returned to the submitter.
{% if allow_edit %}
-
@@ -181,13 +185,21 @@ returned to the submitter.
{% endif %}
{% endif %}
-{% ifequal status.status_value "Initial Version Approval Requested" %}
+{% if can_approve %}
-{% endifequal %}
+{% endif %}
+
+{% if can_force_post %}
+
+
+
+{% endif %}
The IETF is an organized activity of the Internet Society