Skip to content

Commit cfaed84

Browse files
committed
Authenticated post actions. Fixes ietf-tools#597
- Legacy-Id: 2850
1 parent 3d08afd commit cfaed84

5 files changed

Lines changed: 105 additions & 48 deletions

File tree

ietf/submit/forms.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ def clean_version(self):
416416
if existing_revisions:
417417
expected = max(existing_revisions) + 1
418418
if version_int != expected:
419-
raise forms.ValidationError('Invalid Version Number (Version %00d is expected)' % expected)
419+
raise forms.ValidationError('Invalid Version Number (Version %02d is expected)' % expected)
420420
return version
421421

422422
def clean(self):

ietf/submit/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
url(r'^status/(?P<submission_id>\d+)/confirm/(?P<auth_key>[a-f\d]+)/$', 'draft_confirm', name='draft_confirm'),
1010
url(r'^status/(?P<submission_id>\d+)/cancel/$', 'draft_cancel', name='draft_cancel'),
1111
url(r'^status/(?P<submission_id>\d+)/approve/$', 'draft_approve', name='draft_approve'),
12+
url(r'^status/(?P<submission_id>\d+)/force/$', 'draft_force', name='draft_force'),
1213
)
1314

1415
urlpatterns += patterns('django.views.generic.simple',

ietf/submit/utils.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import datetime
44

55
from django.conf import settings
6-
from ietf.idtracker.models import InternetDraft, EmailAddress, PersonOrOrgInfo
6+
from ietf.idtracker.models import InternetDraft, PersonOrOrgInfo
77

88

99
# Some usefull states
@@ -38,23 +38,37 @@ def perform_post(submission):
3838
updated = True
3939
except InternetDraft.DoesNotExist:
4040
draft = InternetDraft.objects.create(
41-
title = submission.id_document_name,
42-
group_id = group_id,
43-
filename = submission.filename,
44-
revision = submission.revision,
45-
revision_date = submission.creation_date,
46-
file_type = submission.file_type,
47-
txt_page_count = submission.txt_page_count,
48-
start_date = datetime.date.today(),
49-
last_modified_date = datetime.date.today(),
50-
abstract = submission.abstract,
51-
status_id = 1, # Active
52-
intended_status_id = 8, # None
41+
title=submission.id_document_name,
42+
group_id=group_id,
43+
filename=submission.filename,
44+
revision=submission.revision,
45+
revision_date=submission.creation_date,
46+
file_type=submission.file_type,
47+
txt_page_count=submission.txt_page_count,
48+
start_date=datetime.date.today(),
49+
last_modified_date=datetime.date.today(),
50+
abstract=submission.abstract,
51+
status_id=1, # Active
52+
intended_status_id=8, # None
5353
)
5454
move_docs(submission)
5555
submission.status_id = POSTED
5656
submission.save()
5757

58+
59+
def get_person_for_user(user):
60+
try:
61+
return user.get_profile().person()
62+
except:
63+
return None
64+
65+
66+
def is_secretariat(user):
67+
if not user or not user.is_authenticated():
68+
return False
69+
return bool(user.groups.filter(name='Secretariat'))
70+
71+
5872
def move_docs(submission):
5973
for ext in submission.file_type.split(','):
6074
source = os.path.join(settings.STAGING_PATH, '%s-%s%s' % (submission.filename, submission.revision, ext))
@@ -118,7 +132,7 @@ def validate_revision(self):
118132
if existing_revisions:
119133
expected = max(existing_revisions) + 1
120134
if int(revision) != expected:
121-
self.add_warning('revision', 'Invalid Version Number (Version %00d is expected)' % expected)
135+
self.add_warning('revision', 'Invalid Version Number (Version %02d is expected)' % expected)
122136

123137
def validate_authors(self):
124138
if not self.authors:

ietf/submit/views.py

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copyright The IETF Trust 2007, All Rights Reserved
22
from django.conf import settings
33
from django.core.urlresolvers import reverse
4-
from django.http import HttpResponseRedirect, Http404
4+
from django.http import HttpResponseRedirect, Http404, HttpResponseForbidden
55
from django.shortcuts import get_object_or_404
66
from django.shortcuts import render_to_response
77
from django.template import RequestContext
@@ -10,7 +10,10 @@
1010
from ietf.submit.models import IdSubmissionDetail, IdApprovedDetail
1111
from ietf.submit.forms import UploadForm, AutoPostForm, MetaDataForm
1212
from ietf.submit.utils import (DraftValidation, perform_post,
13-
UPLOADED, WAITING_AUTHENTICATION, CANCELED, INITIAL_VERSION_APPROVAL_REQUESTED)
13+
get_person_for_user, is_secretariat,
14+
UPLOADED, WAITING_AUTHENTICATION, CANCELED,
15+
INITIAL_VERSION_APPROVAL_REQUESTED,
16+
MANUAL_POST_REQUESTED)
1417
from ietf.utils.mail import send_mail
1518

