diff --git a/ckan/config/who.ini b/ckan/config/who.ini index 01fc7c07bc8..293569878dd 100644 --- a/ckan/config/who.ini +++ b/ckan/config/who.ini @@ -49,7 +49,8 @@ plugins = auth_tkt [authenticators] -plugins = +plugins = + auth_tkt ckan.lib.authenticator:OpenIDAuthenticator ckan.lib.authenticator:UsernamePasswordAuthenticator diff --git a/ckan/new_tests/lib/test_base.py b/ckan/new_tests/lib/test_base.py index 04656093928..e728c38c513 100644 --- a/ckan/new_tests/lib/test_base.py +++ b/ckan/new_tests/lib/test_base.py @@ -1,6 +1,89 @@ from nose import tools as nose_tools -from ckan.new_tests import helpers +import ckan.new_tests.factories as factories +import ckan.new_tests.helpers as helpers + + +class TestLoginView(helpers.FunctionalTestBase): + + def _maybe_follow(self, response, **kw): + """ + Follow all redirects. If this response is not a redirect, do nothing. + Returns another response object. + + (backported from WebTest 2.0.1) + """ + remaining_redirects = 100 # infinite loops protection + + while 300 <= response.status_int < 400 and remaining_redirects: + response = response.follow(**kw) + remaining_redirects -= 1 + + assert remaining_redirects > 0, "redirects chain looks infinite" + return response + + def test_registered_user_login(self): + ''' + Registered user can submit valid login details at /user/login and + be returned to appropriate place. + ''' + app = helpers._get_test_app() + + # make a user + user = factories.User() + + # get the form + response = app.get('/user/login') + # ...it's the second one + login_form = response.forms[1] + + # fill it in + login_form['login'] = user['name'] + login_form['password'] = 'pass' + + # submit it + submit_response = login_form.submit() + # let's go to the last redirect in the chain + final_response = self._maybe_follow(submit_response) + + # the response is the user dashboard, right? + final_response.mustcontain('Dashboard', + '{0}' + .format(user['fullname'])) + # and we're definitely not back on the login page. + final_response.mustcontain(no='

Login

') + + def test_registered_user_login_bad_password(self): + ''' + Registered user is redirected to appropriate place if they submit + invalid login details at /user/login. + ''' + app = helpers._get_test_app() + + # make a user + user = factories.User() + + # get the form + response = app.get('/user/login') + # ...it's the second one + login_form = response.forms[1] + + # fill it in + login_form['login'] = user['name'] + login_form['password'] = 'badpass' + + # submit it + submit_response = login_form.submit() + # let's go to the last redirect in the chain + final_response = self._maybe_follow(submit_response) + + # the response is the login page again + final_response.mustcontain('

Login

', + 'Login failed. Bad username or password.') + # and we're definitely not on the dashboard. + final_response.mustcontain(no='Dashboard'), + final_response.mustcontain(no='{0}' + .format(user['fullname'])) class TestCORS(helpers.FunctionalTestBase): diff --git a/requirements.in b/requirements.in index 496ee97266e..970cddb3b41 100644 --- a/requirements.in +++ b/requirements.in @@ -17,7 +17,7 @@ python-dateutil>=1.5.0,<2.0.0 pyutilib.component.core==4.5.3 repoze.who-friendlyform==1.0.8 repoze.who.plugins.openid==0.5.3 -repoze.who==1.0.19 +repoze.who==2.0 requests==2.3.0 Routes==1.13 solrpy==0.9.5 diff --git a/requirements.txt b/requirements.txt index a8aa7d6079a..b87a30ac995 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,7 +31,7 @@ python-dateutil==1.5 python-openid==2.2.5 pyutilib.component.core==4.5.3 repoze.lru==0.6 -repoze.who==1.0.19 +repoze.who==2.0 repoze.who-friendlyform==1.0.8 repoze.who.plugins.openid==0.5.3 requests==2.3.0