1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Fixed #32191 -- Made CookieStorage use RFC 6265 compliant format.

Co-authored-by: Craig Smith <hello@craigiansmith.com.au>
This commit is contained in:
Florian Apolloner
2020-12-19 15:38:32 +01:00
committed by Mariusz Felisiak
parent 3eb98743dc
commit 2d6179c819
7 changed files with 91 additions and 14 deletions

View File

@@ -1,4 +1,5 @@
import json
import random
from django.conf import settings
from django.contrib.messages import constants
@@ -6,8 +7,10 @@ from django.contrib.messages.storage.base import Message
from django.contrib.messages.storage.cookie import (
CookieStorage, MessageDecoder, MessageEncoder,
)
from django.core.signing import get_cookie_signer
from django.test import SimpleTestCase, override_settings
from django.test.utils import ignore_warnings
from django.utils.crypto import get_random_string
from django.utils.deprecation import RemovedInDjango40Warning
from django.utils.safestring import SafeData, mark_safe
@@ -71,7 +74,9 @@ class CookieTests(BaseTests, SimpleTestCase):
response = self.get_response()
storage.add(constants.INFO, 'test')
storage.update(response)
self.assertIn('test', response.cookies['messages'].value)
messages = storage._decode(response.cookies['messages'].value)
self.assertEqual(len(messages), 1)
self.assertEqual(messages[0].message, 'test')
self.assertEqual(response.cookies['messages']['domain'], '.example.com')
self.assertEqual(response.cookies['messages']['expires'], '')
self.assertIs(response.cookies['messages']['secure'], True)
@@ -116,15 +121,30 @@ class CookieTests(BaseTests, SimpleTestCase):
# size which will fit 4 messages into the cookie, but not 5.
# See also FallbackTest.test_session_fallback
msg_size = int((CookieStorage.max_cookie_size - 54) / 4.5 - 37)
first_msg = None
# Generate the same (tested) content every time that does not get run
# through zlib compression.
random.seed(42)
for i in range(5):
storage.add(constants.INFO, str(i) * msg_size)
msg = get_random_string(msg_size)
storage.add(constants.INFO, msg)
if i == 0:
first_msg = msg
unstored_messages = storage.update(response)
cookie_storing = self.stored_messages_count(storage, response)
self.assertEqual(cookie_storing, 4)
self.assertEqual(len(unstored_messages), 1)
self.assertEqual(unstored_messages[0].message, '0' * msg_size)
self.assertEqual(unstored_messages[0].message, first_msg)
def test_message_rfc6265(self):
non_compliant_chars = ['\\', ',', ';', '"']
messages = ['\\te,st', ';m"e', '\u2019', '123"NOTRECEIVED"']
storage = self.get_storage()
encoded = storage._encode(messages)
for illegal in non_compliant_chars:
self.assertEqual(encoded.find(illegal), -1)
def test_json_encoder_decoder(self):
"""
@@ -172,6 +192,19 @@ class CookieTests(BaseTests, SimpleTestCase):
decoded_messages = storage._decode(encoded_messages)
self.assertEqual(messages, decoded_messages)
def test_legacy_encode_decode(self):
# RemovedInDjango41Warning: pre-Django 3.2 encoded messages will be
# invalid.
storage = self.storage_class(self.get_request())
messages = ['this', 'that']
# Encode/decode a message using the pre-Django 3.2 format.
encoder = MessageEncoder()
value = encoder.encode(messages)
signer = get_cookie_signer(salt=storage.key_salt)
encoded_messages = signer.sign(value)
decoded_messages = storage._decode(encoded_messages)
self.assertEqual(messages, decoded_messages)
@ignore_warnings(category=RemovedInDjango40Warning)
def test_default_hashing_algorithm(self):
messages = Message(constants.DEBUG, ['this', 'that'])