1619

@@ -46,12 +49,30 @@ def submit_status(request):
4649

4750

4851

52+
def _can_approve(user, detail):
53+
person = get_person_for_user(user)
54+
if detail.status_id != INITIAL_VERSION_APPROVAL_REQUESTED or not detail.group_acronym:
55+
return None
56+
if person in [i.person for i in detail.group_acronym.wgchair_set.all()] or is_secretariat(user):
57+
return True
58+
return False
59+
60+
def _can_force_post(user, detail):
61+
person = get_person_for_user(user)
62+
if detail.status_id != MANUAL_POST_REQUESTED:
63+
return None
64+
if is_secretariat(user):
65+
return True
66+
return False
67+
4968
def draft_status(request, submission_id, message=None):
5069
detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id)
5170
validation = DraftValidation(detail)
5271
is_valid = validation.is_valid()
5372
status = None
5473
allow_edit = True
74+
can_force_post = _can_force_post(request.user, detail)
75+
can_approve = _can_approve(request.user, detail)
5576
if detail.status_id != UPLOADED:
5677
if detail.status_id == CANCELED:
5778
message=('error', 'This submission has been canceled, modification is no longer possible')
@@ -60,30 +81,29 @@ def draft_status(request, submission_id, message=None):
6081

6182
if request.method=='POST' and allow_edit:
6283
if request.POST.get('autopost', False):
63-
try:
64-
approved_detail = IdApprovedDetail.objects.get(filename=detail.filename)
65-
except ObjectDoesNotExist:
66-
approved_detail = None
67-
detail.status_id = INITIAL_VERSION_APPROVAL_REQUESTED
68-
detail.save()
69-
70-
if detail.revision == '00' and not approved_detail:
71-
subject = 'New draft waiting for approval: %s' % detail.filename
72-
from_email = settings.IDST_FROM_EMAIL
73-
to_email = []
74-
if detail.group_acronym:
75-
to_email += [i.person.email()[1] for i in detail.group_acronym.wgchair_set.all()]
76-
to_email = list(set(to_email))
77-
if to_email:
78-
metadata_form = MetaDataForm(draft=detail, validation=validation)
79-
send_mail(request, to_email, from_email, subject, 'submit/manual_post_mail.txt',
80-
{'form': metadata_form, 'draft': detail})
81-
else:
82-
auto_post_form = AutoPostForm(draft=detail, validation=validation, data=request.POST)
83-
if auto_post_form.is_valid():
84+
auto_post_form = AutoPostForm(draft=detail, validation=validation, data=request.POST)
85+
if auto_post_form.is_valid():
86+
try:
87+
approved_detail = IdApprovedDetail.objects.get(filename=detail.filename)
88+
except ObjectDoesNotExist:
89+
approved_detail = None
90+
detail.status_id = INITIAL_VERSION_APPROVAL_REQUESTED
91+
detail.save()
92+
93+
if detail.revision == '00' and not approved_detail:
94+
subject = 'New draft waiting for approval: %s' % detail.filename
95+
from_email = settings.IDST_FROM_EMAIL
96+
to_email = []
97+
if detail.group_acronym:
98+
to_email += [i.person.email()[1] for i in detail.group_acronym.wgchair_set.all()]
99+
to_email = list(set(to_email))
100+
if to_email:
101+
metadata_form = MetaDataForm(draft=detail, validation=validation)
102+
send_mail(request, to_email, from_email, subject, 'submit/manual_post_mail.txt',
103+
{'form': metadata_form, 'draft': detail})
104+
return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': detail.submission_id}))
105+
else:
84106
auto_post_form.save(request)
85-
return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': detail.submission_id}))
86-
87107
else:
88108
return HttpResponseRedirect(reverse(draft_edit, None, kwargs={'submission_id': detail.submission_id}))
89109
else:
@@ -97,6 +117,8 @@ def draft_status(request, submission_id, message=None):
97117
'status': status,
98118
'message': message,
99119
'allow_edit': allow_edit,
120+
'can_force_post': can_force_post,
121+
'can_approve': can_approve,
100122
},
101123
context_instance=RequestContext(request))
102124

