Merge pull request #5601 from jennifer-richards/django4

chore: Upgrade to Django 3.0
This commit is contained in:
Jennifer Richards 2023-05-11 11:04:36 -04:00 committed by GitHub
commit 264ff60cd2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
71 changed files with 200 additions and 178 deletions

View file

@ -10,7 +10,7 @@ DATABASES = {
'HOST': '__DBHOST__',
'PORT': 5432,
'NAME': 'datatracker',
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'django',
'PASSWORD': 'RkTkDPFnKpko',
},

View file

@ -10,7 +10,7 @@ DATABASES = {
'HOST': '__DBHOST__',
'PORT': 5432,
'NAME': 'datatracker',
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'django',
'PASSWORD': 'RkTkDPFnKpko',
},

View file

@ -10,7 +10,7 @@ DATABASES = {
'HOST': 'db',
'PORT': 5432,
'NAME': 'datatracker',
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'django',
'PASSWORD': 'RkTkDPFnKpko',
},

View file

@ -3,7 +3,7 @@ DATABASES = {
'HOST': 'db',
'PORT': 5432,
'NAME': 'datatracker',
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'django',
'PASSWORD': 'RkTkDPFnKpko',
},

View file

@ -9,7 +9,7 @@ from django.core.cache import cache
from django.core.exceptions import ObjectDoesNotExist, FieldError
from django.core.serializers.json import Serializer
from django.http import HttpResponse
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str
from django.db.models import Field
from django.db.models.query import QuerySet
from django.db.models.signals import post_save, post_delete, m2m_changed
@ -121,7 +121,7 @@ class AdminJsonSerializer(Serializer):
for name in expansions:
try:
field = getattr(obj, name)
#self._current["_"+name] = smart_text(field)
#self._current["_"+name] = smart_str(field)
if not isinstance(field, Field):
options = self.options.copy()
options["expand"] = [ v[len(name)+2:] for v in options["expand"] if v.startswith(name+"__") ]
@ -188,10 +188,10 @@ class AdminJsonSerializer(Serializer):
related = related.natural_key()
elif field.remote_field.field_name == related._meta.pk.name:
# Related to remote object via primary key
related = smart_text(related._get_pk_val(), strings_only=True)
related = smart_str(related._get_pk_val(), strings_only=True)
else:
# Related to remote object via other field
related = smart_text(getattr(related, field.remote_field.field_name), strings_only=True)
related = smart_str(getattr(related, field.remote_field.field_name), strings_only=True)
self._current[field.name] = related
def handle_m2m_field(self, obj, field):
@ -201,7 +201,7 @@ class AdminJsonSerializer(Serializer):
elif self.use_natural_keys and hasattr(field.remote_field.to, 'natural_key'):
m2m_value = lambda value: value.natural_key()
else:
m2m_value = lambda value: smart_text(value._get_pk_val(), strings_only=True)
m2m_value = lambda value: smart_str(value._get_pk_val(), strings_only=True)
self._current[field.name] = [m2m_value(related)
for related in getattr(obj, field.name).iterator()]
@ -221,7 +221,7 @@ class JsonExportMixin(object):
# obj = None
#
# if obj is None:
# raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(self.model._meta.verbose_name), 'key': escape(object_id)})
# raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_str(self.model._meta.verbose_name), 'key': escape(object_id)})
#
# content_type = 'application/json'
# return HttpResponse(serialize([ obj ], sort_keys=True, indent=3)[2:-2], content_type=content_type)
@ -264,6 +264,6 @@ class JsonExportMixin(object):
qd = dict( ( k, json.loads(v)[0] ) for k,v in items )
except (FieldError, ValueError) as e:
return HttpResponse(json.dumps({"error": str(e)}, sort_keys=True, indent=3), content_type=content_type)
text = json.dumps({smart_text(self.model._meta): qd}, sort_keys=True, indent=3)
text = json.dumps({smart_str(self.model._meta): qd}, sort_keys=True, indent=3)
return HttpResponse(text, content_type=content_type)

View file

@ -11,7 +11,7 @@ from django.utils.html import strip_tags
from django.conf import settings
from django.urls import reverse as urlreverse
from django.utils import timezone
from django.utils.encoding import force_text
from django.utils.encoding import force_str
import debug # pyflakes:ignore
from ietf.doc.templatetags.mail_filters import std_level_prompt
@ -175,7 +175,7 @@ def generate_ballot_writeup(request, doc):
e.doc = doc
e.rev = doc.rev
e.desc = "Ballot writeup was generated"
e.text = force_text(render_to_string("doc/mail/ballot_writeup.txt", {'iana': iana, 'doc': doc }))
e.text = force_str(render_to_string("doc/mail/ballot_writeup.txt", {'iana': iana, 'doc': doc }))
# caller is responsible for saving, if necessary
return e
@ -187,7 +187,7 @@ def generate_ballot_rfceditornote(request, doc):
e.doc = doc
e.rev = doc.rev
e.desc = "RFC Editor Note for ballot was generated"
e.text = force_text(render_to_string("doc/mail/ballot_rfceditornote.txt"))
e.text = force_str(render_to_string("doc/mail/ballot_rfceditornote.txt"))
e.save()
return e
@ -232,7 +232,7 @@ def generate_last_call_announcement(request, doc):
e.doc = doc
e.rev = doc.rev
e.desc = "Last call announcement was generated"
e.text = force_text(mail)
e.text = force_str(mail)
# caller is responsible for saving, if necessary
return e
@ -252,7 +252,7 @@ def generate_approval_mail(request, doc):
e.doc = doc
e.rev = doc.rev
e.desc = "Ballot approval text was generated"
e.text = force_text(mail)
e.text = force_str(mail)
# caller is responsible for saving, if necessary
return e

View file

