tests: add more coverage for tests of next_url checking (#21769)

This commit is contained in:
Benjamin Dauvergne 2018-02-21 10:27:17 +01:00
parent 09dab1b45d
commit 8ae64236cf
4 changed files with 92 additions and 8 deletions

View File

@ -2,6 +2,7 @@
import pytest
import mock
import urlparse
import django_webtest
@ -282,3 +283,50 @@ def user_with_auto_admin_role(auto_admin_role, ou1):
email='user.with.auto.admin.role@example.net', ou=ou1)
user.roles.add(auto_admin_role)
return user
# fixtures to check proper validation of redirect_url
@pytest.fixture
def saml_external_redirect(db):
from authentic2.saml.models import LibertyProvider
next_url = 'https://saml.example.com/whatever/'
LibertyProvider.objects.create(
entity_id='https://saml.example.com/',
protocol_conformance=3,
metadata=utils.saml_sp_metadata('https://example.com'))
return next_url, True
@pytest.fixture
def invalid_external_redirect():
return 'https://invalid.example.com/whatever/', False
@pytest.fixture
def whitelist_external_redirect(settings):
settings.A2_REDIRECT_WHITELIST = ['https://whitelist.example.com/']
return 'https://whitelist.example.com/whatever/', True
@pytest.fixture(params=['saml', 'invalid', 'whitelist'])
def external_redirect(request, saml_external_redirect,
invalid_external_redirect, whitelist_external_redirect):
return locals()[request.param + '_external_redirect']
@pytest.fixture
def external_redirect_next_url(external_redirect):
return external_redirect[0]
@pytest.fixture
def assert_external_redirect(external_redirect):
next_url, valid = external_redirect
if valid:
def check_location(response, default_return):
assert response['Location'] == next_url
else:
def check_location(response, default_return):
assert response['Location'] == urlparse.urljoin('http://testserver/', default_return)
return check_location

View File

@ -10,16 +10,16 @@ from authentic2 import utils, models
from utils import can_resolve_dns, get_link_from_mail
def test_registration(app, db, settings, mailoutbox):
def test_registration(app, db, settings, mailoutbox, external_redirect):
next_url, good_next_url = external_redirect
settings.LANGUAGE_CODE = 'en-us'
settings.A2_VALIDATE_EMAIL_DOMAIN = can_resolve_dns()
settings.A2_REDIRECT_WHITELIST = ['http://relying-party.org/']
# disable existing attributes
models.Attribute.objects.update(disabled=True)
User = get_user_model()
next_url = 'http://relying-party.org/'
url = utils.make_url('registration_register', params={REDIRECT_FIELD_NAME: next_url})
response = app.get(url)
response.form.set('email', 'testbot@entrouvert.com')
@ -44,8 +44,13 @@ def test_registration(app, db, settings, mailoutbox):
response.form.set('password1', 'T0==toto')
response.form.set('password2', 'T0==toto')
response = response.form.submit()
assert 'You have just created an account.' in response.content
assert next_url in response.content
if good_next_url:
assert 'You have just created an account.' in response.content
assert next_url in response.content
else:
assert response['Location'] == 'http://testserver/'
response = response.follow()
assert 'You have just created an account.' in response.content
assert User.objects.count() == 1
assert len(mailoutbox) == 2
assert 'was successful' in mailoutbox[1].body

View File

@ -15,9 +15,15 @@ def test_good_next_url(rf, settings):
assert not good_next_url(request, 'https://google.com/')
assert not good_next_url(request, '')
assert not good_next_url(request, None)
settings.A2_REDIRECT_WHITELIST = ['https://google.com', '//.example.com/']
assert good_next_url(request, 'https://google.com/')
assert good_next_url(request, 'https://www.example.com/')
def test_good_next_url_backends(rf, external_redirect):
next_url, valid = external_redirect
request = rf.get('/', HTTP_HOST='example.net', **{'wsgi.url_scheme': 'https'})
if valid:
assert good_next_url(request, next_url)
else:
assert not good_next_url(request, next_url)
def test_same_origin():

View File

@ -151,3 +151,28 @@ def get_link_from_mail(mail):
assert links, 'there is not link in this mail'
assert len(links) == 1, 'there are more than one link in this mail'
return links[0]
def saml_sp_metadata(base_url):
return '''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<EntityDescriptor
entityID="{base_url}/"
xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
<SPSSODescriptor
AuthnRequestsSigned="true"
WantAssertionsSigned="true"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<SingleLogoutService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://files.entrouvert.org/mellon/logout" />
<AssertionConsumerService
index="0"
isDefault="true"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="{base_url}/sso/POST" />
<AssertionConsumerService
index="1"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
Location="{base_url}/mellon/artifactResponse" />
</SPSSODescriptor>
</EntityDescriptor>'''.format(base_url=base_url)