django3: try to read signed cookie content in tests (#64305)

This commit is contained in:
Paul Marillonnet 2022-04-25 11:09:14 +02:00
parent 9b0ac49118
commit 7cedc98567
4 changed files with 57 additions and 10 deletions

View File

@ -37,7 +37,7 @@ from authentic2_auth_fc import models
from authentic2_auth_fc.backends import FcBackend
from authentic2_auth_fc.utils import requests_retry_session
from ..utils import assert_event, get_link_from_mail, login, set_service
from ..utils import assert_event, decode_cookie, get_link_from_mail, login, set_service
User = get_user_model()
@ -215,7 +215,11 @@ def test_login_email_is_unique_and_already_linked(settings, app, franceconnect,
response = response.click(href='callback')
response = franceconnect.handle_authorization(app, response.location, status=302)
assert models.FcAccount.objects.count() == 1
assert 'is already used' in app.cookies['messages']
cookie = decode_cookie(app.cookies['messages'])
if isinstance(cookie, list):
assert len(cookie) == 1
cookie = cookie[0].message
assert 'is already used' in cookie
assert '_auth_user_id' not in app.session
@ -293,7 +297,11 @@ def test_login_with_missing_required_attributes(settings, app, franceconnect):
assert path(response.location) == '/accounts/edit/'
assert User.objects.count() == 1
assert models.FcAccount.objects.count() == 1
assert 'The following fields are mandatory for account creation: Title' in app.cookies['messages']
cookie = decode_cookie(app.cookies['messages'])
if isinstance(cookie, list):
assert len(cookie) == 1
cookie = cookie[0].message
assert 'The following fields are mandatory for account creation: Title' in cookie
def test_can_change_password(settings, app, franceconnect):
@ -368,7 +376,11 @@ def test_user_info_incomplete_already_linked(settings, app, franceconnect, simpl
response = login(app, simple_user, path='/accounts/')
response = response.click(href='callback')
response = franceconnect.handle_authorization(app, response.location, status=302)
assert 'FranceConnect account is already' in app.cookies['messages']
cookie = decode_cookie(app.cookies['messages'])
if isinstance(cookie, list):
assert len(cookie) == 1
cookie = cookie[0].message
assert 'FranceConnect account is already' in cookie
def test_save_account_on_delete_user(db):

View File

@ -531,7 +531,11 @@ def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, hooks):
with utils.check_log(caplog, "'error': 'invalid request'"):
with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code):
response = app.get(login_callback_url(oidc_provider), params={'code': 'yyyy', 'state': state})
assert 'Authentication on Server failed with error' in app.cookies['messages']
cookie = utils.decode_cookie(app.cookies['messages'])
if isinstance(cookie, list):
assert len(cookie) == 1
cookie = cookie[0].message
assert 'Authentication on Server failed with error' in cookie
with utils.check_log(caplog, 'invalid id_token'):
with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code, extra_id_token={'iss': None}):
response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state})

View File

@ -89,7 +89,7 @@ class TestDeleteAccountEmailVerified:
assert len(mailoutbox) == 2
assert mailoutbox[1].subject == 'Account deletion on testserver'
assert mailoutbox[0].to == [simple_user.email]
assert "Deletion performed" in str(response) # Set-Cookie: messages..
assert "Set-Cookie: messages=" in str(response) # Deletion performed
assert urlparse(response.location).path == '/'
def test_account_delete_when_logged_out(self, app, simple_user, mailoutbox):
@ -112,7 +112,7 @@ class TestDeleteAccountEmailVerified:
assert len(mailoutbox) == 2
assert mailoutbox[1].subject == 'Account deletion on testserver'
assert mailoutbox[0].to == [simple_user.email]
assert "Deletion performed" in str(response) # Set-Cookie: messages..
assert "Set-Cookie: messages=" in str(response) # Deletion performed
assert urlparse(response.location).path == '/'
def test_account_delete_by_other_user(self, app, simple_user, user_ou1, mailoutbox):
@ -138,7 +138,7 @@ class TestDeleteAccountEmailVerified:
assert len(mailoutbox) == 2
assert mailoutbox[1].subject == 'Account deletion on testserver'
assert mailoutbox[0].to == [simple_user.email]
assert "Deletion performed" in str(response) # Set-Cookie: messages..
assert "Set-Cookie: messages=" in str(response) # Deletion performed
assert urlparse(response.location).path == '/'
def test_account_delete_fake_token(self, app, simple_user, mailoutbox):
@ -188,7 +188,7 @@ class TestDeleteAccountEmailNotVerified:
assert len(mailoutbox) == 1
assert mailoutbox[0].subject == 'Account deletion on testserver'
assert mailoutbox[0].to == [simple_user.email]
assert "Deletion performed" in str(response) # Set-Cookie: messages..
assert "Set-Cookie: messages=" in str(response) # Deletion performed
assert urlparse(response.location).path == '/'
def test_account_delete_old_authentication(self, app, simple_user, mailoutbox, freezer):
@ -208,7 +208,7 @@ class TestDeleteAccountEmailNotVerified:
assert len(mailoutbox) == 1
assert mailoutbox[0].subject == 'Account deletion on testserver'
assert mailoutbox[0].to == [simple_user.email]
assert "Deletion performed" in str(response) # Set-Cookie: messages..
assert "Set-Cookie: messages=" in str(response) # Deletion performed
assert urlparse(response.location).path == '/'

View File

@ -21,6 +21,26 @@ import socket
import urllib.parse
from contextlib import closing, contextmanager
from django.contrib.messages.storage.cookie import MessageDecoder, MessageEncoder
try:
from django.contrib.messages.storage.cookie import MessageSerializer
except ImportError: # oops, not running in django3
import json
class MessageSerializer:
def dumps(self, obj):
return json.dumps(
obj,
separators=(',', ':'),
cls=MessageEncoder,
).encode('latin-1')
def loads(self, data):
return json.loads(data.decode('latin-1'), cls=MessageDecoder)
from django.core import signing
from django.core.management import call_command as django_call_command
from django.shortcuts import resolve_url
from django.test import TestCase
@ -325,3 +345,14 @@ def set_service(app, service):
session.save()
if app.session == {}:
app.set_cookie(settings.SESSION_COOKIE_NAME, session.session_key)
def decode_cookie(data):
signer = signing.get_cookie_signer(salt='django.contrib.messages')
try:
return signer.unsign_object(data, serializer=MessageSerializer)
except signing.BadSignature:
return None
except AttributeError:
# xxx support legacy decoding?
return data