@ -23,7 +23,7 @@ from django.urls import reverse as urlreverse
from django.contrib.contenttypes.models import ContentType
from django.conf import settings
from django.utils import timezone
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from django.utils.html import mark_safe # type:ignore
from django.contrib.staticfiles import finders
@ -1131,7 +1131,7 @@ class DocHistory(DocumentInfo):
name = models.CharField(max_length=255)
def __str__(self):
return force_text(self.doc.name)
return force_str(self.doc.name)
def get_related_session(self):
return self.doc.get_related_session()
@ -1193,7 +1193,7 @@ class DocAlias(models.Model):
return self.docs.first()
def __str__(self):
return u"%s-->%s" % (self.name, ','.join([force_text(d.name) for d in self.docs.all() if isinstance(d, Document) ]))
return u"%s-->%s" % (self.name, ','.join([force_str(d.name) for d in self.docs.all() if isinstance(d, Document) ]))
document_link = admin_link("document")
class Meta:
verbose_name = "document alias"

View file

@ -13,8 +13,7 @@ from django.utils.html import escape
from django.template.defaultfilters import truncatewords_html, linebreaksbr, stringfilter, striptags
from django.utils.safestring import mark_safe, SafeData
from django.utils.html import strip_tags
from django.utils.encoding import force_text
from django.utils.encoding import force_str # pyflakes:ignore force_str is used in the doctests
from django.utils.encoding import force_str
from django.urls import reverse as urlreverse
from django.core.cache import cache
from django.core.exceptions import ValidationError
@ -132,7 +131,7 @@ register.filter('fill', fill)
@register.filter
def prettystdname(string, space=" "):
from ietf.doc.utils import prettify_std_name
return prettify_std_name(force_text(string or ""), space)
return prettify_std_name(force_str(string or ""), space)
@register.filter
def rfceditor_info_url(rfcnum : str):

View file

@ -12,7 +12,7 @@ from django.conf import settings
from django.urls import reverse as urlreverse
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.encoding import smart_text, force_text
from django.utils.encoding import smart_str, force_str
import debug # pyflakes:ignore
@ -153,7 +153,7 @@ def generate_ballot_writeup(request, doc):
e.doc = doc
e.rev = doc.rev,
e.desc = "Ballot writeup was generated"
e.text = force_text(render_to_string("doc/charter/ballot_writeup.txt"))
e.text = force_str(render_to_string("doc/charter/ballot_writeup.txt"))
# caller is responsible for saving, if necessary
return e
@ -197,7 +197,7 @@ def derive_new_work_text(review_text,group):
'Reply_to':'<iesg@ietf.org>'})
if not addrs.cc:
del m['Cc']
return smart_text(m.as_string())
return smart_str(m.as_string())
def default_review_text(group, charter, by):
now = timezone.now()

View file

@ -17,7 +17,7 @@ from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.utils import timezone
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from django.utils.html import escape
import debug # pyflakes:ignore
@ -821,7 +821,7 @@ def charter_with_milestones_txt(request, name, rev):
try:
with io.open(os.path.join(settings.CHARTER_PATH, filename), 'r') as f:
charter_text = force_text(f.read(), errors='ignore')
charter_text = force_str(f.read(), errors='ignore')
except IOError:
charter_text = "Error reading charter text %s" % filename

View file

@ -15,7 +15,7 @@ from django.http import Http404, HttpResponseRedirect
from django.urls import reverse
from django.template.loader import render_to_string
from django.conf import settings
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from django.utils.html import escape
import debug # pyflakes:ignore
@ -531,7 +531,7 @@ def rfc_status_changes(request):
)
@role_required("Area Director","Secretariat")
def start_rfc_status_change(request,name):
def start_rfc_status_change(request, name=None):
"""Start the RFC status change review process, setting the initial shepherding AD, and possibly putting the review on a telechat."""
if name:
@ -665,7 +665,7 @@ def generate_last_call_text(request, doc):
e.doc = doc
e.rev = doc.rev
e.desc = 'Last call announcement was generated'
e.text = force_text(new_text)
e.text = force_str(new_text)
e.save()
return e

View file

@ -14,7 +14,7 @@ from django.contrib.admin.utils import unquote
from django.core.management import load_command_class
from django.http import Http404
from django.shortcuts import render
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from django.utils.html import escape
from django.utils.translation import ugettext as _
@ -152,7 +152,7 @@ class GroupAdmin(admin.ModelAdmin):
permission_denied(request, "You don't have edit permissions for this change.")
if obj is None:
raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)})
raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_str(opts.verbose_name), 'key': escape(object_id)})
return self.send_reminder(request, sdo=obj)

View file

@ -300,8 +300,27 @@ def active_groups(request, group_type=None):
raise Http404
def active_group_types(request):
grouptypes = GroupTypeName.objects.filter(slug__in=['wg','rg','ag','rag','team','dir','review','area','program','iabasg','adm']).filter(group__state='active').annotate(group_count=Count('group'))
return render(request, 'group/active_groups.html', {'grouptypes':grouptypes})
grouptypes = (
GroupTypeName.objects.filter(
slug__in=[
"wg",
"rg",
"ag",
"rag",
"team",
"dir",
"review",
"area",
"program",
"iabasg",
"adm",
]
)
.filter(group__state="active")
.order_by('order', 'name') # default ordering ignored for "GROUP BY" queries, make it explicit
.annotate(group_count=Count("group"))
)
return render(request, "group/active_groups.html", {"grouptypes": grouptypes})
def active_dirs(request):
dirs = Group.objects.filter(type__in=['dir', 'review'], state="active").order_by("name")

View file

