This commit is contained in:
Matt Wright
2012-04-27 13:37:50 -04:00
parent 0acf4bca0d
commit ab08abcaf9
4 changed files with 48 additions and 39 deletions
+1
View File
@@ -5,6 +5,7 @@
{{ form.username.label }} {{ form.username }}<br/>
{{ form.password.label }} {{ form.password }}<br/>
{{ form.remember.label }} {{ form.remember }}<br/>
{{ form.next }}
{{ form.submit }}
</form>
<p>{{ content }}</p>
+6 -3
View File
@@ -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():
+2 -2
View File
@@ -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',
+39 -34
View File
@@ -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('<input id="next"', r.data)
class ConfiguredSecurityTests(SecurityTest):
class ConfiguredSecurityTests(SecurityTest):
AUTH_CONFIG = {
'SECURITY_PASSWORD_HASH': 'bcrypt',
'SECURITY_USER_DATASTORE': 'custom_datastore_name',
@@ -112,22 +117,22 @@ class ConfiguredSecurityTests(SecurityTest):
'SECURITY_POST_LOGIN': '/post_login',
'SECURITY_POST_LOGOUT': '/post_logout'
}
def test_login_view(self):
r = self._get('/custom_login')
assert "Custom Login Page" in r.data
def test_authenticate(self):
r = self.authenticate("matt", "password", endpoint="/custom_auth")
assert 'Post Login' in r.data
def test_logout(self):
self.authenticate("matt", "password", endpoint="/custom_auth")
r = self.logout(endpoint="/custom_logout")
assert 'Post Logout' in r.data
class MongoEngineSecurityTests(DefaultSecurityTests):
def _create_app(self, auth_config):
return app.create_mongoengine_app(auth_config)
return app.create_mongoengine_app(auth_config)