From ab08abcaf97f183bd495c26a63920632a7e7a943 Mon Sep 17 00:00:00 2001 From: Matt Wright Date: Fri, 27 Apr 2012 13:37:50 -0400 Subject: [PATCH] Fix #4 --- example/templates/login.html | 1 + flask_security/__init__.py | 9 +++-- setup.py | 4 +- tests/functional_tests.py | 73 +++++++++++++++++++----------------- 4 files changed, 48 insertions(+), 39 deletions(-) diff --git a/example/templates/login.html b/example/templates/login.html index 57672ca..d368e37 100644 --- a/example/templates/login.html +++ b/example/templates/login.html @@ -5,6 +5,7 @@ {{ form.username.label }} {{ form.username }}
{{ form.password.label }} {{ form.password }}
{{ form.remember.label }} {{ form.remember }}
+ {{ form.next }} {{ form.submit }}

{{ content }}

diff --git a/flask_security/__init__.py b/flask_security/__init__.py index 49a98bb..4cb1a62 100644 --- a/flask_security/__init__.py +++ b/flask_security/__init__.py @@ -20,7 +20,8 @@ from flask import (current_app, Blueprint, flash, redirect, request, from flask.ext.login import (AnonymousUser as AnonymousUserBase, UserMixin as BaseUserMixin, LoginManager, login_required, login_user, - logout_user, current_user, user_logged_in, user_logged_out) + logout_user, current_user, user_logged_in, user_logged_out, + login_url) from flask.ext.principal import (Identity, Principal, RoleNeed, UserNeed, Permission, AnonymousIdentity, identity_changed, identity_loaded) @@ -147,7 +148,8 @@ def roles_required(*args): @wraps(fn) def decorated_view(*args, **kwargs): if not current_user.is_authenticated(): - return redirect(current_app.config[LOGIN_VIEW_KEY]) + return redirect( + login_url(current_app.config[LOGIN_VIEW_KEY], request.url)) if perm.can(): return fn(*args, **kwargs) @@ -181,7 +183,8 @@ def roles_accepted(*args): @wraps(fn) def decorated_view(*args, **kwargs): if not current_user.is_authenticated(): - return redirect(current_app.config[LOGIN_VIEW_KEY]) + return redirect( + login_url(current_app.config[LOGIN_VIEW_KEY], request.url)) for perm in perms: if perm.can(): diff --git a/setup.py b/setup.py index cfdf948..6e1c7c7 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ Flask-Security -------------- -Flask-Security is a Flask extension that aims to add quick and simple security +Flask-Security is a Flask extension that aims to add quick and simple security via Flask-Login, Flask-Principal, Flask-WTF, and passlib. Links @@ -17,7 +17,7 @@ from setuptools import setup setup( name='Flask-Security', - version='1.2.1', + version='1.2.2-dev', url='https://github.com/mattupstate/flask-security', license='MIT', author='Matthew Wright', diff --git a/tests/functional_tests.py b/tests/functional_tests.py index 04a6271..0451e7d 100644 --- a/tests/functional_tests.py +++ b/tests/functional_tests.py @@ -1,108 +1,113 @@ import unittest from example import app + class SecurityTest(unittest.TestCase): - + AUTH_CONFIG = None - + def setUp(self): super(SecurityTest, self).setUp() - + self.app = self._create_app(self.AUTH_CONFIG or None) self.app.debug = False self.app.config['TESTING'] = True - + self.client = self.app.test_client() - + def _create_app(self, auth_config): return app.create_sqlalchemy_app(auth_config) - + def _get(self, route, content_type=None, follow_redirects=None): return self.client.get(route, follow_redirects=follow_redirects, content_type=content_type or 'text/html') - + def _post(self, route, data=None, content_type=None, follow_redirects=True): - return self.client.post(route, data=data, + return self.client.post(route, data=data, follow_redirects=follow_redirects, content_type=content_type or 'text/html') - - + def authenticate(self, username, password, endpoint=None): data = dict(username=username, password=password) - return self._post(endpoint or '/auth', data=data, + return self._post(endpoint or '/auth', data=data, content_type='application/x-www-form-urlencoded') - + def logout(self, endpoint=None): return self._get(endpoint or '/logout', follow_redirects=True) + class DefaultSecurityTests(SecurityTest): - + def test_login_view(self): r = self._get('/login') assert 'Login Page' in r.data - + def test_authenticate(self): r = self.authenticate("matt", "password") assert 'Home Page' in r.data - + def test_unprovided_username(self): r = self.authenticate("", "password") assert "Username not provided" in r.data - + def test_unprovided_password(self): r = self.authenticate("matt", "") assert "Password not provided" in r.data - + def test_invalid_user(self): r = self.authenticate("bogus", "password") assert "Specified user does not exist" in r.data - + def test_bad_password(self): r = self.authenticate("matt", "bogus") assert "Password does not match" in r.data - + def test_inactive_user(self): r = self.authenticate("tiya", "password") assert "Inactive user" in r.data - + def test_logout(self): self.authenticate("matt", "password") r = self.logout() assert 'Home Page' in r.data - + def test_unauthorized_access(self): r = self._get('/profile', follow_redirects=True) assert 'Please log in to access this page' in r.data - + def test_authorized_access(self): self.authenticate("matt", "password") r = self._get("/profile") assert 'profile' in r.data - + def test_valid_admin_role(self): self.authenticate("matt", "password") r = self._get("/admin") assert 'Admin Page' in r.data - + def test_invalid_admin_role(self): self.authenticate("joe", "password") r = self._get("/admin", follow_redirects=True) assert 'Home Page' in r.data - + def test_roles_accepted(self): for user in ("matt", "joe"): self.authenticate(user, "password") r = self._get("/admin_or_editor") self.assertIn('Admin or Editor Page', r.data) self.logout() - + self.authenticate("jill", "password") r = self._get("/admin_or_editor", follow_redirects=True) self.assertIn('Home Page', r.data) + def test_unauthenticated_role_required(self): + r = self._get('/admin', follow_redirects=True) + self.assertIn('