@ -7,7 +7,7 @@
import oidc_provider.lib.claims
from functools import wraps
from functools import wraps, WRAPPER_ASSIGNMENTS
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
@ -15,7 +15,6 @@ from django.core.exceptions import PermissionDenied
from django.db.models import Q
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.utils.decorators import available_attrs
from django.utils.http import urlquote
import debug # pyflakes:ignore
@ -113,7 +112,7 @@ def passes_test_decorator(test_func, message):
error. The test function should be on the form fn(user) ->
true/false."""
def decorate(view_func):
@wraps(view_func, assigned=available_attrs(view_func))
@wraps(view_func, assigned=WRAPPER_ASSIGNMENTS)
def inner(request, *args, **kwargs):
if not request.user.is_authenticated:
return HttpResponseRedirect('%s?%s=%s' % (settings.LOGIN_URL, REDIRECT_FIELD_NAME, urlquote(request.get_full_path())))

View file

@ -6,7 +6,7 @@ from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import Atom1Feed
from django.urls import reverse_lazy
from django.utils.safestring import mark_safe
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from ietf.ipr.models import IprDisclosureBase
@ -25,7 +25,7 @@ class LatestIprDisclosuresFeed(Feed):
return mark_safe(item.title)
def item_description(self, item):
return force_text(item.title)
return force_str(item.title)
def item_pubdate(self, item):
return item.time

View file

@ -12,7 +12,7 @@ from email import message_from_bytes
from email.utils import parsedate_tz
from django.template.loader import render_to_string
from django.utils.encoding import force_text, force_bytes
from django.utils.encoding import force_str, force_bytes
import debug # pyflakes:ignore
@ -102,7 +102,7 @@ def get_reply_to():
address with "plus addressing" using a random string. Guaranteed to be unique"""
local,domain = get_base_ipr_request_address().split('@')
while True:
rand = force_text(base64.urlsafe_b64encode(os.urandom(12)))
rand = force_str(base64.urlsafe_b64encode(os.urandom(12)))
address = "{}+{}@{}".format(local,rand,domain)
q = Message.objects.filter(reply_to=address)
if not q:

View file

@ -9,7 +9,6 @@ import operator
from typing import Union # pyflakes:ignore
from email.utils import parseaddr
from form_utils.forms import BetterModelForm
from django import forms
from django.conf import settings
@ -132,7 +131,7 @@ class AddCommentForm(forms.Form):
# def render(self):
# output = []
# for widget in self:
# output.append(format_html(force_text(widget)))
# output.append(format_html(force_str(widget)))
# return mark_safe('\n'.join(output))
@ -213,7 +212,7 @@ class CustomModelMultipleChoiceField(forms.ModelMultipleChoiceField):
return super(CustomModelMultipleChoiceField, self).prepare_value(value)
class LiaisonModelForm(BetterModelForm):
class LiaisonModelForm(forms.ModelForm):
'''Specify fields which require a custom widget or that are not part of the model.
'''
from_groups = forms.ModelMultipleChoiceField(queryset=Group.objects.all(),label='Groups',required=False)
@ -238,13 +237,6 @@ class LiaisonModelForm(BetterModelForm):
class Meta:
model = LiaisonStatement
exclude = ('attachments','state','from_name','to_name')
fieldsets = [('From', {'fields': ['from_groups','from_contact', 'response_contacts'], 'legend': ''}),
('To', {'fields': ['to_groups','to_contacts'], 'legend': ''}),
('Other email addresses', {'fields': ['technical_contacts','action_holder_contacts','cc_contacts'], 'legend': ''}),
('Purpose', {'fields':['purpose', 'deadline'], 'legend': ''}),
('Reference', {'fields': ['other_identifiers','related_to'], 'legend': ''}),
('Liaison Statement', {'fields': ['title', 'submitted_date', 'body', 'attachments'], 'legend': ''}),
('Add attachment', {'fields': ['attach_title', 'attach_file', 'attach_button'], 'legend': ''})]
def __init__(self, user, *args, **kwargs):
super(LiaisonModelForm, self).__init__(*args, **kwargs)
@ -476,14 +468,6 @@ class OutgoingLiaisonForm(LiaisonModelForm):
class Meta:
model = LiaisonStatement
exclude = ('attachments','state','from_name','to_name','action_holder_contacts')
# add approved field, no action_holder_contacts
fieldsets = [('From', {'fields': ['from_groups','from_contact','response_contacts','approved'], 'legend': ''}),
('To', {'fields': ['to_groups','to_contacts'], 'legend': ''}),
('Other email addresses', {'fields': ['technical_contacts','cc_contacts'], 'legend': ''}),
('Purpose', {'fields':['purpose', 'deadline'], 'legend': ''}),
('Reference', {'fields': ['other_identifiers','related_to'], 'legend': ''}),
('Liaison Statement', {'fields': ['title', 'submitted_date', 'body', 'attachments'], 'legend': ''}),
('Add attachment', {'fields': ['attach_title', 'attach_file', 'attach_button'], 'legend': ''})]
def is_approved(self):
return self.cleaned_data['approved']

View file

@ -15,7 +15,7 @@ from django.conf import settings
from django.contrib import messages
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str
import debug # pyflakes:ignore
@ -699,7 +699,7 @@ def handle_upload_file(file, filename, meeting, subdir, request=None, encoding=N
)
else:
try:
text = smart_text(text)
text = smart_str(text)
except UnicodeDecodeError as e:
return "Failure trying to save '%s'. Hint: Try to upload as UTF-8: %s..." % (filename, str(e)[:120])
# Whole file sanitization; add back what's missing from a complete

View file

