launch tests with Django 1.11 (fixes #27095)

This commit is contained in:
Benjamin Dauvergne 2018-10-08 12:07:04 +02:00
parent 7b2f4f2f9a
commit 460def09da
4 changed files with 38 additions and 13 deletions

8
Jenkinsfile vendored
View File

@ -25,9 +25,13 @@ pipeline {
utils.mail_notify(currentBuild, env, 'admin+jenkins-authentic2-auth-fc@entrouvert.com') utils.mail_notify(currentBuild, env, 'admin+jenkins-authentic2-auth-fc@entrouvert.com')
utils.publish_coverage('coverage-*.xml') utils.publish_coverage('coverage-*.xml')
utils.publish_coverage_native( utils.publish_coverage_native(
'index.html', 'htmlcov-coverage-dj18-pg', 'Coverage a2-auth-fc PG') 'index.html', 'htmlcov-coverage-dj18-pg', 'Coverage a2-auth-fc dj18 PG')
utils.publish_coverage_native( utils.publish_coverage_native(
'index.html', 'htmlcov-coverage-dj18-sqlite', 'Coverage a2-auth-fc SQLITE') 'index.html', 'htmlcov-coverage-dj18-sqlite', 'Coverage a2-auth-fc dj18 SQLITE')
utils.publish_coverage_native(
'index.html', 'htmlcov-coverage-dj111-pg', 'Coverage a2-auth-fc dj111 PG')
utils.publish_coverage_native(
'index.html', 'htmlcov-coverage-dj111-sqlite', 'Coverage a2-auth-fc dj111 SQLITE')
utils.publish_pylint('pylint.out') utils.publish_pylint('pylint.out')
} }
junit 'junit-*.xml' junit 'junit-*.xml'

View File

@ -8,6 +8,7 @@ import requests
from requests_oauthlib import OAuth2Session from requests_oauthlib import OAuth2Session
import django
from django.views.generic import View, FormView from django.views.generic import View, FormView
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from django.http import HttpResponseRedirect, Http404 from django.http import HttpResponseRedirect, Http404
@ -22,6 +23,10 @@ from django.core.cache import InvalidCacheBackendError, caches
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.forms import Form from django.forms import Form
try:
from django.contrib.auth.views import update_session_auth_hash
except ImportError:
update_session_auth_hash = None
from authentic2 import app_settings as a2_app_settings from authentic2 import app_settings as a2_app_settings
from authentic2 import utils as a2_utils, hooks, constants from authentic2 import utils as a2_utils, hooks, constants
@ -150,7 +155,11 @@ class FcOAuthSessionViewMixin(LoggerMixin):
else: else:
redirect_to = request.GET.get(self.redirect_field_name, '') redirect_to = request.GET.get(self.redirect_field_name, '')
if not is_safe_url(url=redirect_to, host=request.get_host()): if django.VERSION < (1, 11):
safe = is_safe_url(url=redirect_to, host=request.get_host())
else:
safe = is_safe_url(url=redirect_to, allowed_hosts=[request.get_host()])
if not safe:
redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL) redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
return redirect_to return redirect_to
@ -523,6 +532,7 @@ class UnlinkView(LoggerMixin, FormView):
def form_valid(self, form): def form_valid(self, form):
if self.must_set_password(): if self.must_set_password():
form.save() form.save()
update_session_auth_hash(self.request, self.request.user)
self.logger.info(u'user %s has set a password', self.request.user) self.logger.info(u'user %s has set a password', self.request.user)
links = models.FcAccount.objects.filter(user=self.request.user) links = models.FcAccount.objects.filter(user=self.request.user)
for link in links: for link in links:

View File

