From 8b9746b0be7044d7eef352e35cca87eefc224df8 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Wed, 30 Nov 2022 14:43:02 +0100 Subject: [PATCH 1/2] settings: set secure flag on cookies (#71880) Tests fixes : * force https scheme in webtest HTTP client * add secure=True to call with the django HTTP client * replace http scheme by https in URLs assertions, * properly use response.form in tests directly using app.post, as CSRF checks on secure connection also test the Referrer * manually add Referer header in other cases, --- src/authentic2/settings.py | 5 ++++ tests/api/test_all.py | 16 ++++++------- tests/auth_fc/conftest.py | 4 ++-- tests/auth_fc/test_auth_fc.py | 2 +- tests/auth_fc/test_auth_fc_api.py | 4 ++-- tests/conftest.py | 6 +++-- tests/idp_oidc/test_misc.py | 4 ++-- tests/settings.py | 2 +- tests/test_attribute_kinds.py | 2 +- tests/test_auth_oidc.py | 2 +- tests/test_commands.py | 2 +- tests/test_csv_import.py | 2 +- tests/test_idp_saml2.py | 16 +++++++------ tests/test_manager.py | 40 ++++++++++++++++++++++--------- tests/test_password_reset.py | 15 ++++-------- tests/test_registration.py | 11 +++------ tests/test_role_manager.py | 8 +++++-- tests/test_user_manager.py | 4 +++- 18 files changed, 84 insertions(+), 61 deletions(-) diff --git a/src/authentic2/settings.py b/src/authentic2/settings.py index 688ed251..14e77979 100644 --- a/src/authentic2/settings.py +++ b/src/authentic2/settings.py @@ -55,6 +55,11 @@ DATABASES = { } } +# Cookies +SESSION_COOKIE_SECURE = True +CSRF_COOKIE_SECURE = True +LANGUAGE_COOKIE_SECURE = True + # Hey Entr'ouvert is in France !! TIME_ZONE = 'Europe/Paris' LANGUAGE_CODE = 'fr' diff --git a/tests/api/test_all.py b/tests/api/test_all.py index 24bd654c..6d313bac 100644 --- a/tests/api/test_all.py +++ b/tests/api/test_all.py @@ -100,12 +100,12 @@ def test_api_user(client): Role.objects.create(name='Role4', service=service) # test failure when unlogged - response = client.get('/api/user/', HTTP_ORIGIN='http://testserver') + response = client.get('/api/user/', HTTP_ORIGIN='https://testserver', secure=True) assert response.content == b'{}' # login client.login(request=None, username='john.doe', password='password') - response = client.get('/api/user/', HTTP_ORIGIN='http://testserver') + response = client.get('/api/user/', HTTP_ORIGIN='https://testserver', secure=True) data = json.loads(force_str(response.content)) assert isinstance(data, dict) assert set(data.keys()) == { @@ -1055,7 +1055,7 @@ def test_register_no_email_validation(settings, app, admin, django_user_model): assert response.json['user']['last_name'] == last_name assert check_password(password, response.json['user']['password']) assert response.json['token'] - assert response.json['validation_url'].startswith('http://testserver/accounts/activate/') + assert response.json['validation_url'].startswith('https://testserver/accounts/activate/') assert User.objects.count() == 2 user = User.objects.latest('id') assert user.ou == get_default_ou() @@ -1114,7 +1114,7 @@ def test_register_ou_no_email_validation(settings, app, admin, django_user_model assert response.json['user']['last_name'] == last_name assert check_password(password, response.json['user']['password']) assert response.json['token'] - assert response.json['validation_url'].startswith('http://testserver/accounts/activate/') + assert response.json['validation_url'].startswith('https://testserver/accounts/activate/') assert User.objects.count() == 2 user = User.objects.latest('id') assert user.username == username @@ -1232,7 +1232,7 @@ def test_password_reset(app, ou1, admin, user_ou1, mailoutbox): assert len(mailoutbox) == 1 mail = mailoutbox[0] assert mail.to[0] == email - assert 'http://testserver/password/reset/confirm/' in mail.body + assert 'https://testserver/password/reset/confirm/' in mail.body assert_event('manager.user.password.reset.request', user=admin, api=True) @@ -1265,7 +1265,7 @@ def test_users_email(app, ou1, admin, user_ou1, mailoutbox): mail = mailoutbox[0] assert mail.to[0] == new_email - assert 'http://testserver/accounts/change-email/verify/' in mail.body + assert 'https://testserver/accounts/change-email/verify/' in mail.body def test_api_delete_role(app, admin_ou1, role_ou1): @@ -2391,7 +2391,7 @@ def test_api_statistics_list(app, admin): assert len(resp.json['data']) == 6 login_stats = { 'name': 'Login count by authentication type', - 'url': 'http://testserver/api/statistics/login/', + 'url': 'https://testserver/api/statistics/login/', 'id': 'login', 'filters': [ { @@ -2411,7 +2411,7 @@ def test_api_statistics_list(app, admin): assert login_stats in resp.json['data'] assert { 'name': 'Login count by service', - 'url': 'http://testserver/api/statistics/service_login/', + 'url': 'https://testserver/api/statistics/service_login/', 'id': 'service-login', 'filters': [ { diff --git a/tests/auth_fc/conftest.py b/tests/auth_fc/conftest.py index 8177a3e6..bb19a08d 100644 --- a/tests/auth_fc/conftest.py +++ b/tests/auth_fc/conftest.py @@ -80,7 +80,7 @@ class FranceConnectMock: @property def callback_url(self): - return 'http://testserver' + reverse('fc-login-or-link') + return 'https://testserver' + reverse('fc-login-or-link') def login_with_fc_fixed_params(self, app): if app.session: @@ -154,7 +154,7 @@ class FranceConnectMock: assert url.startswith('https://fcp.integ01.dev-franceconnect.fr/api/v1/logout') parsed_url = urllib.parse.urlparse(url) query = QueryDict(parsed_url.query) - assert_equals_url(query['post_logout_redirect_uri'], 'http://testserver' + reverse('fc-logout')) + assert_equals_url(query['post_logout_redirect_uri'], 'https://testserver' + reverse('fc-logout')) assert query['state'] self.state = query['state'] return app.get(reverse('fc-logout') + '?state=' + self.state) diff --git a/tests/auth_fc/test_auth_fc.py b/tests/auth_fc/test_auth_fc.py index a3852306..bda6a1ec 100644 --- a/tests/auth_fc/test_auth_fc.py +++ b/tests/auth_fc/test_auth_fc.py @@ -128,7 +128,7 @@ def test_create(settings, app, franceconnect, hooks, service, mailoutbox): for body in (mailoutbox[0].body, mailoutbox[0].alternatives[0][0]): assert 'Hi AnonymousUser,' in body assert 'You have just created an account using FranceConnect.' in body - assert 'http://testserver/login/' in body + assert 'https://testserver/login/' in body assert user.verified_attributes.first_name == 'Ÿuñe' assert user.verified_attributes.last_name == 'Frédérique' diff --git a/tests/auth_fc/test_auth_fc_api.py b/tests/auth_fc/test_auth_fc_api.py index 77572f66..a9a35562 100644 --- a/tests/auth_fc/test_auth_fc_api.py +++ b/tests/auth_fc/test_auth_fc_api.py @@ -43,9 +43,9 @@ def test_api_user_franceconnect(settings, app, admin, simple_user, franceconnect content = response.json['franceconnect'] assert isinstance(content, dict), 'franceconnect field is not a dict' assert content.get('linked') is True - assert content.get('link_url').startswith('http://') + assert content.get('link_url').startswith('https://') assert content.get('link_url').endswith('/callback/') - assert content.get('unlink_url').startswith('http://') + assert content.get('unlink_url').startswith('https://') assert content.get('unlink_url').endswith('/unlink/') unlink_url = '/api/users/%s/fc-unlink/' % simple_user.uuid diff --git a/tests/conftest.py b/tests/conftest.py index ecf6765f..53c78603 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -63,7 +63,9 @@ def app_factory(): try: def factory(hostname='testserver'): - return django_webtest.DjangoTestApp(extra_environ={'HTTP_HOST': hostname}) + return django_webtest.DjangoTestApp( + extra_environ={'HTTP_HOST': hostname, 'wsgi.url_scheme': 'https'} + ) yield factory finally: @@ -420,7 +422,7 @@ def assert_external_redirect(external_redirect): else: def check_location(response, default_return): - assert urllib.parse.urljoin('http://testserver/', default_return).endswith(response['Location']) + assert urllib.parse.urljoin('https://testserver/', default_return).endswith(response['Location']) return check_location diff --git a/tests/idp_oidc/test_misc.py b/tests/idp_oidc/test_misc.py index 68e6ccc5..bc5f42b3 100644 --- a/tests/idp_oidc/test_misc.py +++ b/tests/idp_oidc/test_misc.py @@ -353,7 +353,7 @@ def test_authorization_code_sso( with open('tests/200x200.jpg', 'rb') as fd: simple_user.attributes.cityscape_image = File(fd) response = app.get(user_info_url, headers=bearer_authentication_headers(access_token)) - assert response.json['cityscape_image'].startswith('http://testserver/media/profile-image/') + assert response.json['cityscape_image'].startswith('https://testserver/media/profile-image/') # check against a user without username simple_user.username = None @@ -381,7 +381,7 @@ def test_authorization_code_sso( src = iframes.attr('src') assert '?' in src src_qd = QueryDict(src.split('?', 1)[1]) - assert 'iss' in src_qd and src_qd['iss'] == 'http://testserver/' + assert 'iss' in src_qd and src_qd['iss'] == 'https://testserver/' assert 'sid' in src_qd and src_qd['sid'] == get_session_id( mock.Mock(session=app.session), oidc_client ) diff --git a/tests/settings.py b/tests/settings.py index 89e63fa3..fbf94ed4 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -55,7 +55,7 @@ A2_HOOKS_PROPAGATE_EXCEPTIONS = True TEMPLATES[0]['DIRS'].append('tests/templates') # pylint: disable=undefined-variable TEMPLATES[0]['OPTIONS']['debug'] = True # pylint: disable=undefined-variable -SITE_BASE_URL = 'http://testserver' +SITE_BASE_URL = 'https://testserver' A2_MAX_EMAILS_PER_IP = None A2_MAX_EMAILS_FOR_ADDRESS = None diff --git a/tests/test_attribute_kinds.py b/tests/test_attribute_kinds.py index 2b41e20e..3eb32c1e 100644 --- a/tests/test_attribute_kinds.py +++ b/tests/test_attribute_kinds.py @@ -541,7 +541,7 @@ def test_profile_image(db, app, admin, mailoutbox): response = app.get('/api/users/%s/' % john().uuid) assert ( response.json['cityscape_image'] - == 'http://testserver/media/%s' % john().attributes.cityscape_image.name + == 'https://testserver/media/%s' % john().attributes.cityscape_image.name ) app.authorization = None diff --git a/tests/test_auth_oidc.py b/tests/test_auth_oidc.py index 5551c4a8..b1cbb663 100644 --- a/tests/test_auth_oidc.py +++ b/tests/test_auth_oidc.py @@ -511,7 +511,7 @@ def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, hooks): assert query['response_type'] == 'code' assert query['client_id'] == str(oidc_provider.client_id) assert query['scope'] == 'openid' - assert query['redirect_uri'] == 'http://testserver' + reverse('oidc-login-callback') + assert query['redirect_uri'] == 'https://testserver' + reverse('oidc-login-callback') nonce = query['nonce'] if oidc_provider.claims_parameter_supported: diff --git a/tests/test_commands.py b/tests/test_commands.py index 2c37d942..ac049984 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -256,7 +256,7 @@ def test_clean_unused_account_login_url(simple_user, mailoutbox): simple_user.save() call_command('clean-unused-accounts') mail = mailoutbox[0] - assert 'href="http://testserver/login/"' in mail.message().as_string() + assert 'href="https://testserver/login/"' in mail.message().as_string() def test_clean_unused_account_with_no_email(simple_user, mailoutbox, caplog): diff --git a/tests/test_csv_import.py b/tests/test_csv_import.py index 0d007f1d..9409eae6 100644 --- a/tests/test_csv_import.py +++ b/tests/test_csv_import.py @@ -559,7 +559,7 @@ tnoel@entrouvert.com,Thomas,Noël,''' assert importer.run() thomas = User.objects.get(email='tnoel@entrouvert.com') assert len(mail.outbox) == 1 - assert 'http://testserver/password/reset/confirm/' in mail.outbox[0].body + assert 'https://testserver/password/reset/confirm/' in mail.outbox[0].body password = thomas.password del mail.outbox[0] diff --git a/tests/test_idp_saml2.py b/tests/test_idp_saml2.py index fe4f355e..2322f156 100644 --- a/tests/test_idp_saml2.py +++ b/tests/test_idp_saml2.py @@ -149,7 +149,7 @@ class SamlSP: self.base_url = 'https://sp.example.com' self.name = 'Test SP' self.slug = 'test-sp' - self.idp_entity_idp = ('http://testserver/idp/saml2/metadata',) + self.idp_entity_idp = ('https://testserver/idp/saml2/metadata',) self.default_name_id_format = 'email' self.accepted_name_id_format = ['email', 'persistent', 'transient', 'username'] self.ou = OrganizationalUnit.objects.get() @@ -504,7 +504,7 @@ class Scenario: ), ( "/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name='avatar']/saml:AttributeValue", - re.compile('^http://testserver/media/profile-image/.*$'), + re.compile('^https://testserver/media/profile-image/.*$'), ), ( "/saml:Assertion/saml:AttributeStatement/saml:Attribute[@Name='verified_attributes']/@NameFormat", @@ -662,7 +662,7 @@ def add_attributes(rf): with mock.patch( 'authentic2.idp.saml.saml2_endpoints.get_attributes', wraps=saml2_endpoints.get_attributes ) as get_attributes: - request = rf.get('/') + request = rf.get('/', secure=True) request.user = None assertion = lasso.Saml2Assertion() provider = Service(ou=None) @@ -815,14 +815,16 @@ def test_make_edu_person_targeted_id(db, settings, rf): == '_' + hashlib.sha256(b'b' + b'https://sp.com/' + b'a').hexdigest().upper() ) - edpt = saml2_endpoints.make_edu_person_targeted_id('http://testserver/idp/saml2/metadata', provider, user) + edpt = saml2_endpoints.make_edu_person_targeted_id( + 'https://testserver/idp/saml2/metadata', provider, user + ) assert edpt is not None node = lasso.Node.newFromXmlNode(force_str(ET.tostring(edpt))) assert isinstance(node, lasso.Saml2NameID) assert force_str(node.content) == '_A485C0ACEEF43A6D39145F5CFE25D9D3B6F15DC6443F412263C76D81C72DA8D5' assert node.format == lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT - assert node.nameQualifier == 'http://testserver/idp/saml2/metadata' + assert node.nameQualifier == 'https://testserver/idp/saml2/metadata' assert node.spNameQualifier == 'https://sp.com/' @@ -854,7 +856,7 @@ def test_add_attributes_edu_person_targeted_id_nid_format(db, settings, rf, add_ assert isinstance(node, lasso.Saml2NameID) assert force_str(node.content) == '_A485C0ACEEF43A6D39145F5CFE25D9D3B6F15DC6443F412263C76D81C72DA8D5' assert node.format == lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT - assert node.nameQualifier == 'http://testserver/idp/saml2/metadata' + assert node.nameQualifier == 'https://testserver/idp/saml2/metadata' assert node.spNameQualifier == 'https://sp.com/' @@ -886,7 +888,7 @@ def test_add_attributes_edu_person_targeted_id_attribute(db, settings, rf, add_a assert isinstance(node, lasso.Saml2NameID) assert force_str(node.content) == '_A485C0ACEEF43A6D39145F5CFE25D9D3B6F15DC6443F412263C76D81C72DA8D5' assert node.format == lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT - assert node.nameQualifier == 'http://testserver/idp/saml2/metadata' + assert node.nameQualifier == 'https://testserver/idp/saml2/metadata' assert node.spNameQualifier == 'https://sp.com/' diff --git a/tests/test_manager.py b/tests/test_manager.py index b48fe07e..f388c63e 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -1034,7 +1034,7 @@ def test_manager_role_admin_permissions(app, simple_user, admin, simple_role): assert q('table tbody tr td .icon-remove-sign') token = str(response.context['csrf_token']) params = {'action': 'remove', 'user_or_role': 'user-%s' % admin.pk, 'csrfmiddlewaretoken': token} - app.post('/manage/roles/%s/' % simple_role.pk, params=params) + app.post('/manage/roles/%s/' % simple_role.pk, params=params, headers={'Referer': 'https://testserver/'}) assert simple_role not in admin.roles.all() # user can act on role inheritance @@ -1049,21 +1049,33 @@ def test_manager_role_admin_permissions(app, simple_user, admin, simple_role): response = app.get('/manage/roles/%s/children/' % simple_role.pk) token = str(response.context['csrf_token']) params = {'action': 'add', 'role': role.pk, 'csrfmiddlewaretoken': token} - response = app.post('/manage/roles/%s/children/' % simple_role.pk, params=params) + response = app.post( + '/manage/roles/%s/children/' % simple_role.pk, + params=params, + headers={'Referer': 'https://testserver/'}, + ) assert role in simple_role.children() params = {'action': 'remove', 'role': role.pk, 'csrfmiddlewaretoken': token} - response = app.post('/manage/roles/%s/children/' % simple_role.pk, params=params) + response = app.post( + '/manage/roles/%s/children/' % simple_role.pk, + params=params, + headers={'Referer': 'https://testserver/'}, + ) assert role not in simple_role.children() response = app.get('/manage/roles/%s/parents/' % role.pk) token = str(response.context['csrf_token']) params = {'action': 'add', 'role': simple_role.pk, 'csrfmiddlewaretoken': token} - response = app.post('/manage/roles/%s/parents/' % role.pk, params=params) + response = app.post( + '/manage/roles/%s/parents/' % role.pk, params=params, headers={'Referer': 'https://testserver/'} + ) assert simple_role in role.parents() params = {'action': 'remove', 'role': simple_role.pk, 'csrfmiddlewaretoken': token} - response = app.post('/manage/roles/%s/parents/' % role.pk, params=params) + response = app.post( + '/manage/roles/%s/parents/' % role.pk, params=params, headers={'Referer': 'https://testserver/'} + ) assert simple_role not in role.parents() # user can add role as a member through role members form @@ -1078,7 +1090,7 @@ def test_manager_role_admin_permissions(app, simple_user, admin, simple_role): assert q('table tbody tr td .icon-remove-sign') token = str(response.context['csrf_token']) params = {'action': 'remove', 'user_or_role': 'role-%s' % role.pk, 'csrfmiddlewaretoken': token} - app.post('/manage/roles/%s/' % simple_role.pk, params=params) + app.post('/manage/roles/%s/' % simple_role.pk, params=params, headers={'Referer': 'https://testserver/'}) assert role not in simple_role.children() # try to add arbitrary role @@ -1086,7 +1098,11 @@ def test_manager_role_admin_permissions(app, simple_user, admin, simple_role): response = app.get('/manage/roles/%s/parents/' % role.pk) token = str(response.context['csrf_token']) params = {'action': 'add', 'role': admin_role.pk, 'csrfmiddlewaretoken': token} - response = app.post('/manage/roles/%s/parents/' % simple_role.pk, params=params) + response = app.post( + '/manage/roles/%s/parents/' % simple_role.pk, + params=params, + headers={'Referer': 'https://testserver/'}, + ) assert admin_role not in role.parents() # user roles view works @@ -1097,7 +1113,9 @@ def test_manager_role_admin_permissions(app, simple_user, admin, simple_role): token = str(response.context['csrf_token']) params = {'action': 'add', 'role': simple_role.pk, 'csrfmiddlewaretoken': token} - response = app.post('/manage/users/%s/roles/' % admin.pk, params=params) + response = app.post( + '/manage/users/%s/roles/' % admin.pk, params=params, headers={'Referer': 'https://testserver/'} + ) assert simple_role in admin.roles.all() app.get('/manage/roles/add/', status=403) @@ -1306,11 +1324,11 @@ def test_manager_menu_json(app, admin): { 'label': 'Identity management', 'slug': 'identity-management', - 'url': 'http://testserver/manage/', + 'url': 'https://testserver/manage/', 'sub': False, }, - {'label': 'Users', 'slug': 'users', 'url': 'http://testserver/manage/users/', 'sub': True}, - {'label': 'Roles', 'slug': 'roles', 'url': 'http://testserver/manage/roles/', 'sub': True}, + {'label': 'Users', 'slug': 'users', 'url': 'https://testserver/manage/users/', 'sub': True}, + {'label': 'Roles', 'slug': 'roles', 'url': 'https://testserver/manage/roles/', 'sub': True}, ] response = login(app, admin) diff --git a/tests/test_password_reset.py b/tests/test_password_reset.py index e0646616..7002dbb2 100644 --- a/tests/test_password_reset.py +++ b/tests/test_password_reset.py @@ -176,11 +176,11 @@ def test_send_password_reset_email_no_account(app, db, mailoutbox, settings, reg for body in (mail.body, mail.alternatives[0][0]): assert 'no account was found associated with this address' in body if settings.REGISTRATION_OPEN: - assert 'http://testserver/register/' in body + assert 'https://testserver/register/' in body # check next_url was preserved assert 'next=/whatever/' in body else: - assert 'http://testserver/register/' not in body + assert 'https://testserver/register/' not in body def test_send_password_reset_email_disabled_account(app, simple_user, mailoutbox): @@ -209,14 +209,9 @@ def test_honeypot(app, db, settings, mailoutbox): url = reverse('password_reset') response = app.get(url, status=200) - response = app.post( - url, - params={ - 'email': 'testbot@entrouvert.com', - 'csrfmiddlewaretoken': response.context['csrf_token'], - 'robotcheck': 'a', - }, - ) + response.form.set('email', 'testbot@entrouvert.com') + response.form.set('robotcheck', True) + response = response.form.submit() response = response.follow() assert len(mailoutbox) == 0 assert 'Your password reset request has been refused' in response diff --git a/tests/test_registration.py b/tests/test_registration.py index 4167d6dc..203cd635 100644 --- a/tests/test_registration.py +++ b/tests/test_registration.py @@ -812,14 +812,9 @@ def test_honeypot(app, db, settings, mailoutbox): settings.DEFAULT_FROM_EMAIL = 'show only addr ' response = app.get(utils_misc.make_url('registration_register')) - response = app.post( - utils_misc.make_url('registration_register'), - params={ - 'email': 'testbot@entrouvert.com', - 'csrfmiddlewaretoken': response.context['csrf_token'], - 'robotcheck': 'a', - }, - ) + response.form.set('email', 'testbot@entrouvert.com') + response.form.set('robotcheck', True) + response = response.form.submit() response = response.follow() assert len(mailoutbox) == 0 assert 'Your registration request has been refused' in response diff --git a/tests/test_role_manager.py b/tests/test_role_manager.py index d648cd26..e088b2aa 100644 --- a/tests/test_role_manager.py +++ b/tests/test_role_manager.py @@ -622,13 +622,17 @@ def test_role_members_user_role_add_remove(app, superuser, settings, simple_role # simulate click on Jôhn Dôe delete icon token = str(resp.context['csrf_token']) params = {'action': 'remove', 'user_or_role': 'user-%s' % simple_user.pk, 'csrfmiddlewaretoken': token} - resp = app.post('/manage/roles/%s/' % simple_role.pk, params=params).follow() + resp = app.post( + '/manage/roles/%s/' % simple_role.pk, params=params, headers={'Referer': 'https://testserver/'} + ).follow() assert 'Jôhn Dôe' not in resp.text # simulate click on role_ou1 delete icon token = str(resp.context['csrf_token']) params = {'action': 'remove', 'user_or_role': 'role-%s' % role_ou1.pk, 'csrfmiddlewaretoken': token} - resp = app.post('/manage/roles/%s/' % simple_role.pk, params=params).follow() + resp = app.post( + '/manage/roles/%s/' % simple_role.pk, params=params, headers={'Referer': 'https://testserver/'} + ).follow() assert 'role_ou1' not in resp.text # invalid choices are ignored diff --git a/tests/test_user_manager.py b/tests/test_user_manager.py index 06b965c3..942ab4d0 100644 --- a/tests/test_user_manager.py +++ b/tests/test_user_manager.py @@ -1174,7 +1174,9 @@ def test_manager_user_authorizations(app, superuser, simple_user): # cannot click it's JS :/ token = str(resp.context['csrf_token']) params = {'authorization': auth.pk, 'csrfmiddlewaretoken': token} - resp = app.post(user_authorizations_url, params=params, status=302) + resp = app.post( + user_authorizations_url, params=params, status=302, headers={'Referer': 'https://testserver/'} + ) assert OIDCAuthorization.objects.count() == 0 resp = resp.follow() assert resp.html.find('td').text == 'This user has not granted profile data access to any service yet.' -- 2.37.2