fix: return to ballotpopup (#7858)

* fix: return to ballotpopup

* fix: ballot position return to in modals

* fix: ballot return to test

* fix: ballot return to additional allow handlers

* fix: ballot return to handler syntax error in test
This commit is contained in:
Matthew Holloway 2024-08-29 00:51:05 +12:00 committed by GitHub
parent bece8fd71b
commit 715edafcdc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 42 additions and 16 deletions

View file

@ -96,9 +96,14 @@ def ballot_icon(context, doc):
positions = list(ballot.active_balloter_positions().items()) positions = list(ballot.active_balloter_positions().items())
positions.sort(key=sort_key) positions.sort(key=sort_key)
request = context.get("request")
ballot_edit_return_point_param = f"ballot_edit_return_point={request.path}"
right_click_string = '' right_click_string = ''
if has_role(user, "Area Director"): if has_role(user, "Area Director"):
right_click_string = 'oncontextmenu="window.location.href=\'%s\';return false;"' % urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=doc.name, ballot_id=ballot.pk)) right_click_string = 'oncontextmenu="window.location.href=\'{}?{}\';return false;"'.format(
urlreverse('ietf.doc.views_ballot.edit_position', kwargs=dict(name=doc.name, ballot_id=ballot.pk)),
ballot_edit_return_point_param)
my_blocking = False my_blocking = False
for i, (balloter, pos) in enumerate(positions): for i, (balloter, pos) in enumerate(positions):
@ -113,10 +118,14 @@ def ballot_icon(context, doc):
typename = "RSAB" typename = "RSAB"
else: else:
typename = "IESG" typename = "IESG"
modal_url = "{}?{}".format(
urlreverse("ietf.doc.views_doc.ballot_popup", kwargs=dict(name=doc.name, ballot_id=ballot.pk)),
ballot_edit_return_point_param)
res = ['<a %s href="%s" data-bs-toggle="modal" data-bs-target="#modal-%d" aria-label="%s positions" title="%s positions (click to show more)" class="ballot-icon"><table' % ( res = ['<a %s href="%s" data-bs-toggle="modal" data-bs-target="#modal-%d" aria-label="%s positions" title="%s positions (click to show more)" class="ballot-icon"><table' % (
right_click_string, right_click_string,
urlreverse("ietf.doc.views_doc.ballot_popup", kwargs=dict(name=doc.name, ballot_id=ballot.pk)), modal_url,
ballot.pk, ballot.pk,
typename, typename,
typename,)] typename,)]

View file