@ -17,6 +17,7 @@ import tempfile
from calendar import timegm
from collections import OrderedDict, Counter, deque, defaultdict, namedtuple
from functools import partialmethod
from urllib.parse import parse_qs, unquote, urlencode, urlsplit, urlunsplit
from tempfile import mkstemp
from wsgiref.handlers import format_date_time
@ -38,7 +39,6 @@ from django.template import TemplateDoesNotExist
from django.template.loader import render_to_string
from django.utils import timezone
from django.utils.encoding import force_str
from django.utils.functional import curry
from django.utils.text import slugify
from django.views.decorators.cache import cache_page
from django.views.decorators.csrf import ensure_csrf_cookie, csrf_exempt
@ -2730,7 +2730,7 @@ def upload_session_agenda(request, session_id, num):
})
def upload_session_slides(request, session_id, num, name):
def upload_session_slides(request, session_id, num, name=None):
# num is redundant, but we're dragging it along an artifact of where we are in the current URL structure
session = get_object_or_404(Session,pk=session_id)
if not session.can_manage_materials(request.user):
@ -3210,8 +3210,8 @@ def interim_request(request):
if meeting_type in ('single', 'multi-day'):
meeting = form.save(date=get_earliest_session_date(formset))
# need to use curry here to pass custom variable to form init
SessionFormset.form.__init__ = curry(
# need to use partialmethod here to pass custom variable to form init
SessionFormset.form.__init__ = partialmethod(
InterimSessionModelForm.__init__,
user=request.user,
group=group,
@ -3233,7 +3233,7 @@ def interim_request(request):
# subsequently dealt with individually
elif meeting_type == 'series':
series = []
SessionFormset.form.__init__ = curry(
SessionFormset.form.__init__ = partialmethod(
InterimSessionModelForm.__init__,
user=request.user,
group=group,
@ -3453,7 +3453,7 @@ def interim_request_edit(request, number):
group = Group.objects.get(pk=form.data['group'])
is_approved = is_interim_meeting_approved(meeting)
SessionFormset.form.__init__ = curry(
SessionFormset.form.__init__ = partialmethod(
InterimSessionModelForm.__init__,
user=request.user,
group=group,

View file

@ -6,7 +6,7 @@ import re
from django import template
from django.conf import settings
from django.template.defaultfilters import linebreaksbr, force_escape
from django.utils.encoding import force_text, DjangoUnicodeDecodeError
from django.utils.encoding import force_str, DjangoUnicodeDecodeError
from django.utils.safestring import mark_safe
import debug # pyflakes:ignore
@ -68,7 +68,7 @@ def decrypt(string, request, year, plain=False):
code, out, error = pipe(command % (settings.OPENSSL_COMMAND,
encrypted_file.name), key)
try:
out = force_text(out)
out = force_str(out)
except DjangoUnicodeDecodeError:
pass
if code != 0:

View file

@ -18,7 +18,7 @@ from django.http import Http404, HttpResponseRedirect, HttpResponse
from django.shortcuts import render, get_object_or_404, redirect
from django.template.loader import render_to_string
from django.urls import reverse
from django.utils.encoding import force_bytes, force_text
from django.utils.encoding import force_bytes, force_str
from ietf.dbtemplate.models import DBTemplate
@ -684,7 +684,7 @@ def private_questionnaire(request, year):
if form.is_valid():
form.save()
messages.success(request, 'The questionnaire response has been registered.')
questionnaire_response = force_text(form.cleaned_data['comment_text'])
questionnaire_response = force_str(form.cleaned_data['comment_text'])
form = QuestionnaireForm(nomcom=nomcom, user=request.user)
else:
form = QuestionnaireForm(nomcom=nomcom, user=request.user)

View file

@ -16,7 +16,7 @@ from unicodedata import normalize
from django.conf import settings
from django.contrib.auth.models import User
from django.utils.text import slugify
from django.utils.encoding import force_text
from django.utils.encoding import force_str
import debug # pyflakes:ignore
@ -68,7 +68,7 @@ class PersonFactory(factory.django.DjangoModelFactory):
# Some i18n names, e.g., "शिला के.सी." have a dot at the end that is also part of the ASCII, e.g., "Shilaa Kesii."
# That trailing dot breaks extract_authors(). Avoid this issue by stripping the dot from the ASCII.
# Some others have a trailing semicolon (e.g., "உயிரோவியம் தங்கராஐ;") - strip those, too.
ascii = factory.LazyAttribute(lambda p: force_text(unidecode_name(p.name)).rstrip(".;"))
ascii = factory.LazyAttribute(lambda p: force_str(unidecode_name(p.name)).rstrip(".;"))
class Params:
with_bio = factory.Trait(biography = "\n\n".join(fake.paragraphs())) # type: ignore

View file

@ -4,10 +4,11 @@
import datetime
from functools import partialmethod
from django.contrib import messages
from django.forms.formsets import formset_factory
from django.shortcuts import render, get_object_or_404, redirect
from django.utils.functional import curry
import debug # pyflakes:ignore
@ -215,7 +216,7 @@ def doc_detail(request, date, name):
initial_state = {'state':doc.get_state(state_type).pk,
'substate':tag}
# need to use curry here to pass custom variable to form init
# need to use partialmethod here to pass custom variable to form init
if doc.active_ballot():
ballot_type = doc.active_ballot().ballot_type
elif doc.type.slug == 'draft':
@ -223,7 +224,7 @@ def doc_detail(request, date, name):
else:
ballot_type = BallotType.objects.get(doc_type=doc.type)
BallotFormset = formset_factory(BallotForm, extra=0)
BallotFormset.form.__init__ = curry(BallotForm.__init__, ballot_type=ballot_type)
BallotFormset.form.__init__ = partialmethod(BallotForm.__init__, ballot_type=ballot_type)
agenda = agenda_data(date=date)
header = get_section_header(doc, agenda)

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Announcement{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Areas{% endblock %}
{% block extrahead %}{{ block.super }}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Areas - People{% endblock %}
{% block extrahead %}{{ block.super }}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Areas - View{% endblock %}
{% block extrahead %}{{ block.super }}

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
{% load staticfiles %}
{% load static %}
<html lang="en">
<head>
<meta charset="utf-8">

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
{% load staticfiles %}
{% load static %}
<html lang="en">
<head>
<meta charset="utf-8">

View file

@ -1,7 +1,7 @@
{% extends "base_secr.html" %}
{% load i18n %}
{% load ietf_filters %}
{% load staticfiles %}
{% load static %}
{% block title %}{{ title }}{% if user|has_role:"Secretariat" %} Secretariat Dashboard {% else %} IETF Dashboard {% endif %}{% endblock %}

View file

@ -1,7 +1,7 @@
{% extends "base_secr_bootstrap.html" %}
{% load i18n %}
{% load ietf_filters %}
{% load staticfiles %}
{% load static %}
{% block title %}{{ title }}{% if user|has_role:"Secretariat" %} Secretariat Dashboard {% else %} WG Chair Dashboard {% endif %}{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Confirm Cancel{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Confirm Delete{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Meetings - Add{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site_bootstrap.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Meetings{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Meetings - Blue Sheet{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Meetings - Edit{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Meetings{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Meetings{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles tz %}
{% load static tz %}
{% block title %}Meetings{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Meetings{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Rolodex - Add{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Rolodex - Edit{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Rolodex - Search{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Sessions - Confirm{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Sessions - Edit{% endblock %}
{% block extrahead %}{{ block.super }}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Sessions{% endblock %}

View file

@ -1,6 +1,6 @@
{% extends "base_site.html" %}
{% load ietf_filters %}
{% load staticfiles %}
{% load static %}
{% block title %}Sessions{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Sessions- New{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Sessions{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Sessions - View{% endblock %}

View file

@ -1,5 +1,5 @@
{% extends "base_site.html" %}
{% load staticfiles %}
{% load static %}
{% block title %}Telechat{% endblock %}

View file

@ -13,12 +13,11 @@ import warnings
from typing import Any, Dict, List, Tuple # pyflakes:ignore
warnings.simplefilter("always", DeprecationWarning)
warnings.filterwarnings("ignore", message="'urllib3\[secure\]' extra is deprecated")
warnings.filterwarnings("ignore", message="The logout\(\) view is superseded by")
warnings.filterwarnings("ignore", message="'urllib3\\[secure\\]' extra is deprecated")
warnings.filterwarnings("ignore", message="The logout\\(\\) view is superseded by")
warnings.filterwarnings("ignore", message="Report.file_reporters will no longer be available in Coverage.py 4.2", module="coverage.report")
warnings.filterwarnings("ignore", message="{% load staticfiles %} is deprecated")
warnings.filterwarnings("ignore", message="Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated", module="bleach")
warnings.filterwarnings("ignore", message="HTTPResponse.getheader\(\) is deprecated", module='selenium.webdriver')
warnings.filterwarnings("ignore", message="HTTPResponse.getheader\\(\\) is deprecated", module='selenium.webdriver')
try:
import syslog
syslog.openlog(str("datatracker"), syslog.LOG_PID, syslog.LOG_USER)
@ -430,7 +429,6 @@ INSTALLED_APPS = [
'corsheaders',
'django_markup',
'django_password_strength',
'form_utils',
'oidc_provider',
'simple_history',
'tastypie',

View file

@ -39,7 +39,7 @@ DATABASES = {
'HOST': 'db',
'PORT': '5432',
'NAME': 'test.db',
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'ENGINE': 'django.db.backends.postgresql',
'USER': 'django',
'PASSWORD': 'RkTkDPFnKpko',
},

View file

@ -13,7 +13,7 @@ from django.urls import reverse as urlreverse
from django.core.exceptions import ValidationError
from django.contrib.sites.models import Site
from django.template.loader import render_to_string
from django.utils.encoding import force_text, force_str
from django.utils.encoding import force_str
import debug # pyflakes:ignore
@ -202,7 +202,7 @@ def get_reply_to():
address with "plus addressing" using a random string. Guaranteed to be unique"""
local,domain = get_base_submission_message_address().split('@')
while True:
rand = force_text(base64.urlsafe_b64encode(os.urandom(12)))
rand = force_str(base64.urlsafe_b64encode(os.urandom(12)))
address = "{}+{}@{}".format(local,rand,domain)
q = Message.objects.filter(reply_to=address)
if not q:

View file

@ -24,7 +24,7 @@ from django.test import override_settings
from django.test.client import RequestFactory
from django.urls import reverse as urlreverse
from django.utils import timezone
from django.utils.encoding import force_str, force_text
from django.utils.encoding import force_str
import debug # pyflakes:ignore
from ietf.submit.utils import (expirable_submissions, expire_submission, find_submission_filenames,
@ -750,10 +750,10 @@ class SubmitTests(BaseSubmitTestCase):
self.assertTrue("New Version Notification" in outbox[-2]["Subject"])
self.assertTrue(name in get_payload_text(outbox[-2]))
interesting_address = {'ietf':'mars', 'irtf':'irtf-chair', 'iab':'iab-chair', 'ise':'rfc-ise'}[draft.stream_id]
self.assertTrue(interesting_address in force_text(outbox[-2].as_string()))
self.assertTrue(interesting_address in force_str(outbox[-2].as_string()))
if draft.stream_id == 'ietf':
self.assertTrue(draft.ad.role_email("ad").address in force_text(outbox[-2].as_string()))
self.assertTrue(ballot_position.balloter.role_email("ad").address in force_text(outbox[-2].as_string()))
self.assertTrue(draft.ad.role_email("ad").address in force_str(outbox[-2].as_string()))
self.assertTrue(ballot_position.balloter.role_email("ad").address in force_str(outbox[-2].as_string()))
self.assertTrue("New Version Notification" in outbox[-1]["Subject"])
self.assertTrue(name in get_payload_text(outbox[-1]))
r = self.client.get(urlreverse('ietf.doc.views_search.recent_drafts'))

View file

@ -12,7 +12,7 @@ from xml.dom import pulldom, Node
from django.conf import settings
from django.utils import timezone
from django.utils.encoding import smart_bytes, force_str, force_text
from django.utils.encoding import smart_bytes, force_str
import debug # pyflakes:ignore
@ -583,7 +583,7 @@ def post_approved_draft(url, name):
if r.status_code != 200:
raise RuntimeError("Status code is not 200 OK (it's %s)." % r.status_code)
if force_text(r.text) != "OK":
if force_str(r.text) != "OK":
raise RuntimeError('Response is not "OK" (it\'s "%s").' % r.text)
except Exception as e:

View file

@ -47,21 +47,43 @@
method="post"
enctype="multipart/form-data"
data-edit-form="{{ form.edit }}"
data-ajax-info-url="{% url "ietf.liaisons.views.ajax_get_liaison_info" %}">
data-ajax-info-url="{% url 'ietf.liaisons.views.ajax_get_liaison_info' %}">
{% csrf_token %}
{% for fieldset in form.fieldsets %}
<h2>{{ fieldset.name }}</h2>
{% for field in fieldset %}
{% if field.id_for_label != "id_attachments" %}
{% bootstrap_field field layout="horizontal" %}
{% else %}
<div class="row mb-3">
<p class="col-md-2 fw-bold col-form-label">{{ field.label }}</p>
<div class="col-md-10">{{ field }}</div>
</div>
{% endif %}
{% endfor %}
{% endfor %}
<h2>From</h2>
{% bootstrap_field form.from_groups layout="horizontal" %}
{% bootstrap_field form.from_contact layout="horizontal" %}
{% bootstrap_field form.response_contacts layout="horizontal" %}
{% if form.approved %}
{% bootstrap_field form.approved layout="horizontal" %}
{% endif %}
<h2>To</h2>
{% bootstrap_field form.to_groups layout="horizontal" %}
{% bootstrap_field form.to_contacts layout="horizontal" %}
<h2>Other email addresses</h2>
{% bootstrap_field form.technical_contacts layout="horizontal" %}
{% if form.action_holder_contacts %}
{% bootstrap_field form.action_holder_contacts layout="horizontal" %}
{% endif %}
{% bootstrap_field form.cc_contacts layout="horizontal" %}
<h2>Purpose</h2>
{% bootstrap_field form.purpose layout="horizontal" %}
{% bootstrap_field form.deadline layout="horizontal" %}
<h2>Reference</h2>
{% bootstrap_field form.other_identifiers layout="horizontal" %}
{% bootstrap_field form.related_to layout="horizontal" %}
<h2>Liaison Statement</h2>
{% bootstrap_field form.title layout="horizontal" %}
{% bootstrap_field form.submitted_date layout="horizontal" %}
{% bootstrap_field form.body layout="horizontal" %}
<div class="row mb-3">
<p class="col-md-2 fw-bold col-form-label">{{ form.attachments.label }}</p>
<div class="col-md-10">{{ form.attachments }}</div>
</div>
<h2>Add attachment</h2>
{% bootstrap_field form.attach_title layout="horizontal" %}
{% bootstrap_field form.attach_file layout="horizontal" %}
{% bootstrap_field form.attach_button layout="horizontal" %}
<a class="btn btn-danger float-end"
href="{% if liaison %}{% url 'ietf.liaisons.views.liaison_detail' object_id=liaison.pk %}{% else %}{% url 'ietf.liaisons.views.liaison_list' %}{% endif %}">
Cancel

View file

@ -1,7 +1,7 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015-2020, All Rights Reserved #}
{% load origin %}
{% load staticfiles %}
{% load static %}
{% load ietf_filters %}
{% load django_bootstrap5 %}
{% block title %}{{ schedule.name }}: IETF {{ meeting.number }} meeting agenda{% endblock %}

View file

@ -1,7 +1,7 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2015-2020, All Rights Reserved #}
{% load origin %}
{% load staticfiles %}
{% load static %}
{% load ietf_filters %}
{% load django_bootstrap5 %}
{% block content %}

View file

@ -1,6 +1,6 @@
{% extends "base.html" %}
{# Copyright The IETF Trust 2020, All Rights Reserved #}
{% load origin staticfiles django_bootstrap5 %}
{% load origin static django_bootstrap5 %}
{% block title %}
Approved Slides for {{ submission.session.meeting }} : {{ submission.session.group.acronym }}
{% endblock %}

View file

@ -5,7 +5,7 @@
import time, random, hashlib
from django.conf import settings
from django.utils.encoding import force_bytes, force_text
from django.utils.encoding import force_bytes, force_str
def generate_random_key(max_length=32):
@ -18,4 +18,4 @@ def generate_access_token(key, max_length=32):
# we hash it with the private key to make sure only we can
# generate and use the final token - so storing the key in the
# database is safe
return force_text(hashlib.sha256(force_bytes(settings.SECRET_KEY) + force_bytes(key)).hexdigest()[:max_length])
return force_str(hashlib.sha256(force_bytes(settings.SECRET_KEY) + force_bytes(key)).hexdigest()[:max_length])

View file

@ -3,7 +3,7 @@
from django.contrib import admin
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from ietf.utils.models import VersionInfo
@ -14,7 +14,7 @@ def name(obj):
if callable(obj.name):
name = obj.name()
else:
name = force_text(obj.name)
name = force_str(obj.name)
if name:
return name
return str(obj)

View file

@ -27,7 +27,7 @@ from django.core.validators import validate_email
from django.template.loader import render_to_string
from django.template import Context,RequestContext
from django.utils import timezone
from django.utils.encoding import force_text, force_str, force_bytes
from django.utils.encoding import force_str, force_bytes
import debug # pyflakes:ignore
@ -137,7 +137,7 @@ def send_smtp(msg, bcc=None):
server.quit()
except smtplib.SMTPServerDisconnected:
pass
subj = force_text(msg.get('Subject', '[no subject]'))
subj = force_str(msg.get('Subject', '[no subject]'))
tau = time.time() - mark
log("sent email (%.3fs) from '%s' to %s id %s subject '%s'" % (tau, frm, to, msg.get('Message-ID', ''), subj))
@ -166,7 +166,7 @@ def copy_email(msg, to, toUser=False, originalBcc=None):
# Overwrite the From: header, so that the copy from a development or
# test server doesn't look like spam.
new['From'] = settings.DEFAULT_FROM_EMAIL
new['Subject'] = '[Django %s] %s' % (settings.SERVER_MODE, force_text(msg.get('Subject', '[no subject]')))
new['Subject'] = '[Django %s] %s' % (settings.SERVER_MODE, force_str(msg.get('Subject', '[no subject]')))
new['To'] = to
send_smtp(new)
@ -325,7 +325,7 @@ def show_that_mail_was_sent(request,leadline,msg,bcc):
from ietf.ietfauth.utils import has_role
if has_role(request.user,['Area Director','Secretariat','IANA','RFC Editor','ISE','IAD','IRTF Chair','WG Chair','RG Chair','WG Secretary','RG Secretary']):
info = "%s at %s %s\n" % (leadline,timezone.now().strftime("%Y-%m-%d %H:%M:%S"),settings.TIME_ZONE)
info += "Subject: %s\n" % force_text(msg.get('Subject','[no subject]'))
info += "Subject: %s\n" % force_str(msg.get('Subject','[no subject]'))
info += "To: %s\n" % msg.get('To','[no to]')
if msg.get('Cc'):
info += "Cc: %s\n" % msg.get('Cc')
@ -336,7 +336,7 @@ def show_that_mail_was_sent(request,leadline,msg,bcc):
def save_as_message(request, msg, bcc):
by = ((request and request.user and not request.user.is_anonymous and request.user.person)
or ietf.person.models.Person.objects.get(name="(System)"))
headers, body = force_text(str(msg)).split('\n\n', 1)
headers, body = force_str(str(msg)).split('\n\n', 1)
kwargs = {'by': by, 'body': body, 'content_type': msg.get_content_type(), 'bcc': bcc or '' }
for (arg, field) in [
('cc', 'Cc'),

View file

@ -18,7 +18,7 @@ from django.core.exceptions import ObjectDoesNotExist
from django.core import serializers
from django.db import DEFAULT_DB_ALIAS, DatabaseError, IntegrityError, connections
from django.db.models.signals import post_save
from django.utils.encoding import force_text
from django.utils.encoding import force_str
import django.core.management.commands.loaddata as loaddata
import debug # pyflakes:ignore
@ -91,7 +91,7 @@ class Command(loaddata.Command):
obj.save(using=self.using)
self.loaded_object_count += 1
except (DatabaseError, IntegrityError, ObjectDoesNotExist, AttributeError) as e:
error_msg = force_text(e)
error_msg = force_str(e)
if "Duplicate entry" in error_msg:
pass
else:

View file

@ -15,7 +15,7 @@ from django.core.management.base import CommandError
from django.core.management.commands.loaddata import Command as LoadCommand, humanize
from django.db import DatabaseError, IntegrityError, router, transaction
from django.db.models import ManyToManyField
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from ietf.utils.models import ForeignKey
@ -234,7 +234,7 @@ class Command(LoadCommand):
'object_name': obj.object._meta.object_name,
'pk': obj.object.pk,
'data': obj_to_dict(obj.object),
'error_msg': force_text(e)
'error_msg': force_str(e)
},)
raise
if objects and show_progress:

View file

@ -7,7 +7,7 @@ import datetime
from django.conf import settings
from django.contrib.auth.models import User
from django.utils import timezone
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str
import debug # pyflakes:ignore
@ -38,7 +38,7 @@ def create_person(group, role_name, name=None, username=None, email_address=None
user = User.objects.create(username=username,is_staff=is_staff,is_superuser=is_superuser)
user.set_password(password)
user.save()
person = Person.objects.create(name=name, ascii=unidecode_name(smart_text(name)), user=user)
person = Person.objects.create(name=name, ascii=unidecode_name(smart_str(name)), user=user)
email = Email.objects.create(address=email_address, person=person, origin=user.username)
Role.objects.create(group=group, name_id=role_name, person=person, email=email)
return person

View file

@ -95,7 +95,7 @@ old_create = None
template_coverage_collection = None
code_coverage_collection = None
url_coverage_collection = None
validation_settings = {"validate_html": None, "validate_html_harder": None, "show_logging": False}
def start_vnu_server(port=8888):
"Start a vnu validation server on the indicated port"
@ -282,7 +282,7 @@ class ValidatingTemplates(DjangoTemplates):
def __init__(self, params):
super().__init__(params)
if not settings.validate_html:
if not validation_settings["validate_html"]:
return
self.validation_cache = set()
self.cwd = str(pathlib.Path.cwd())
@ -298,7 +298,7 @@ class ValidatingTemplate(Template):
def render(self, context=None, request=None):
content = super().render(context, request)
if not settings.validate_html:
if not validation_settings["validate_html"]:
return content
if not self.origin.name.endswith("html"):
@ -310,7 +310,7 @@ class ValidatingTemplate(Template):
return content
fingerprint = hash(content) + sys.maxsize + 1 # make hash positive
if not settings.validate_html_harder and fingerprint in self.backend.validation_cache:
if not validation_settings["validate_html_harder"] and fingerprint in self.backend.validation_cache:
# already validated this HTML fragment, skip it
# as an optimization, make page a bit smaller by not returning HTML for the menus
# FIXME: figure out why this still includes base/menu.html
@ -326,7 +326,7 @@ class ValidatingTemplate(Template):
# don't validate each template by itself, causes too much overhead
# instead, save a batch of them and then validate them all in one go
# this delays error detection a bit, but is MUCH faster
settings.validate_html.batches[kind].append(
validation_settings["validate_html"].batches[kind].append(
(self.origin.name, content, fingerprint)
)
return content
@ -726,9 +726,10 @@ class IetfTestRunner(DiscoverRunner):
self.html_report = html_report
self.permit_mixed_migrations = permit_mixed_migrations
self.show_logging = show_logging
settings.validate_html = self if validate_html else None
settings.validate_html_harder = self if validate_html and validate_html_harder else None
settings.show_logging = show_logging
global validation_settings
validation_settings["validate_html"] = self if validate_html else None
validation_settings["validate_html_harder"] = self if validate_html and validate_html_harder else None
validation_settings["show_logging"] = show_logging
#
self.root_dir = os.path.dirname(settings.BASE_DIR)
self.coverage_file = os.path.join(self.root_dir, settings.TEST_COVERAGE_MAIN_FILE)
@ -843,7 +844,7 @@ class IetfTestRunner(DiscoverRunner):
s[1] = tuple(s[1]) # random.setstate() won't accept a list in lieu of a tuple
factory.random.set_random_state(s)
if not settings.validate_html:
if not validation_settings["validate_html"]:
print(" Not validating any generated HTML; "
"please do so at least once before committing changes")
else:
@ -912,7 +913,7 @@ class IetfTestRunner(DiscoverRunner):
self.config_file[kind].flush()
pathlib.Path(self.config_file[kind].name).chmod(0o644)
if not settings.validate_html_harder:
if not validation_settings["validate_html_harder"]:
print("")
self.vnu = None
else:
@ -941,7 +942,7 @@ class IetfTestRunner(DiscoverRunner):
with open(self.coverage_file, "w") as file:
json.dump(self.coverage_master, file, indent=2, sort_keys=True)
if settings.validate_html:
if validation_settings["validate_html"]:
for kind in self.batches:
if len(self.batches[kind]):
print(f" WARNING: not all templates of kind '{kind}' were validated")
@ -1007,7 +1008,7 @@ class IetfTestRunner(DiscoverRunner):
+ "\n"
)
if settings.validate_html_harder and kind != "frag":
if validation_settings["validate_html_harder"] and kind != "frag":
files = [
os.path.join(d, f)
for d, dirs, files in os.walk(tmppath)
@ -1084,7 +1085,7 @@ class IetfTestRunner(DiscoverRunner):
self.test_apps, self.test_paths = self.get_test_paths(test_labels)
if settings.validate_html:
if validation_settings["validate_html"]:
extra_tests += [
TemplateValidationTests(
test_runner=self,

View file

@ -1,6 +1,6 @@
--- django/http/response.py.orig 2020-07-08 14:34:42.776562458 +0200
+++ django/http/response.py 2020-07-08 14:35:56.454687322 +0200
@@ -197,8 +197,8 @@
@@ -196,8 +196,8 @@
if httponly:
self.cookies[key]['httponly'] = True
if samesite:

View file

@ -11,7 +11,7 @@
--- django/http/response.py.orig 2020-08-13 11:16:04.060627793 +0200
+++ django/http/response.py 2020-08-13 11:54:03.482476973 +0200
@@ -210,12 +210,18 @@
@@ -209,12 +209,18 @@
value = signing.get_cookie_signer(salt=key + salt).sign(value)
return self.set_cookie(key, value, **kwargs)
@ -35,12 +35,12 @@
--- django/contrib/sessions/middleware.py.orig 2020-08-13 12:12:12.401898114 +0200
+++ django/contrib/sessions/middleware.py 2020-08-13 12:14:52.690520659 +0200
@@ -39,6 +39,8 @@
settings.SESSION_COOKIE_NAME,
path=settings.SESSION_COOKIE_PATH,
domain=settings.SESSION_COOKIE_DOMAIN,
+ secure=settings.SESSION_COOKIE_SECURE or None,
+ httponly=settings.SESSION_COOKIE_HTTPONLY or None,
samesite=settings.SESSION_COOKIE_SAMESITE,
)
else:
@@ -38,6 +38,8 @@
settings.SESSION_COOKIE_NAME,
path=settings.SESSION_COOKIE_PATH,
domain=settings.SESSION_COOKIE_DOMAIN,
+ secure=settings.SESSION_COOKIE_SECURE or None,
+ httponly=settings.SESSION_COOKIE_HTTPONLY or None,
samesite=settings.SESSION_COOKIE_SAMESITE,
)
patch_vary_headers(response, ('Cookie',))

View file

@ -1,5 +1,5 @@
# -*- conf-mode -*-
setuptools>=51.1.0 # Require this first, to prevent later errors
setuptools>=51.1.0,<67.5.0 # Require this first, to prevent later errors
#
argon2-cffi>=21.3.0 # For the Argon2 password hasher option
beautifulsoup4>=4.11.1 # Only used in tests
@ -9,14 +9,13 @@ celery>=5.2.6
coverage>=4.5.4,<5.0 # Coverage 5.x moves from a json database to SQLite. Moving to 5.x will require substantial rewrites in ietf.utils.test_runner and ietf.release.views
decorator>=5.1.1
defusedxml>=0.7.1 # for TastyPie when using xml; not a declared dependency
Django>=2.2.28,<3.0
Django<3.1
django-analytical>=3.1.0
django-bootstrap5>=21.3
django-celery-beat>=2.3.0
django-csp>=3.7
django-cors-headers>=3.11.0
django-debug-toolbar>=3.2.4
django-form-utils>=1.0.3 # Only one use, in the liaisons app. Last release was in 2015.
django-markup>=1.5 # Limited use - need to reconcile against direct use of markdown
django-oidc-provider>=0.7,<0.8 # 0.8 dropped Django 2 support
django-password-strength>=1.2.1