changeset 7701:9c2fc1390291

tests: prepare for adding CSRF protection on login forms CSRF is about avoiding abuse of credentials by doing things in existing sessions. The login form does not have any previous credentials, so there is nothing to abuse and no real need for CSRF protection. But there is still an unauth session, so we *can* have CSRF protection. CSRF protection is currently in LoginRequired (which obviously isn't applied to the login form), but let's prepare for changing that.
author Mads Kiilerich <mads@kiilerich.com>
date Fri, 04 Jan 2019 03:42:17 +0100
parents ffdcf0dfe0e4
children 797883404f17
files kallithea/tests/base.py kallithea/tests/functional/test_login.py
diffstat 2 files changed, 52 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/tests/base.py	Wed Jan 23 00:56:18 2019 +0100
+++ b/kallithea/tests/base.py	Fri Jan 04 03:42:17 2019 +0100
@@ -154,7 +154,8 @@
         self._logged_username = username
         response = self.app.post(url(controller='login', action='index'),
                                  {'username': username,
-                                  'password': password})
+                                  'password': password,
+                                  '_authentication_token': self.authentication_token()})
 
         if 'Invalid username or password' in response.body:
             pytest.fail('could not login using %s %s' % (username, password))
--- a/kallithea/tests/functional/test_login.py	Wed Jan 23 00:56:18 2019 +0100
+++ b/kallithea/tests/functional/test_login.py	Fri Jan 04 03:42:17 2019 +0100
@@ -31,7 +31,8 @@
     def test_login_admin_ok(self):
         response = self.app.post(url(controller='login', action='index'),
                                  {'username': TEST_USER_ADMIN_LOGIN,
-                                  'password': TEST_USER_ADMIN_PASS})
+                                  'password': TEST_USER_ADMIN_PASS,
+                                  '_authentication_token': self.authentication_token()})
         assert response.status == '302 Found'
         self.assert_authenticated_user(response, TEST_USER_ADMIN_LOGIN)
 
@@ -41,7 +42,8 @@
     def test_login_regular_ok(self):
         response = self.app.post(url(controller='login', action='index'),
                                  {'username': TEST_USER_REGULAR_LOGIN,
-                                  'password': TEST_USER_REGULAR_PASS})
+                                  'password': TEST_USER_REGULAR_PASS,
+                                  '_authentication_token': self.authentication_token()})
 
         assert response.status == '302 Found'
         self.assert_authenticated_user(response, TEST_USER_REGULAR_LOGIN)
@@ -52,7 +54,8 @@
     def test_login_regular_email_ok(self):
         response = self.app.post(url(controller='login', action='index'),
                                  {'username': TEST_USER_REGULAR_EMAIL,
-                                  'password': TEST_USER_REGULAR_PASS})
+                                  'password': TEST_USER_REGULAR_PASS,
+                                  '_authentication_token': self.authentication_token()})
 
         assert response.status == '302 Found'
         self.assert_authenticated_user(response, TEST_USER_REGULAR_LOGIN)
@@ -65,7 +68,8 @@
         response = self.app.post(url(controller='login', action='index',
                                      came_from=test_came_from),
                                  {'username': TEST_USER_ADMIN_LOGIN,
-                                  'password': TEST_USER_ADMIN_PASS})
+                                  'password': TEST_USER_ADMIN_PASS,
+                                  '_authentication_token': self.authentication_token()})
         assert response.status == '302 Found'
         response = response.follow()
 
@@ -76,7 +80,8 @@
         response = self.app.post(url(controller='login', action='index'),
                                  {'username': TEST_USER_REGULAR_LOGIN,
                                   'password': TEST_USER_REGULAR_PASS,
-                                  'remember': False})
+                                  'remember': False,
+                                  '_authentication_token': self.authentication_token()})
 
         assert 'Set-Cookie' in response.headers
         for cookie in response.headers.getall('Set-Cookie'):
