From 0154cce46c43f54d98a54f29ed95ad38558c42a2 Mon Sep 17 00:00:00 2001 From: Matt Wright Date: Thu, 11 Oct 2012 16:58:53 -0400 Subject: [PATCH] Only give out auth token on the login endpoint --- flask_security/views.py | 28 +++++++++++++++++----------- tests/configured_tests.py | 30 +++++++++++++++++++++++++----- tests/functional_tests.py | 18 ++++++++++++++---- 3 files changed, 56 insertions(+), 20 deletions(-) diff --git a/flask_security/views.py b/flask_security/views.py index 73f8071..89bb0dc 100644 --- a/flask_security/views.py +++ b/flask_security/views.py @@ -35,7 +35,7 @@ _security = LocalProxy(lambda: current_app.extensions['security']) _datastore = LocalProxy(lambda: _security.datastore) -def _render_json(form, include_auth_token=True): +def _render_json(form, include_auth_token=False): has_errors = len(form.errors) > 0 if has_errors: @@ -77,7 +77,7 @@ def login(): return redirect(get_post_login_redirect()) if request.json: - return _render_json(form) + return _render_json(form, True) return render_template('security/login_user.html', login_user_form=form, @@ -140,9 +140,11 @@ def send_login(): if form.validate_on_submit(): send_login_instructions(form.user) - if request.json: - return _render_json(form, False) - do_flash(*get_message('LOGIN_EMAIL_SENT', email=form.user.email)) + if request.json is None: + do_flash(*get_message('LOGIN_EMAIL_SENT', email=form.user.email)) + + if request.json: + return _render_json(form) return render_template('security/send_login.html', send_login_form=form, @@ -181,9 +183,11 @@ def send_confirmation(): if form.validate_on_submit(): send_confirmation_instructions(form.user) - if request.json: - return _render_json(form, False) - do_flash(*get_message('CONFIRMATION_REQUEST', email=form.user.email)) + if request.json is None: + do_flash(*get_message('CONFIRMATION_REQUEST', email=form.user.email)) + + if request.json: + return _render_json(form) return render_template('security/send_confirmation.html', send_confirmation_form=form, @@ -225,9 +229,11 @@ def forgot_password(): if form.validate_on_submit(): send_reset_password_instructions(form.user) - if request.json: - return _render_json(form, False) - do_flash(*get_message('PASSWORD_RESET_REQUEST', email=form.user.email)) + if request.json is None: + do_flash(*get_message('PASSWORD_RESET_REQUEST', email=form.user.email)) + + if request.json: + return _render_json(form) return render_template('security/forgot_password.html', forgot_password_form=form, diff --git a/tests/configured_tests.py b/tests/configured_tests.py index 0ac9d6f..b2e75bc 100644 --- a/tests/configured_tests.py +++ b/tests/configured_tests.py @@ -62,19 +62,18 @@ class ConfiguredSecurityTests(SecurityTest): self.assertIn('Post Register', r.data) def test_register_json(self): - r = self._post('/register', - data='{ "email": "dude@lp.com", "password": "password" }', - content_type='application/json') + data = '{ "email": "dude@lp.com", "password": "password" }' + r = self._post('/register', data=data, content_type='application/json') data = json.loads(r.data) self.assertEquals(data['meta']['code'], 200) - self.assertIn('authentication_token', data['response']['user']) def test_register_existing_email(self): data = dict(email='matt@lp.com', password='password', password_confirm='password') r = self._post('/register', data=data, follow_redirects=True) - self.assertIn('matt@lp.com is already associated with an account', r.data) + msg = 'matt@lp.com is already associated with an account' + self.assertIn(msg, r.data) def test_unauthorized(self): self.authenticate("joe@lp.com", endpoint="/custom_auth") @@ -166,6 +165,11 @@ class ConfirmableTests(SecurityTest): r = self.client.get('/confirm/bogus', follow_redirects=True) self.assertIn('Invalid confirmation token', r.data) + def test_send_confirmation_json(self): + r = self._post('/confirm', data='{"email": "matt@lp.com"}', + content_type='application/json') + self.assertEquals(r.status_code, 200) + def test_send_confirmation_with_invalid_email(self): r = self._post('/confirm', data=dict(email='bogus@bogus.com')) self.assertIn('Specified user does not exist', r.data) @@ -247,6 +251,11 @@ class RecoverableTests(SecurityTest): self.client.post('/reset', data=dict(email='joe@lp.com')) self.assertEqual(len(outbox), 1) + def test_forgot_password_json(self): + r = self.client.post('/reset', data='{"email": "matt@lp.com"}', + content_type="application/json") + self.assertEquals(r.status_code, 200) + def test_forgot_password_invalid_email(self): r = self.client.post('/reset', data=dict(email='larry@lp.com'), @@ -337,6 +346,17 @@ class PasswordlessTests(SecurityTest): follow_redirects=True) self.assertIn(msg, r.data) + def test_request_login_token_with_json_and_valid_email(self): + data = '{"email": "matt@lp.com", "password": "password"}' + r = self.client.post('/login', data=data, content_type='application/json') + self.assertEquals(r.status_code, 200) + self.assertNotIn('error', r.data) + + def test_request_login_token_with_json_and_invalid_email(self): + data = '{"email": "nobody@lp.com", "password": "password"}' + r = self.client.post('/login', data=data, content_type='application/json') + self.assertIn('errors', r.data) + def test_request_login_token_sends_email_and_can_login(self): e = 'matt@lp.com' r, user, token = None, None, None diff --git a/tests/functional_tests.py b/tests/functional_tests.py index fa3bb05..c9fd8da 100644 --- a/tests/functional_tests.py +++ b/tests/functional_tests.py @@ -148,7 +148,8 @@ class DefaultSecurityTests(SecurityTest): }) self.assertIn('

Unauthorized

', r.data) self.assertIn('WWW-Authenticate', r.headers) - self.assertEquals('Basic realm="Login Required"', r.headers['WWW-Authenticate']) + self.assertEquals('Basic realm="Login Required"', + r.headers['WWW-Authenticate']) def test_invalid_http_auth_bad_password(self): r = self._get('/http', headers={ @@ -156,7 +157,8 @@ class DefaultSecurityTests(SecurityTest): }) self.assertIn('

Unauthorized

', r.data) self.assertIn('WWW-Authenticate', r.headers) - self.assertEquals('Basic realm="Login Required"', r.headers['WWW-Authenticate']) + self.assertEquals('Basic realm="Login Required"', + r.headers['WWW-Authenticate']) def test_custom_http_auth_realm(self): r = self._get('/http_custom_realm', headers={ @@ -164,7 +166,8 @@ class DefaultSecurityTests(SecurityTest): }) self.assertIn('

Unauthorized

', r.data) self.assertIn('WWW-Authenticate', r.headers) - self.assertEquals('Basic realm="My Realm"', r.headers['WWW-Authenticate']) + self.assertEquals('Basic realm="My Realm"', + r.headers['WWW-Authenticate']) def test_user_deleted_during_session_reverts_to_anonymous_user(self): self.authenticate() @@ -184,7 +187,14 @@ class DefaultSecurityTests(SecurityTest): self.assertIn('profile', r.data) def test_token_loader_does_not_fail_with_invalid_token(self): - self.client.cookie_jar.set_cookie(Cookie(version=0, name='remember_token', value='None', port=None, port_specified=False, domain='www.example.com', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False)) + c = Cookie(version=0, name='remember_token', value='None', port=None, + port_specified=False, domain='www.example.com', + domain_specified=False, domain_initial_dot=False, path='/', + path_specified=True, secure=False, expires=None, + discard=True, comment=None, comment_url=None, + rest={'HttpOnly': None}, rfc2109=False) + + self.client.cookie_jar.set_cookie(c) r = self._get('/') self.assertNotIn('BadSignature', r.data)