Date: Sun, 5 Nov 2023 11:04:25 +0100
Subject: [PATCH 09/26] fix: Remove time from materials cell (#6584)
Fixes #6542
---
ietf/templates/group/meetings-row.html | 1 -
1 file changed, 1 deletion(-)
diff --git a/ietf/templates/group/meetings-row.html b/ietf/templates/group/meetings-row.html
index d1775f3cc9..fbaf7cd560 100644
--- a/ietf/templates/group/meetings-row.html
+++ b/ietf/templates/group/meetings-row.html
@@ -32,7 +32,6 @@
{% if show_ical and s.current_status == "sched" %}
{% if s.meeting.type_id == 'ietf' %}
- {{ s.time|date:"H:i" }}
Date: Sun, 5 Nov 2023 02:09:07 -0800
Subject: [PATCH 10/26] fix: Don't redirect user to the login page when logging
in (#6570)
* fix: Don't redirect user to the login page when logging in (#5876)
(Embrace and extend c4bf508cd8.)
* test: Add test case for login button
* refactor: The template filter just strips off a path prefix, so rename/recode accordingly
Also test with a non-trivial redirect target.
---
ietf/doc/templatetags/ietf_filters.py | 12 +++++------
ietf/ietfauth/tests.py | 31 ++++++++++++++++++++++++++-
ietf/templates/base.html | 4 ++--
ietf/templates/base/menu_user.html | 4 ++--
4 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/ietf/doc/templatetags/ietf_filters.py b/ietf/doc/templatetags/ietf_filters.py
index 9b4700bfb1..c0ea94ab71 100644
--- a/ietf/doc/templatetags/ietf_filters.py
+++ b/ietf/doc/templatetags/ietf_filters.py
@@ -1,4 +1,4 @@
-# Copyright The IETF Trust 2007-2020, All Rights Reserved
+# Copyright The IETF Trust 2007-2023, All Rights Reserved
# -*- coding: utf-8 -*-
@@ -409,9 +409,9 @@ def startswith(x, y):
return str(x).startswith(y)
-@register.filter(name='removesuffix', is_safe=False)
-def removesuffix(value, suffix):
- """Remove an exact-match suffix
+@register.filter(name='removeprefix', is_safe=False)
+def removeprefix(value, prefix):
+ """Remove an exact-match prefix
The is_safe flag is False because indiscriminate use of this could result in non-safe output.
See https://docs.djangoproject.com/en/2.2/howto/custom-template-tags/#filters-and-auto-escaping
@@ -419,8 +419,8 @@ def removesuffix(value, suffix):
HTML-unsafe output.
"""
base = str(value)
- if base.endswith(suffix):
- return base[:-len(suffix)]
+ if base.startswith(prefix):
+ return base[len(prefix):]
else:
return base
diff --git a/ietf/ietfauth/tests.py b/ietf/ietfauth/tests.py
index 0e5fcb3c40..ec085ed813 100644
--- a/ietf/ietfauth/tests.py
+++ b/ietf/ietfauth/tests.py
@@ -1,4 +1,4 @@
-# Copyright The IETF Trust 2009-2022, All Rights Reserved
+# Copyright The IETF Trust 2009-2023, All Rights Reserved
# -*- coding: utf-8 -*-
@@ -111,6 +111,35 @@ def test_login_and_logout(self):
self.assertEqual(r.status_code, 302)
self.assertEqual(urlsplit(r["Location"])[2], "/foobar")
+ def test_login_button(self):
+ PersonFactory(user__username='plain')
+
+ def _test_login(url):
+ # try mashing the sign-in button repeatedly
+ r = self.client.get(url)
+ if r.status_code == 302:
+ r = self.client.get(r["Location"])
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ login_url = q("a:Contains('Sign in')").attr("href")
+ self.assertEqual(login_url, "/accounts/login/?next=" + url)
+ r = self.client.get(login_url)
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ login_url = q("a:Contains('Sign in')").attr("href")
+ self.assertEqual(login_url, "/accounts/login/?next=" + url)
+
+ # try logging in with the provided next
+ r = self.client.post(login_url, {"username":"plain", "password":"plain+password"})
+ self.assertEqual(r.status_code, 302)
+ self.assertEqual(urlsplit(r["Location"])[2], url)
+ self.client.logout()
+
+ # try with a trivial next
+ _test_login("/")
+ # try with a next that requires login
+ _test_login(urlreverse(ietf.ietfauth.views.profile))
+
def test_login_with_different_email(self):
person = PersonFactory(user__username='plain')
email = EmailFactory(person=person)
diff --git a/ietf/templates/base.html b/ietf/templates/base.html
index bc315dd561..7dc552268c 100644
--- a/ietf/templates/base.html
+++ b/ietf/templates/base.html
@@ -1,4 +1,4 @@
-{# Copyright The IETF Trust 2015-2022, All Rights Reserved #}
+{# Copyright The IETF Trust 2015-2023, All Rights Reserved #}
{% load analytical %}
{% load ietf_filters static %}
@@ -60,7 +60,7 @@
{% if not user.is_authenticated %}
+ href="{% url 'ietf.ietfauth.views.login' %}?next={{ request.get_full_path|removeprefix:'/accounts/logout'|removeprefix:'/accounts/login/?next='|urlencode }}">
Sign in
{% endif %}
diff --git a/ietf/templates/base/menu_user.html b/ietf/templates/base/menu_user.html
index e731307f2b..8245ece71c 100644
--- a/ietf/templates/base/menu_user.html
+++ b/ietf/templates/base/menu_user.html
@@ -1,4 +1,4 @@
-{# Copyright The IETF Trust 2015, All Rights Reserved #}
+{# Copyright The IETF Trust 2015-2023, All Rights Reserved #}
{% load origin %}
{% origin %}
{% load ietf_filters %}
@@ -87,7 +87,7 @@
+ href="{% url 'ietf.ietfauth.views.login' %}?next={{ request.get_full_path|removeprefix:'/accounts/login/?next='|urlencode }}">
Sign in
From b5ee9ec9ab944c91ee289f0899fd5898c0570089 Mon Sep 17 00:00:00 2001
From: Paul Selkirk
Date: Sun, 5 Nov 2023 03:32:03 -0800
Subject: [PATCH 11/26] fix: Don't allow group chair to change group parent
(#6496)
* fix: Don't allow group chair to change group parent (#6037)
* test: Fix test_edit_parent_field, add test_edit_parent (whole form)
* test: Verify that the chair can't circumvent the system to change the group parent
* fix: 403 if user tries to edit an unknown or hidden field
* fix: Give edwg GroupFeatures a parent type
This tracks a change that was made directly in the production database
to fix the immediate cause of #6037.
* Empty commit to trigger github unit test
---
ietf/group/forms.py | 31 +++++++------
ietf/group/tests_info.py | 82 ++++++++++++++++++++++++++++++++++-
ietf/group/views.py | 11 +++--
ietf/name/fixtures/names.json | 4 +-
4 files changed, 109 insertions(+), 19 deletions(-)
diff --git a/ietf/group/forms.py b/ietf/group/forms.py
index c93ca1d63c..7e00429271 100644
--- a/ietf/group/forms.py
+++ b/ietf/group/forms.py
@@ -1,4 +1,4 @@
-# Copyright The IETF Trust 2017-2020, All Rights Reserved
+# Copyright The IETF Trust 2017-2023, All Rights Reserved
# -*- coding: utf-8 -*-
@@ -103,6 +103,8 @@ def __init__(self, *args, **kwargs):
else:
field = None
+ self.hide_parent = kwargs.pop('hide_parent', False)
+
super(self.__class__, self).__init__(*args, **kwargs)
if not group_features or group_features.has_chartering_process:
@@ -138,18 +140,21 @@ def __init__(self, *args, **kwargs):
self.fields['acronym'].widget.attrs['readonly'] = ""
# Sort out parent options
- self.fields['parent'].queryset = self.fields['parent'].queryset.filter(type__in=parent_types)
- if need_parent:
- self.fields['parent'].required = True
- self.fields['parent'].empty_label = None
- # if this is a new group, fill in the default parent, if any
- if self.group is None or (not hasattr(self.group, 'pk')):
- self.fields['parent'].initial = self.fields['parent'].queryset.filter(
- acronym=default_parent
- ).first()
- # label the parent field as 'IETF Area' if appropriate, for consistency with past behavior
- if parent_types.count() == 1 and parent_types.first().pk == 'area':
- self.fields['parent'].label = "IETF Area"
+ if self.hide_parent:
+ self.fields.pop('parent')
+ else:
+ self.fields['parent'].queryset = self.fields['parent'].queryset.filter(type__in=parent_types)
+ if need_parent:
+ self.fields['parent'].required = True
+ self.fields['parent'].empty_label = None
+ # if this is a new group, fill in the default parent, if any
+ if self.group is None or (not hasattr(self.group, 'pk')):
+ self.fields['parent'].initial = self.fields['parent'].queryset.filter(
+ acronym=default_parent
+ ).first()
+ # label the parent field as 'IETF Area' if appropriate, for consistency with past behavior
+ if parent_types.count() == 1 and parent_types.first().pk == 'area':
+ self.fields['parent'].label = "IETF Area"
if field:
keys = list(self.fields.keys())
diff --git a/ietf/group/tests_info.py b/ietf/group/tests_info.py
index e0a738d073..136e195494 100644
--- a/ietf/group/tests_info.py
+++ b/ietf/group/tests_info.py
@@ -1,4 +1,4 @@
-# Copyright The IETF Trust 2009-2022, All Rights Reserved
+# Copyright The IETF Trust 2009-2023, All Rights Reserved
# -*- coding: utf-8 -*-
@@ -946,10 +946,88 @@ def test_edit_description_field(self):
r = self.client.post(url, {
'description': 'Ignored description',
})
- self.assertEqual(r.status_code, 302)
+ self.assertEqual(r.status_code, 403)
group = Group.objects.get(pk=group.pk) # refresh
self.assertEqual(group.description, 'Updated description')
+ def test_edit_parent(self):
+ group = GroupFactory.create(type_id='wg', parent=GroupFactory.create(type_id='area'))
+ chair = RoleFactory(group=group, name_id='chair').person
+ url = urlreverse('ietf.group.views.edit', kwargs=dict(group_type=group.type_id, acronym=group.acronym, action='edit'))
+
+ # parent is not shown to group chair
+ login_testing_unauthorized(self, chair.user.username, url)
+ r = self.client.get(url)
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ self.assertEqual(len(q('form select[name=parent]')), 0)
+
+ # view ignores attempt to change parent
+ old_parent = group.parent
+ new_parent = GroupFactory(type_id='area')
+ self.assertNotEqual(new_parent.acronym, group.parent.acronym)
+ r = self.client.post(url, dict(
+ name=group.name,
+ acronym=group.acronym,
+ state=group.state_id,
+ parent=new_parent.pk))
+ self.assertEqual(r.status_code, 302)
+ group = Group.objects.get(pk=group.pk)
+ self.assertNotEqual(group.parent, new_parent)
+ self.assertEqual(group.parent, old_parent)
+
+ # parent is shown to AD and Secretariat
+ for priv_user in ('ad', 'secretary'):
+ self.client.logout()
+ login_testing_unauthorized(self, priv_user, url)
+ r = self.client.get(url)
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ self.assertEqual(len(q('form select[name=parent]')), 1)
+
+ new_parent = GroupFactory(type_id='area')
+ self.assertNotEqual(new_parent.acronym, group.parent.acronym)
+ r = self.client.post(url, dict(
+ name=group.name,
+ acronym=group.acronym,
+ state=group.state_id,
+ parent=new_parent.pk))
+ self.assertEqual(r.status_code, 302)
+ group = Group.objects.get(pk=group.pk)
+ self.assertEqual(group.parent, new_parent)
+
+ def test_edit_parent_field(self):
+ group = GroupFactory.create(type_id='wg', parent=GroupFactory.create(type_id='area'))
+ chair = RoleFactory(group=group, name_id='chair').person
+ url = urlreverse('ietf.group.views.edit', kwargs=dict(group_type=group.type_id, acronym=group.acronym, action='edit', field='parent'))
+
+ # parent is not shown to group chair
+ login_testing_unauthorized(self, chair.user.username, url)
+ r = self.client.get(url)
+ self.assertEqual(r.status_code, 403)
+
+ # chair is not allowed to change parent
+ new_parent = GroupFactory(type_id='area')
+ self.assertNotEqual(new_parent.acronym, group.parent.acronym)
+ r = self.client.post(url, dict(parent=new_parent.pk))
+ self.assertEqual(r.status_code, 403)
+
+ # parent is shown to AD and Secretariat
+ for priv_user in ('ad', 'secretary'):
+ self.client.logout()
+ login_testing_unauthorized(self, priv_user, url)
+ r = self.client.get(url)
+ self.assertEqual(r.status_code, 200)
+ q = PyQuery(r.content)
+ self.assertEqual(len(q('form select[name=parent]')), 1)
+
+ new_parent = GroupFactory(type_id='area')
+ self.assertNotEqual(new_parent.acronym, group.parent.acronym)
+ r = self.client.post(url, dict(parent=new_parent.pk))
+ self.assertEqual(r.status_code, 302)
+ group = Group.objects.get(pk=group.pk)
+ self.assertEqual(group.parent, new_parent)
+
def test_conclude(self):
group = GroupFactory(acronym="mars")
diff --git a/ietf/group/views.py b/ietf/group/views.py
index 2b93e07607..593c649bb1 100644
--- a/ietf/group/views.py
+++ b/ietf/group/views.py
@@ -945,14 +945,17 @@ def diff(attr, name):
if not (can_manage_group(request.user, group)
or group.has_role(request.user, group.features.groupman_roles)):
permission_denied(request, "You don't have permission to access this view")
+ hide_parent = not has_role(request.user, ("Secretariat", "Area Director", "IRTF Chair"))
else:
# This allows ADs to create RG and the IRTF Chair to create WG, but we trust them not to
if not has_role(request.user, ("Secretariat", "Area Director", "IRTF Chair")):
permission_denied(request, "You don't have permission to access this view")
-
+ hide_parent = False
if request.method == 'POST':
- form = GroupForm(request.POST, group=group, group_type=group_type, field=field)
+ form = GroupForm(request.POST, group=group, group_type=group_type, field=field, hide_parent=hide_parent)
+ if field and not form.fields:
+ permission_denied(request, "You don't have permission to edit this field")
if form.is_valid():
clean = form.cleaned_data
if new_group:
@@ -1114,7 +1117,9 @@ def diff(attr, name):
else:
init = dict()
- form = GroupForm(initial=init, group=group, group_type=group_type, field=field)
+ form = GroupForm(initial=init, group=group, group_type=group_type, field=field, hide_parent=hide_parent)
+ if field and not form.fields:
+ permission_denied(request, "You don't have permission to edit this field")
return render(request, 'group/edit.html',
dict(group=group,
diff --git a/ietf/name/fixtures/names.json b/ietf/name/fixtures/names.json
index d105e8c61c..4dfe1574a2 100644
--- a/ietf/name/fixtures/names.json
+++ b/ietf/name/fixtures/names.json
@@ -3034,7 +3034,9 @@
"material_types": "[\n \"slides\"\n]",
"matman_roles": "[\n \"chair\"\n]",
"need_parent": false,
- "parent_types": [],
+ "parent_types": [
+ "rfcedtyp"
+ ],
"req_subm_approval": true,
"role_order": "[\n \"chair\"\n]",
"session_purposes": "[\n \"regular\"\n]",
From f8a06f663ede3a0654e19aace927b51ccebd84c8 Mon Sep 17 00:00:00 2001
From: Tero Kivinen
Date: Mon, 6 Nov 2023 11:19:32 -0500
Subject: [PATCH 12/26] fix: Add history entry when approving the slides.
(#6588)
* Added history entry when approving the slides.
Also changed os.rename to shutils.move as the submissions and
proceedings are on the separate filesystems on the docker image,
and this same thing might happen in the real environment in the
future.
* Add migrations for the docevents type.
---
.../migrations/0008_alter_docevent_type.py | 91 +++++++++++++++++++
ietf/doc/models.py | 3 +
ietf/meeting/views.py | 5 +-
3 files changed, 98 insertions(+), 1 deletion(-)
create mode 100644 ietf/doc/migrations/0008_alter_docevent_type.py
diff --git a/ietf/doc/migrations/0008_alter_docevent_type.py b/ietf/doc/migrations/0008_alter_docevent_type.py
new file mode 100644
index 0000000000..52a75f074b
--- /dev/null
+++ b/ietf/doc/migrations/0008_alter_docevent_type.py
@@ -0,0 +1,91 @@
+# Generated by Django 4.2.7 on 2023-11-04 13:02
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("doc", "0007_alter_docevent_type"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="docevent",
+ name="type",
+ field=models.CharField(
+ choices=[
+ ("new_revision", "Added new revision"),
+ ("new_submission", "Uploaded new revision"),
+ ("changed_document", "Changed document metadata"),
+ ("added_comment", "Added comment"),
+ ("added_message", "Added message"),
+ ("edited_authors", "Edited the documents author list"),
+ ("deleted", "Deleted document"),
+ ("changed_state", "Changed state"),
+ ("changed_stream", "Changed document stream"),
+ ("expired_document", "Expired document"),
+ ("extended_expiry", "Extended expiry of document"),
+ ("requested_resurrect", "Requested resurrect"),
+ ("completed_resurrect", "Completed resurrect"),
+ ("changed_consensus", "Changed consensus"),
+ ("published_rfc", "Published RFC"),
+ (
+ "added_suggested_replaces",
+ "Added suggested replacement relationships",
+ ),
+ (
+ "reviewed_suggested_replaces",
+ "Reviewed suggested replacement relationships",
+ ),
+ ("changed_action_holders", "Changed action holders for document"),
+ ("changed_group", "Changed group"),
+ ("changed_protocol_writeup", "Changed protocol writeup"),
+ ("changed_charter_milestone", "Changed charter milestone"),
+ ("initial_review", "Set initial review time"),
+ ("changed_review_announcement", "Changed WG Review text"),
+ ("changed_action_announcement", "Changed WG Action text"),
+ ("started_iesg_process", "Started IESG process on document"),
+ ("created_ballot", "Created ballot"),
+ ("closed_ballot", "Closed ballot"),
+ ("sent_ballot_announcement", "Sent ballot announcement"),
+ ("changed_ballot_position", "Changed ballot position"),
+ ("changed_ballot_approval_text", "Changed ballot approval text"),
+ ("changed_ballot_writeup_text", "Changed ballot writeup text"),
+ ("changed_rfc_editor_note_text", "Changed RFC Editor Note text"),
+ ("changed_last_call_text", "Changed last call text"),
+ ("requested_last_call", "Requested last call"),
+ ("sent_last_call", "Sent last call"),
+ ("scheduled_for_telechat", "Scheduled for telechat"),
+ ("iesg_approved", "IESG approved document (no problem)"),
+ ("iesg_disapproved", "IESG disapproved document (do not publish)"),
+ ("approved_in_minute", "Approved in minute"),
+ ("iana_review", "IANA review comment"),
+ ("rfc_in_iana_registry", "RFC is in IANA registry"),
+ (
+ "rfc_editor_received_announcement",
+ "Announcement was received by RFC Editor",
+ ),
+ ("requested_publication", "Publication at RFC Editor requested"),
+ (
+ "sync_from_rfc_editor",
+ "Received updated information from RFC Editor",
+ ),
+ ("requested_review", "Requested review"),
+ ("assigned_review_request", "Assigned review request"),
+ ("closed_review_request", "Closed review request"),
+ ("closed_review_assignment", "Closed review assignment"),
+ ("downref_approved", "Downref approved"),
+ ("posted_related_ipr", "Posted related IPR"),
+ ("removed_related_ipr", "Removed related IPR"),
+ (
+ "removed_objfalse_related_ipr",
+ "Removed Objectively False related IPR",
+ ),
+ ("changed_editors", "Changed BOF Request editors"),
+ ("published_statement", "Published statement"),
+ ("approved_slides", "Slides approved"),
+ ],
+ max_length=50,
+ ),
+ ),
+ ]
diff --git a/ietf/doc/models.py b/ietf/doc/models.py
index 15e882e710..30d95fbf50 100644
--- a/ietf/doc/models.py
+++ b/ietf/doc/models.py
@@ -1315,6 +1315,9 @@ class DocReminder(models.Model):
# Statement events
("published_statement", "Published statement"),
+
+ # Slide events
+ ("approved_slides", "Slides approved"),
]
diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py
index 3e7b89d585..48b0f2f06a 100644
--- a/ietf/meeting/views.py
+++ b/ietf/meeting/views.py
@@ -14,6 +14,7 @@
import re
import tarfile
import tempfile
+import shutil
from calendar import timegm
from collections import OrderedDict, Counter, deque, defaultdict, namedtuple
@@ -4555,8 +4556,10 @@ def approve_proposed_slides(request, slidesubmission_id, num):
path = os.path.join(submission.session.meeting.get_materials_path(),'slides')
if not os.path.exists(path):
os.makedirs(path)
- os.rename(submission.staged_filepath(), os.path.join(path, target_filename))
+ shutil.move(submission.staged_filepath(), os.path.join(path, target_filename))
post_process(doc)
+ DocEvent.objects.create(type="approved_slides", doc=doc, rev=doc.rev, by=request.user.person, desc="Slides approved")
+
acronym = submission.session.group.acronym
submission.status = SlideSubmissionStatusName.objects.get(slug='approved')
submission.doc = doc
From f1425e4a52ec31a164d7a2f616468df0fa340c08 Mon Sep 17 00:00:00 2001
From: Peter Yee
Date: Mon, 6 Nov 2023 17:45:07 +0100
Subject: [PATCH 13/26] fix: move meeting management from base Docs to Meeting
(#6586)
* fix: move meeting management from base Docs to Meeting
* fix: add permission check for ability to request an interim meeting
* fix: guard against no user being logged in
---------
Co-authored-by: Robert Sparks
---
ietf/meeting/templatetags/meetings_filters.py | 21 ++++++++++++
ietf/templates/base/menu.html | 32 +++++++++++++------
2 files changed, 43 insertions(+), 10 deletions(-)
create mode 100644 ietf/meeting/templatetags/meetings_filters.py
diff --git a/ietf/meeting/templatetags/meetings_filters.py b/ietf/meeting/templatetags/meetings_filters.py
new file mode 100644
index 0000000000..3fa209daa2
--- /dev/null
+++ b/ietf/meeting/templatetags/meetings_filters.py
@@ -0,0 +1,21 @@
+# Copyright The IETF Trust 2023, All Rights Reserved
+# -*- coding: utf-8 -*-
+
+from django import template
+from ietf.meeting.helpers import can_request_interim_meeting
+
+import debug # pyflakes:ignore
+
+register = template.Library()
+
+@register.filter
+def can_request_interim(user):
+ """Determine whether the user can request an interim meeting
+
+ Usage: can_request_interim
+ Returns Boolean. True means user can request an interim meeting.
+ """
+
+ if not user:
+ return False
+ return can_request_interim_meeting(user)
diff --git a/ietf/templates/base/menu.html b/ietf/templates/base/menu.html
index 693a33bd8f..8d70fd4811 100644
--- a/ietf/templates/base/menu.html
+++ b/ietf/templates/base/menu.html
@@ -1,7 +1,7 @@
{# Copyright The IETF Trust 2015-2022, All Rights Reserved #}
{% load origin %}
{% origin %}
-{% load ietf_filters managed_groups wg_menu active_groups_menu group_filters cache %}
+{% load ietf_filters managed_groups wg_menu active_groups_menu group_filters cache meetings_filters %}
{% if flavor != 'top' %}
{% include "base/menu_user.html" %}
{% endif %}
@@ -144,14 +144,6 @@
{% endfor %}
- {% for g in user|matman_groups %}
-
-
- {{ g.acronym }} {{ g.type.slug }} meetings
-
-
- {% endfor %}
{% endif %}
{% if user|has_role:"Review Team Secretary" %}
{% if flavor == 'top' %}
@@ -275,12 +267,32 @@
Request a session
+ {% if user|can_request_interim %}
+
+
+ Request an interim meeting
+
+
+ {% endif %}
Session requests
+ {% if user|matman_groups %}
+ {% if flavor == 'top' %} {% endif %}
+ Manage
+ {% for g in user|matman_groups %}
+
+
+ {{ g.acronym }} {{ g.type.slug }} meetings
+
+
+ {% endfor %}
+ {% endif %}
{% if flavor == 'top' %}
{% if flavor == 'top' %}
@@ -425,4 +437,4 @@
{% endif %}
{% if flavor == 'top' %}
{% include "base/menu_user.html" %}
-{% endif %}
\ No newline at end of file
+{% endif %}
From 2bec81da95c6143579a90471d16e12f416496ff0 Mon Sep 17 00:00:00 2001
From: Paul Selkirk
Date: Tue, 7 Nov 2023 03:50:23 -0500
Subject: [PATCH 14/26] fix: Don't include csrf_token in GET-only form (#6549)
---
ietf/templates/doc/search/search_form.html | 1 -
1 file changed, 1 deletion(-)
diff --git a/ietf/templates/doc/search/search_form.html b/ietf/templates/doc/search/search_form.html
index 50c036f86a..d4f463ec66 100644
--- a/ietf/templates/doc/search/search_form.html
+++ b/ietf/templates/doc/search/search_form.html
@@ -6,7 +6,6 @@
|