From dcd372a928c6356ab06bad3309b4d4bbf17f8fa9 Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Thu, 8 Jul 2021 19:16:58 +0000 Subject: [PATCH] Restrict editor access in all states but proposed. - Legacy-Id: 19205 --- ietf/doc/tests_bofreq.py | 29 ++++++++++++++++++++++++- ietf/doc/utils.py | 5 +++-- ietf/doc/views_bofreq.py | 9 +++++--- ietf/doc/views_doc.py | 4 ++-- ietf/ietfauth/utils.py | 11 ++++++++++ ietf/templates/doc/document_bofreq.html | 10 ++++----- 6 files changed, 55 insertions(+), 13 deletions(-) diff --git a/ietf/doc/tests_bofreq.py b/ietf/doc/tests_bofreq.py index 460734450..d5e0ac7dd 100644 --- a/ietf/doc/tests_bofreq.py +++ b/ietf/doc/tests_bofreq.py @@ -80,7 +80,7 @@ This test section has some text. self.write_bofreq_file(doc) editors = bofreq_editors(doc) responsible = bofreq_responsible(doc) - url = urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=doc)) + url = urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=doc.name)) r = self.client.get(url) self.assertContains(r,'Version: 01',status_code=200) q = PyQuery(r.content) @@ -365,4 +365,31 @@ This test section has some text. self.assertEqual(r.status_code, 200) q = PyQuery(r.content) self.assertTrue(q('form div.has-error')) + + def test_post_proposed_restrictions(self): + states = State.objects.filter(type_id='bofreq').exclude(slug='proposed') + bofreq = BofreqFactory() + editor = bofreq_editors(bofreq).first() + + for view in ('submit', 'change_editors', 'edit_title'): + url = urlreverse(f'ietf.doc.views_bofreq.{view}', kwargs=dict(name=bofreq.name)) + for state in states: + bofreq.set_state(state) + for username in ('secretary', 'ad', 'iab-member'): + self.client.login(username=username, password=username+'+password') + r = self.client.get(url) + self.assertEqual(r.status_code,200) + self.client.logout() + self.client.login(username=editor.user.username, password=editor.user.username+'+password') + r = self.client.get(url) + self.assertEqual(r.status_code, 403, f'editor should not be able to use {view} in state {state.slug}') + self.client.logout() + + url = urlreverse('ietf.doc.views_doc.document_main', kwargs=dict(name=bofreq.name)) + self.client.login(username=editor.user.username, password=editor.user.username+'+password') + r = self.client.get(url) + self.assertEqual(r.status_code,200) + q = PyQuery(r.content) + self.assertEqual(0, len(q('td.edit>a.btn'))) + self.assertEqual([],q('#change-request')) diff --git a/ietf/doc/utils.py b/ietf/doc/utils.py index 3b8dd1332..59a02c416 100644 --- a/ietf/doc/utils.py +++ b/ietf/doc/utils.py @@ -29,7 +29,7 @@ from ietf.doc.models import DocEvent, ConsensusDocEvent, BallotDocEvent, IRSGBal from ietf.doc.models import TelechatDocEvent, DocumentActionHolder, EditedAuthorsDocEvent from ietf.name.models import DocReminderTypeName, DocRelationshipName from ietf.group.models import Role, Group -from ietf.ietfauth.utils import has_role, is_authorized_in_doc_stream, is_individual_draft_author +from ietf.ietfauth.utils import has_role, is_authorized_in_doc_stream, is_individual_draft_author, is_bofreq_editor from ietf.person.models import Person from ietf.review.models import ReviewWish from ietf.utils import draft, text @@ -152,7 +152,8 @@ def can_unadopt_draft(user, doc): def can_edit_docextresources(user, doc): return (has_role(user, ("Secretariat", "Area Director")) or is_authorized_in_doc_stream(user, doc) - or is_individual_draft_author(user, doc)) + or is_individual_draft_author(user, doc) + or is_bofreq_editor(user, doc)) def two_thirds_rule( recused=0 ): # For standards-track, need positions from 2/3 of the non-recused current IESG. diff --git a/ietf/doc/views_bofreq.py b/ietf/doc/views_bofreq.py index 732ae3127..9ae92f4cd 100644 --- a/ietf/doc/views_bofreq.py +++ b/ietf/doc/views_bofreq.py @@ -76,7 +76,8 @@ class BofreqUploadForm(forms.Form): def submit(request, name): bofreq = get_object_or_404(Document, type="bofreq", name=name) previous_editors = bofreq_editors(bofreq) - if not (has_role(request.user,('Secretariat', 'Area Director', 'IAB')) or request.user.person in previous_editors): + state_id = bofreq.get_state_slug('bofreq') + if not (has_role(request.user,('Secretariat', 'Area Director', 'IAB')) or (state_id=='proposed' and request.user.person in previous_editors)): permission_denied(request,"You do not have permission to upload a new revision of this BOF Request") if request.method == 'POST': @@ -189,7 +190,8 @@ class ChangeEditorsForm(forms.Form): def change_editors(request, name): bofreq = get_object_or_404(Document, type="bofreq", name=name) previous_editors = bofreq_editors(bofreq) - if not (has_role(request.user,('Secretariat', 'Area Director', 'IAB')) or request.user.person in previous_editors): + state_id = bofreq.get_state_slug('bofreq') + if not (has_role(request.user,('Secretariat', 'Area Director', 'IAB')) or (state_id=='proposed' and request.user.person in previous_editors)): permission_denied(request,"You do not have permission to change this document's editors") if request.method == 'POST': @@ -267,7 +269,8 @@ class ChangeTitleForm(forms.Form): def edit_title(request, name): bofreq = get_object_or_404(Document, type="bofreq", name=name) editors = bofreq_editors(bofreq) - if not (has_role(request.user,('Secretariat', 'Area Director', 'IAB')) or request.user.person in editors): + state_id = bofreq.get_state_slug('bofreq') + if not (has_role(request.user,('Secretariat', 'Area Director', 'IAB')) or (state_id=='proposed' and request.user.person in editors)): permission_denied(request, "You do not have permission to edit this document's title") if request.method == 'POST': diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py index 56b021686..e95077564 100644 --- a/ietf/doc/views_doc.py +++ b/ietf/doc/views_doc.py @@ -533,7 +533,7 @@ def document_main(request, name, rev=None): editors = bofreq_editors(doc) responsible = bofreq_responsible(doc) can_manage = has_role(request.user,['Secretariat', 'Area Director', 'IAB']) - is_editor = request.user.is_authenticated and request.user.person in editors + editor_can_manage = doc.get_state_slug('bofreq')=='proposed' and request.user.is_authenticated and request.user.person in editors return render(request, "doc/document_bofreq.html", dict(doc=doc, @@ -545,7 +545,7 @@ def document_main(request, name, rev=None): can_manage=can_manage, editors=editors, responsible=responsible, - is_editor=is_editor, + editor_can_manage=editor_can_manage, )) if doc.type_id == "conflrev": diff --git a/ietf/ietfauth/utils.py b/ietf/ietfauth/utils.py index f84d430ce..40042fbfd 100644 --- a/ietf/ietfauth/utils.py +++ b/ietf/ietfauth/utils.py @@ -25,6 +25,7 @@ import debug # pyflakes:ignore from ietf.group.models import Role, GroupFeatures from ietf.person.models import Person +from ietf.doc.utils_bofreq import bofreq_editors def user_is_person(user, person): """Test whether user is associated with person.""" @@ -194,6 +195,9 @@ def is_individual_draft_author(user, doc): if not user.is_authenticated: return False + if not doc.type_id=='draft': + return False + if not doc.group.type_id == "individ" : return False @@ -204,6 +208,13 @@ def is_individual_draft_author(user, doc): return True return False + +def is_bofreq_editor(user, doc): + if not user.is_authenticated: + return False + if not doc.type_id=='bofreq': + return False + return user.person in bofreq_editors(doc) def openid_userinfo(claims, user): # Populate claims dict. diff --git a/ietf/templates/doc/document_bofreq.html b/ietf/templates/doc/document_bofreq.html index a5e194296..6ab624a95 100644 --- a/ietf/templates/doc/document_bofreq.html +++ b/ietf/templates/doc/document_bofreq.html @@ -50,7 +50,7 @@ Title {% if not snapshot %} - {% if is_editor or can_manage %} + {% if editor_can_manage or can_manage %} {% doc_edit_button 'ietf.doc.views_bofreq.edit_title' name=doc.name %} {% endif %} {% endif %} @@ -87,7 +87,7 @@ Editor{{editors|pluralize}} {% if not snapshot %} - {% if is_editor or can_manage %} + {% if editor_can_manage or can_manage %} {% doc_edit_button 'ietf.doc.views_bofreq.change_editors' name=doc.name %} {% endif %} {% endif %} @@ -117,12 +117,12 @@ {% with doc.docextresource_set.all as resources %} - {% if resources or is_editor or can_manage %} + {% if resources or editor_can_manage or can_manage %} Additional Resources - {% if is_editor or can_manage %} + {% if editor_can_manage or can_manage %} Edit {% endif %} @@ -165,7 +165,7 @@ {% if not snapshot %} - {% if is_editor or can_manage %} + {% if editor_can_manage or can_manage %}

Change BOF request text

{% endif %} {% endif %}