@@ -117,6 +139,7 @@ def draft_edit(request, submission_id):
117139
form = MetaDataForm(draft=detail, validation=validation, data=request.POST)
118140
if form.is_valid():
119141
form.save(request)
142+
return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': detail.submission_id}))
120143
else:
121144
form = MetaDataForm(draft=detail, validation=validation)
122145
return render_to_response('submit/draft_edit.html',
@@ -141,10 +164,17 @@ def draft_confirm(request, submission_id, auth_key):
141164
return draft_status(request, submission_id, message)
142165

143166

144-
def draft_approve(request, submission_id):
167+
def draft_approve(request, submission_id, check_function=_can_approve):
145168
detail = get_object_or_404(IdSubmissionDetail, submission_id=submission_id)
146-
if detail.status_id == INITIAL_VERSION_APPROVAL_REQUESTED:
147-
validation = DraftValidation(detail)
148-
approved_detail = IdApprovedDetail()
149-
perform_post(detail)
169+
person = get_person_for_user(request.user)
170+
can_perform = check_function(request.user, detail)
171+
if not can_perform:
172+
if can_perform == None:
173+
raise Http404
174+
return HttpResponseForbidden('You have no permission to perform this action')
175+
perform_post(detail)
150176
return HttpResponseRedirect(reverse(draft_status, None, kwargs={'submission_id': submission_id}))
177+
178+
179+
def draft_force(request, submission_id):
180+
return draft_approve(request, submission_id, check_function=_can_force_post)

ietf/templates/submit/draft_status.html

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ <h2>Status of the submission: {{ status.status_value }}</h2>
7676
<div class="info-message-{{ message.0 }}">{{ message.1 }}</div>
7777
{% endif %}
7878

79+
{% if auto_post_form.errors %}
80+
<div class="info-message-error">Please fix errors in the form below</div>
81+
{% endif %}
82+
7983
<h2>Check Page</h2>
8084
<p>
8185
{% if validation.passes_idnits %}
@@ -146,7 +150,7 @@ <h3>Meta-Data errors found</h3>
146150
</table>
147151

148152
{% if allow_edit %}
149-
<form method="post" action="" name="auto_post_form">
153+
<form method="post" action="">
150154
<input type="submit" value="Adjust Meta-Data" value="adjust" /> (Leads to manual post by the Secretariat)
151155
</form>
152156

@@ -181,13 +185,21 @@ <h3>Submitter information</h3>
181185
{% endif %}
182186
{% endif %}
183187

184-
{% ifequal status.status_value "Initial Version Approval Requested" %}
188+
{% if can_approve %}
185189
<p>
186190
<form method="post" action="/submit/status/{{ detail.submission_id }}/approve/">
187191
<input type="submit" value="Approve this submission" />
188192
</form>
189193
</p>
190-
{% endifequal %}
194+
{% endif %}
195+
196+
{% if can_force_post %}
197+
<p>
198+
<form method="post" action="/submit/status/{{ detail.submission_id }}/force/">
199+
<input type="submit" value="Force post" />
200+
</form>
201+
</p>
202+
{% endif %}
191203

192204
<p>
193205
The IETF is an organized activity of the <a href="http://www.isoc.org">Internet Society</a>

0 commit comments

Comments
 (0)