@ -1455,18 +1455,14 @@ class BallotContentTests(TestCase):
class ReturnToUrlTests(TestCase): class ReturnToUrlTests(TestCase):
def test_invalid_return_to_url(self): def test_invalid_return_to_url(self):
self.assertRaises( with self.assertRaises(ValueError):
Exception, parse_ballot_edit_return_point('/', 'draft-ietf-opsawg-ipfix-tcpo-v6eh', '998718')
lambda: parse_ballot_edit_return_point('/doc/', 'draft-ietf-opsawg-ipfix-tcpo-v6eh', '998718'),
) with self.assertRaises(ValueError):
self.assertRaises( parse_ballot_edit_return_point('/a-route-that-does-not-exist/', 'draft-ietf-opsawg-ipfix-tcpo-v6eh', '998718')
Exception,
lambda: parse_ballot_edit_return_point('/a-route-that-does-not-exist/', 'draft-ietf-opsawg-ipfix-tcpo-v6eh', '998718'), with self.assertRaises(ValueError):
) parse_ballot_edit_return_point('https://example.com/phishing', 'draft-ietf-opsawg-ipfix-tcpo-v6eh', '998718')
self.assertRaises(
Exception,
lambda: parse_ballot_edit_return_point('https://example.com/phishing', 'draft-ietf-opsawg-ipfix-tcpo-v6eh', '998718'),
)
def test_valid_default_return_to_url(self): def test_valid_default_return_to_url(self):
self.assertEqual(parse_ballot_edit_return_point( self.assertEqual(parse_ballot_edit_return_point(

View file

@ -1314,10 +1314,23 @@ def rsab_ballot_status(request):
def parse_ballot_edit_return_point(path, doc_name, ballot_id): def parse_ballot_edit_return_point(path, doc_name, ballot_id):
get_default_path = lambda: urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc_name, ballot_id=ballot_id)) get_default_path = lambda: urlreverse("ietf.doc.views_doc.document_ballot", kwargs=dict(name=doc_name, ballot_id=ballot_id))
allowed_path_handlers = { allowed_path_handlers = {
"ietf.community.views.view_list",
"ietf.doc.views_doc.document_ballot", "ietf.doc.views_doc.document_ballot",
"ietf.doc.views_doc.document_irsg_ballot", "ietf.doc.views_doc.document_irsg_ballot",
"ietf.doc.views_doc.document_rsab_ballot", "ietf.doc.views_doc.document_rsab_ballot",
"ietf.doc.views_ballot.irsg_ballot_status",
"ietf.doc.views_ballot.rsab_ballot_status",
"ietf.doc.views_search.search",
"ietf.doc.views_search.docs_for_ad",
"ietf.doc.views_search.drafts_in_last_call",
"ietf.doc.views_search.recent_drafts",
"ietf.group.views.chartering_groups",
"ietf.group.views.group_documents",
"ietf.group.views.stream_documents",
"ietf.iesg.views.agenda", "ietf.iesg.views.agenda",
"ietf.iesg.views.agenda_documents", "ietf.iesg.views.agenda_documents",
"ietf.iesg.views.discusses",
"ietf.iesg.views.past_documents",
} }
return validate_return_to_path(path, get_default_path, allowed_path_handlers) return validate_return_to_path(path, get_default_path, allowed_path_handlers)

View file

@ -43,7 +43,7 @@ from pathlib import Path
from django.core.cache import caches from django.core.cache import caches
from django.db.models import Max from django.db.models import Max
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404, HttpResponseBadRequest
from django.shortcuts import render, get_object_or_404, redirect from django.shortcuts import render, get_object_or_404, redirect
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.urls import reverse as urlreverse from django.urls import reverse as urlreverse
@ -73,6 +73,7 @@ from ietf.ietfauth.utils import ( has_role, is_authorized_in_doc_stream, user_is
role_required, is_individual_draft_author, can_request_rfc_publication) role_required, is_individual_draft_author, can_request_rfc_publication)
from ietf.name.models import StreamName, BallotPositionName from ietf.name.models import StreamName, BallotPositionName
from ietf.utils.history import find_history_active_at from ietf.utils.history import find_history_active_at
from ietf.doc.views_ballot import parse_ballot_edit_return_point
from ietf.doc.forms import InvestigateForm, TelechatForm, NotifyForm, ActionHoldersForm, DocAuthorForm, DocAuthorChangeBasisForm from ietf.doc.forms import InvestigateForm, TelechatForm, NotifyForm, ActionHoldersForm, DocAuthorForm, DocAuthorChangeBasisForm
from ietf.doc.mails import email_comment, email_remind_action_holders from ietf.doc.mails import email_comment, email_remind_action_holders
from ietf.mailtrigger.utils import gather_relevant_expansions from ietf.mailtrigger.utils import gather_relevant_expansions
@ -1586,11 +1587,18 @@ def ballot_popup(request, name, ballot_id):
doc = get_object_or_404(Document, name=name) doc = get_object_or_404(Document, name=name)
c = document_ballot_content(request, doc, ballot_id=ballot_id, editable=False) c = document_ballot_content(request, doc, ballot_id=ballot_id, editable=False)
ballot = get_object_or_404(BallotDocEvent,id=ballot_id) ballot = get_object_or_404(BallotDocEvent,id=ballot_id)
try:
return_to_url = parse_ballot_edit_return_point(request.GET.get('ballot_edit_return_point'), name, ballot_id)
except ValueError:
return HttpResponseBadRequest('ballot_edit_return_point is invalid')
return render(request, "doc/ballot_popup.html", return render(request, "doc/ballot_popup.html",
dict(doc=doc, dict(doc=doc,
ballot_content=c, ballot_content=c,
ballot_id=ballot_id, ballot_id=ballot_id,
ballot_type_slug=ballot.ballot_type.slug, ballot_type_slug=ballot.ballot_type.slug,
ballot_edit_return_point=return_to_url,
editable=True, editable=True,
)) ))

View file

@ -27,7 +27,7 @@
{% if editable and user|has_role:"Area Director,Secretariat,IRSG Member,RSAB Member" %} {% if editable and user|has_role:"Area Director,Secretariat,IRSG Member,RSAB Member" %}
{% if user|can_ballot:doc %} {% if user|can_ballot:doc %}
<a class="btn btn-primary" <a class="btn btn-primary"
href="{% url "ietf.doc.views_ballot.edit_position" name=doc.name ballot_id=ballot_id %}?ballot_edit_return_point={{ request.path|urlencode }}"> href="{% url "ietf.doc.views_ballot.edit_position" name=doc.name ballot_id=ballot_id %}?ballot_edit_return_point={{ ballot_edit_return_point|urlencode }}">
Edit position Edit position
</a> </a>
{% endif %} {% endif %}