@@ -86,7 +91,8 @@
         response = self.app.post(url(controller='login', action='index'),
                                  {'username': TEST_USER_REGULAR_LOGIN,
                                   'password': TEST_USER_REGULAR_PASS,
-                                  'remember': True})
+                                  'remember': True,
+                                  '_authentication_token': self.authentication_token()})
 
         assert 'Set-Cookie' in response.headers
         for cookie in response.headers.getall('Set-Cookie'):
@@ -95,7 +101,8 @@
     def test_logout(self):
         response = self.app.post(url(controller='login', action='index'),
                                  {'username': TEST_USER_REGULAR_LOGIN,
-                                  'password': TEST_USER_REGULAR_PASS})
+                                  'password': TEST_USER_REGULAR_PASS,
+                                  '_authentication_token': self.authentication_token()})
 
         # Verify that a login session has been established.
         response = self.app.get(url(controller='login', action='index'))
@@ -123,13 +130,15 @@
         response = self.app.post(url(controller='login', action='index',
                                      came_from=url_came_from),
                                  {'username': TEST_USER_ADMIN_LOGIN,
-                                  'password': TEST_USER_ADMIN_PASS},
+                                  'password': TEST_USER_ADMIN_PASS,
+                                  '_authentication_token': self.authentication_token()},
                                  status=400)
 
     def test_login_short_password(self):
         response = self.app.post(url(controller='login', action='index'),
                                  {'username': TEST_USER_ADMIN_LOGIN,
-                                  'password': 'as'})
+                                  'password': 'as',
+                                  '_authentication_token': self.authentication_token()})
         assert response.status == '200 OK'
 
         response.mustcontain('Enter 3 characters or more')
@@ -137,14 +146,16 @@
     def test_login_wrong_username_password(self):
         response = self.app.post(url(controller='login', action='index'),
                                  {'username': 'error',
-                                  'password': 'test12'})
+                                  'password': 'test12',
+                                  '_authentication_token': self.authentication_token()})
 
         response.mustcontain('Invalid username or password')
 
     def test_login_non_ascii(self):
         response = self.app.post(url(controller='login', action='index'),
                                  {'username': TEST_USER_REGULAR_LOGIN,
-                                  'password': 'blåbærgrød'})
+                                  'password': 'blåbærgrød',
+                                  '_authentication_token': self.authentication_token()})
 
         response.mustcontain('>Invalid username or password<')
 
@@ -187,7 +198,8 @@
         response = self.app.post(url(controller='login', action='index',
                                      came_from=url('/_admin/users', **args)),
                                  {'username': TEST_USER_ADMIN_LOGIN,
-                                  'password': TEST_USER_ADMIN_PASS})
+                                  'password': TEST_USER_ADMIN_PASS,
+                                  '_authentication_token': self.authentication_token()})
         assert response.status == '302 Found'
         for encoded in args_encoded:
             assert encoded in response.location
@@ -201,7 +213,8 @@
         response = self.app.post(url(controller='login', action='index',
                                      came_from=url('/_admin/users', **args)),
                                  {'username': 'error',
-                                  'password': 'test12'})
+                                  'password': 'test12',
+                                  '_authentication_token': self.authentication_token()})
 
         response.mustcontain('Invalid username or password')
         came_from = urlparse.parse_qs(urlparse.urlparse(response.form.action).query)['came_from'][0]
@@ -223,7 +236,8 @@
                                              'password_confirmation': 'test12',
                                              'email': 'goodmail@example.com',
                                              'firstname': 'test',
-                                             'lastname': 'test'})
+                                             'lastname': 'test',
+                                             '_authentication_token': self.authentication_token()})
 
         with test_context(self.app):
             msg = validators.ValidUsername()._messages['username_exists']
@@ -237,7 +251,8 @@
                                              'password_confirmation': 'test12',
                                              'email': TEST_USER_ADMIN_EMAIL,
                                              'firstname': 'test',
-                                             'lastname': 'test'})
+                                             'lastname': 'test',
+                                             '_authentication_token': self.authentication_token()})
 
         with test_context(self.app):
             msg = validators.UniqSystemEmail()()._messages['email_taken']
@@ -250,7 +265,8 @@
                                              'password_confirmation': 'test12',
                                              'email': TEST_USER_ADMIN_EMAIL.title(),
                                              'firstname': 'test',