@ -24,6 +24,15 @@ from authentic2_auth_fc.utils import requests_retry_session
User = get_user_model() User = get_user_model()
def path(url):
return urlparse.urlparse(url).path
def path_and_query(url):
parsed = urlparse.urlparse(url)
return parsed.path + '?' + parsed.query
def get_links_from_mail(mail): def get_links_from_mail(mail):
'''Extract links from mail sent by Django''' '''Extract links from mail sent by Django'''
return re.findall('https?://[^ \n]*', mail.body) return re.findall('https?://[^ \n]*', mail.body)
@ -113,7 +122,7 @@ def test_login_simple(app, fc_settings, caplog, hooks, exp):
else: else:
assert User.objects.count() == 1 assert User.objects.count() == 1
if User.objects.count(): if User.objects.count():
assert response['Location'] == 'http://testserver/idp/' assert path(response['Location']) == '/idp/'
assert hooks.event[1]['kwargs']['name'] == 'login' assert hooks.event[1]['kwargs']['name'] == 'login'
assert hooks.event[1]['kwargs']['service'] == 'portail' assert hooks.event[1]['kwargs']['service'] == 'portail'
# we must be connected # we must be connected
@ -130,7 +139,7 @@ def test_login_simple(app, fc_settings, caplog, hooks, exp):
state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0] state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0]
assert app.session['fc_states'][state]['next'] == '/accounts/' assert app.session['fc_states'][state]['next'] == '/accounts/'
response = app.get(reverse('fc-logout') + '?state=' + state) response = app.get(reverse('fc-logout') + '?state=' + state)
assert response['Location'] == 'http://testserver/accounts/' assert path(response['Location']) == '/accounts/'
def test_login_email_is_unique(app, fc_settings, caplog): def test_login_email_is_unique(app, fc_settings, caplog):
@ -327,7 +336,7 @@ def test_registration1(app, fc_settings, caplog, hooks):
with httmock.HTTMock(access_token_response, user_info_response): with httmock.HTTMock(access_token_response, user_info_response):
response = app.get(callback + '&code=zzz&state=%s' % state, status=302) response = app.get(callback + '&code=zzz&state=%s' % state, status=302)
assert User.objects.count() == 0 assert User.objects.count() == 0
assert response['Location'].startswith('http://testserver/login/') assert path(response['Location']) == '/login/'
response = response.follow() response = response.follow()
response = response.click('Create your account with FranceConnect') response = response.click('Create your account with FranceConnect')
location = response['Location'] location = response['Location']
@ -336,7 +345,7 @@ def test_registration1(app, fc_settings, caplog, hooks):
assert hooks.calls['event'][0]['kwargs']['service'] == 'portail' assert hooks.calls['event'][0]['kwargs']['service'] == 'portail'
# we must be connected # we must be connected
assert app.session['_auth_user_id'] assert app.session['_auth_user_id']
assert response['Location'].startswith(callback) assert path_and_query(response['Location']) == path_and_query(callback)
response = response.follow() response = response.follow()
location = response['Location'] location = response['Location']
state = check_authorization_url(location) state = check_authorization_url(location)
@ -354,7 +363,7 @@ def test_registration1(app, fc_settings, caplog, hooks):
state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0] state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0]
assert app.session['fc_states'][state]['next'] == '/accounts/' assert app.session['fc_states'][state]['next'] == '/accounts/'
response = app.get(reverse('fc-logout') + '?state=' + state) response = app.get(reverse('fc-logout') + '?state=' + state)
assert response['Location'] == 'http://testserver/accounts/' assert path(response['Location']) == '/accounts/'
def test_registration2(app, fc_settings, caplog, hooks): def test_registration2(app, fc_settings, caplog, hooks):
@ -406,7 +415,7 @@ def test_registration2(app, fc_settings, caplog, hooks):
with httmock.HTTMock(access_token_response, user_info_response): with httmock.HTTMock(access_token_response, user_info_response):
response = app.get(callback + '&code=zzz&state=%s' % state, status=302) response = app.get(callback + '&code=zzz&state=%s' % state, status=302)
assert User.objects.count() == 0 assert User.objects.count() == 0
assert response['Location'].startswith('http://testserver/accounts/fc/register/') assert path(response['Location']) == '/accounts/fc/register/'
response = response.follow() response = response.follow()
location = response['Location'] location = response['Location']
location.startswith('http://testserver/accounts/activate/') location.startswith('http://testserver/accounts/activate/')
@ -419,7 +428,7 @@ def test_registration2(app, fc_settings, caplog, hooks):
callback = callback.replace('&registration=', '') callback = callback.replace('&registration=', '')
callback = callback.replace('?registration=', '?') callback = callback.replace('?registration=', '?')
callback = callback.replace('?&', '?') callback = callback.replace('?&', '?')
assert response['Location'].startswith(callback) assert path_and_query(response['Location']) == path_and_query(callback)
response = response.follow() response = response.follow()
location = response['Location'] location = response['Location']
state = check_authorization_url(location) state = check_authorization_url(location)
@ -437,4 +446,4 @@ def test_registration2(app, fc_settings, caplog, hooks):
state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0] state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0]
assert app.session['fc_states'][state]['next'] == '/accounts/' assert app.session['fc_states'][state]['next'] == '/accounts/'
response = app.get(reverse('fc-logout') + '?state=' + state) response = app.get(reverse('fc-logout') + '?state=' + state)
assert response['Location'] == 'http://testserver/accounts/' assert path(response['Location']) == '/accounts/'

View File

@ -5,7 +5,7 @@
[tox] [tox]
toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/authentic2-auth-fc/ toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/authentic2-auth-fc/
envlist = coverage-dj18-{pg,sqlite} envlist = coverage-{dj18,dj111}-{pg,sqlite}
[testenv] [testenv]
whitelist_externals = whitelist_externals =
@ -24,6 +24,8 @@ usedevelop =
deps = deps =
dj18: django>1.8,<1.9 dj18: django>1.8,<1.9
dj18: django-tables2<1.1 dj18: django-tables2<1.1
dj111: django<2.0
dj111: django-tables<2.0
pg: psycopg2 pg: psycopg2
coverage coverage
pytest-cov pytest-cov
@ -34,7 +36,7 @@ deps =
cssselect cssselect
pylint pylint
pylint-django pylint-django
django-webtest django-webtest<1.9.3
WebTest WebTest
pyquery pyquery
httmock httmock