-                                             'lastname': 'test'})
+                                             'lastname': 'test',
+                                             '_authentication_token': self.authentication_token()})
         with test_context(self.app):
             msg = validators.UniqSystemEmail()()._messages['email_taken']
         response.mustcontain(msg)
@@ -262,7 +278,8 @@
                                              'password_confirmation': 'test',
                                              'email': 'goodmailm',
                                              'firstname': 'test',
-                                             'lastname': 'test'})
+                                             'lastname': 'test',
+                                             '_authentication_token': self.authentication_token()})
         assert response.status == '200 OK'
         response.mustcontain('An email address must contain a single @')
         response.mustcontain('Enter a value 6 characters long or more')
@@ -274,7 +291,8 @@
                                              'password_confirmation': 'test12',
                                              'email': 'goodmailm',
                                              'firstname': 'test',
-                                             'lastname': 'test'})
+                                             'lastname': 'test',
+                                             '_authentication_token': self.authentication_token()})
 
         response.mustcontain('An email address must contain a single @')
         response.mustcontain('Username may only contain '
@@ -290,7 +308,8 @@
                                              'password_confirmation': 'test12',
                                              'email': 'goodmailm',
                                              'firstname': 'test',
-                                             'lastname': 'test'})
+                                             'lastname': 'test',
+                                             '_authentication_token': self.authentication_token()})
 
         response.mustcontain('An email address must contain a single @')
         with test_context(self.app):
@@ -305,7 +324,8 @@
                                          'password_confirmation': 'ąćźżąśśśś',
                                          'email': 'goodmailm@test.plx',
                                          'firstname': 'test',
-                                         'lastname': 'test'})
+                                         'lastname': 'test',
+                                         '_authentication_token': self.authentication_token()})
 
         with test_context(self.app):
             msg = validators.ValidPassword()._messages['invalid_password']
@@ -318,7 +338,8 @@
                                              'password_confirmation': 'qwe123',
                                              'email': 'goodmailm@test.plxa',
                                              'firstname': 'test',
-                                             'lastname': 'test'})
+                                             'lastname': 'test',
+                                             '_authentication_token': self.authentication_token()})
         with test_context(self.app):
             msg = validators.ValidPasswordsMatch('password', 'password_confirmation')._messages['password_mismatch']
         response.mustcontain(msg)
@@ -337,7 +358,8 @@
                                              'email': email,
                                              'firstname': name,
                                              'lastname': lastname,
-                                             'admin': True})  # This should be overridden
+                                             'admin': True,
+                                             '_authentication_token': self.authentication_token()})  # This should be overridden
         assert response.status == '302 Found'
         self.checkSessionFlash(response, 'You have successfully registered with Kallithea')
 
@@ -358,8 +380,8 @@
         bad_email = 'username%wrongmail.org'
         response = self.app.post(
                         url(controller='login', action='password_reset'),
-                            {'email': bad_email, }
-        )
+                            {'email': bad_email,
+                             '_authentication_token': self.authentication_token()})
 
         response.mustcontain('An email address must contain a single @')
 
@@ -387,7 +409,8 @@
 
         response = self.app.post(url(controller='login',
                                      action='password_reset'),
-                                 {'email': email, })
+                                 {'email': email,
+                                  '_authentication_token': self.authentication_token()})
 
         self.checkSessionFlash(response, 'A password reset confirmation code has been sent')
 
@@ -404,6 +427,7 @@
                                   'password': "p@ssw0rd",
                                   'password_confirm': "p@ssw0rd",
                                   'token': token,
+                                  '_authentication_token': self.authentication_token(),
                                  })
         assert response.status == '200 OK'
         response.mustcontain('Invalid password reset token')
@@ -431,6 +455,7 @@
                                   'password': "p@ssw0rd",
                                   'password_confirm': "p@ssw0rd",
                                   'token': token,
+                                  '_authentication_token': self.authentication_token(),
                                  })
         assert response.status == '302 Found'
         self.checkSessionFlash(response, 'Successfully updated password')