mirror of
https://github.com/wassname/flask-security.git
synced 2026-08-07 11:22:21 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d34d87a97 | ||
|
|
461ace9303 | ||
|
|
d19bb98abd | ||
|
|
c24af5ca6e | ||
|
|
26045fc4dc | ||
|
|
bf260d4b7e |
@@ -4,6 +4,16 @@ Flask-Security Changelog
|
|||||||
Here you can see the full list of changes between each Flask-Security release.
|
Here you can see the full list of changes between each Flask-Security release.
|
||||||
|
|
||||||
|
|
||||||
|
Version 1.6.4
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Released June 18th 2013
|
||||||
|
|
||||||
|
- Added `SECURITY_DEFAULT_REMEMBER_ME` configuration value to unify behavior between endpoints
|
||||||
|
- Fixed Flask-Login dependency problem
|
||||||
|
- Added optional `next` parameter to registration endpoint, similar to that of login
|
||||||
|
|
||||||
|
|
||||||
Version 1.6.3
|
Version 1.6.3
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -49,7 +49,7 @@ copyright = u'2012, Matt Wright'
|
|||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '1.6.3'
|
version = '1.6.4'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = version
|
release = version
|
||||||
|
|
||||||
|
|||||||
@@ -220,4 +220,7 @@ Miscellaneous
|
|||||||
remember tokens. Remember tokens are
|
remember tokens. Remember tokens are
|
||||||
used instead of user ID's as it is more
|
used instead of user ID's as it is more
|
||||||
secure. Defaults to ``remember-salt``.
|
secure. Defaults to ``remember-salt``.
|
||||||
|
``SECURITY_DEFAULT_REMEMBER_ME`` Specifies the default "remember me"
|
||||||
|
value used when logging in a user.
|
||||||
|
Defaults to ``False``.
|
||||||
======================================= ========================================
|
======================================= ========================================
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
:license: MIT, see LICENSE for more details.
|
:license: MIT, see LICENSE for more details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = '1.6.3'
|
__version__ = '1.6.4'
|
||||||
|
|
||||||
from .core import Security, RoleMixin, UserMixin, AnonymousUser, current_user
|
from .core import Security, RoleMixin, UserMixin, AnonymousUser, current_user
|
||||||
from .datastore import SQLAlchemyUserDatastore, MongoEngineUserDatastore, PeeweeUserDatastore
|
from .datastore import SQLAlchemyUserDatastore, MongoEngineUserDatastore, PeeweeUserDatastore
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ from flask import current_app as app, request
|
|||||||
from werkzeug.local import LocalProxy
|
from werkzeug.local import LocalProxy
|
||||||
|
|
||||||
from .signals import password_changed
|
from .signals import password_changed
|
||||||
from .utils import send_mail, encrypt_password, url_for_security, \
|
from .utils import send_mail, encrypt_password, config_value
|
||||||
config_value
|
|
||||||
|
|
||||||
|
|
||||||
# Convenient references
|
# Convenient references
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from flask import current_app as app, request
|
|||||||
from werkzeug.local import LocalProxy
|
from werkzeug.local import LocalProxy
|
||||||
|
|
||||||
from .utils import send_mail, md5, url_for_security, get_token_status,\
|
from .utils import send_mail, md5, url_for_security, get_token_status,\
|
||||||
config_value
|
config_value
|
||||||
from .signals import user_confirmed, confirm_instructions_sent
|
from .signals import user_confirmed, confirm_instructions_sent
|
||||||
|
|
||||||
|
|
||||||
@@ -27,8 +27,7 @@ _datastore = LocalProxy(lambda: _security.datastore)
|
|||||||
|
|
||||||
def generate_confirmation_link(user):
|
def generate_confirmation_link(user):
|
||||||
token = generate_confirmation_token(user)
|
token = generate_confirmation_token(user)
|
||||||
url = url_for_security('confirm_email', token=token)
|
return url_for_security('confirm_email', token=token, _extenal=True), token
|
||||||
return request.url_root[:-1] + url, token
|
|
||||||
|
|
||||||
|
|
||||||
def send_confirmation_instructions(user):
|
def send_confirmation_instructions(user):
|
||||||
|
|||||||
@@ -10,10 +10,10 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from flask.ext.login import AnonymousUser as AnonymousUserBase, \
|
from flask.ext.login import AnonymousUserMixin, UserMixin as BaseUserMixin, \
|
||||||
UserMixin as BaseUserMixin, LoginManager, current_user
|
LoginManager, current_user
|
||||||
from flask.ext.principal import Principal, RoleNeed, UserNeed, Identity, \
|
from flask.ext.principal import Principal, RoleNeed, UserNeed, Identity, \
|
||||||
identity_loaded
|
identity_loaded
|
||||||
from itsdangerous import URLSafeTimedSerializer
|
from itsdangerous import URLSafeTimedSerializer
|
||||||
from passlib.context import CryptContext
|
from passlib.context import CryptContext
|
||||||
from werkzeug.datastructures import ImmutableList
|
from werkzeug.datastructures import ImmutableList
|
||||||
@@ -22,8 +22,8 @@ from werkzeug.local import LocalProxy
|
|||||||
from .utils import config_value as cv, get_config, md5, url_for_security
|
from .utils import config_value as cv, get_config, md5, url_for_security
|
||||||
from .views import create_blueprint
|
from .views import create_blueprint
|
||||||
from .forms import LoginForm, ConfirmRegisterForm, RegisterForm, \
|
from .forms import LoginForm, ConfirmRegisterForm, RegisterForm, \
|
||||||
ForgotPasswordForm, ChangePasswordForm, ResetPasswordForm, \
|
ForgotPasswordForm, ChangePasswordForm, ResetPasswordForm, \
|
||||||
SendConfirmationForm, PasswordlessLoginForm
|
SendConfirmationForm, PasswordlessLoginForm
|
||||||
|
|
||||||
# Convenient references
|
# Convenient references
|
||||||
_security = LocalProxy(lambda: current_app.extensions['security'])
|
_security = LocalProxy(lambda: current_app.extensions['security'])
|
||||||
@@ -76,6 +76,7 @@ _default_config = {
|
|||||||
'LOGIN_SALT': 'login-salt',
|
'LOGIN_SALT': 'login-salt',
|
||||||
'CHANGE_SALT': 'change-salt',
|
'CHANGE_SALT': 'change-salt',
|
||||||
'REMEMBER_SALT': 'remember-salt',
|
'REMEMBER_SALT': 'remember-salt',
|
||||||
|
'DEFAULT_REMEMBER_ME': False,
|
||||||
'DEFAULT_HTTP_AUTH_REALM': 'Login Required',
|
'DEFAULT_HTTP_AUTH_REALM': 'Login Required',
|
||||||
'EMAIL_SUBJECT_REGISTER': 'Welcome',
|
'EMAIL_SUBJECT_REGISTER': 'Welcome',
|
||||||
'EMAIL_SUBJECT_CONFIRM': 'Please confirm your email',
|
'EMAIL_SUBJECT_CONFIRM': 'Please confirm your email',
|
||||||
@@ -153,8 +154,7 @@ def _token_loader(token):
|
|||||||
return user
|
return user
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
return AnonymousUser()
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def _identity_loader():
|
def _identity_loader():
|
||||||
@@ -272,11 +272,10 @@ class UserMixin(BaseUserMixin):
|
|||||||
return role in self.roles
|
return role in self.roles
|
||||||
|
|
||||||
|
|
||||||
class AnonymousUser(AnonymousUserBase):
|
class AnonymousUser(AnonymousUserMixin):
|
||||||
"""AnonymousUser definition"""
|
"""AnonymousUser definition"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(AnonymousUser, self).__init__()
|
|
||||||
self.roles = ImmutableList()
|
self.roles = ImmutableList()
|
||||||
|
|
||||||
def has_role(self, *args):
|
def has_role(self, *args):
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import flask_wtf as wtf
|
|||||||
|
|
||||||
from flask import request, current_app
|
from flask import request, current_app
|
||||||
from flask_wtf import Form as BaseForm, TextField, PasswordField, \
|
from flask_wtf import Form as BaseForm, TextField, PasswordField, \
|
||||||
SubmitField, HiddenField, BooleanField, ValidationError, Field
|
SubmitField, HiddenField, BooleanField, ValidationError, Field
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from werkzeug.local import LocalProxy
|
from werkzeug.local import LocalProxy
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from werkzeug.local import LocalProxy
|
|||||||
|
|
||||||
from .signals import login_instructions_sent
|
from .signals import login_instructions_sent
|
||||||
from .utils import send_mail, url_for_security, get_token_status, \
|
from .utils import send_mail, url_for_security, get_token_status, \
|
||||||
config_value
|
config_value
|
||||||
|
|
||||||
|
|
||||||
# Convenient references
|
# Convenient references
|
||||||
@@ -30,8 +30,7 @@ def send_login_instructions(user):
|
|||||||
:param token: The login token
|
:param token: The login token
|
||||||
"""
|
"""
|
||||||
token = generate_login_token(user)
|
token = generate_login_token(user)
|
||||||
url = url_for_security('token_login', token=token)
|
login_link = url_for_security('token_login', token=token, _external=True)
|
||||||
login_link = request.url_root[:-1] + url
|
|
||||||
|
|
||||||
send_mail(config_value('EMAIL_SUBJECT_PASSWORDLESS'), user.email,
|
send_mail(config_value('EMAIL_SUBJECT_PASSWORDLESS'), user.email,
|
||||||
'login_instructions', user=user, login_link=login_link)
|
'login_instructions', user=user, login_link=login_link)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from werkzeug.local import LocalProxy
|
|||||||
|
|
||||||
from .signals import password_reset, reset_password_instructions_sent
|
from .signals import password_reset, reset_password_instructions_sent
|
||||||
from .utils import send_mail, md5, encrypt_password, url_for_security, \
|
from .utils import send_mail, md5, encrypt_password, url_for_security, \
|
||||||
get_token_status, config_value
|
get_token_status, config_value
|
||||||
|
|
||||||
|
|
||||||
# Convenient references
|
# Convenient references
|
||||||
@@ -29,8 +29,7 @@ def send_reset_password_instructions(user):
|
|||||||
:param user: The user to send the instructions to
|
:param user: The user to send the instructions to
|
||||||
"""
|
"""
|
||||||
token = generate_reset_password_token(user)
|
token = generate_reset_password_token(user)
|
||||||
url = url_for_security('reset_password', token=token)
|
reset_link = url_for_security('reset_password', token=token, _external=True)
|
||||||
reset_link = request.url_root[:-1] + url
|
|
||||||
|
|
||||||
send_mail(config_value('EMAIL_SUBJECT_PASSWORD_RESET'), user.email,
|
send_mail(config_value('EMAIL_SUBJECT_PASSWORD_RESET'), user.email,
|
||||||
'reset_instructions',
|
'reset_instructions',
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from werkzeug.local import LocalProxy
|
|||||||
from .confirmable import generate_confirmation_link
|
from .confirmable import generate_confirmation_link
|
||||||
from .signals import user_registered
|
from .signals import user_registered
|
||||||
from .utils import do_flash, get_message, send_mail, encrypt_password, \
|
from .utils import do_flash, get_message, send_mail, encrypt_password, \
|
||||||
config_value
|
config_value
|
||||||
|
|
||||||
# Convenient references
|
# Convenient references
|
||||||
_security = LocalProxy(lambda: app.extensions['security'])
|
_security = LocalProxy(lambda: app.extensions['security'])
|
||||||
|
|||||||
+16
-5
@@ -14,12 +14,13 @@ import blinker
|
|||||||
import functools
|
import functools
|
||||||
import hashlib
|
import hashlib
|
||||||
import hmac
|
import hmac
|
||||||
|
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from flask import url_for, flash, current_app, request, session, render_template
|
from flask import url_for, flash, current_app, request, session, render_template
|
||||||
from flask.ext.login import login_user as _login_user, \
|
from flask.ext.login import login_user as _login_user, \
|
||||||
logout_user as _logout_user
|
logout_user as _logout_user
|
||||||
from flask.ext.mail import Message
|
from flask.ext.mail import Message
|
||||||
from flask.ext.principal import Identity, AnonymousIdentity, identity_changed
|
from flask.ext.principal import Identity, AnonymousIdentity, identity_changed
|
||||||
from itsdangerous import BadSignature, SignatureExpired
|
from itsdangerous import BadSignature, SignatureExpired
|
||||||
@@ -37,9 +38,12 @@ _datastore = LocalProxy(lambda: _security.datastore)
|
|||||||
_pwd_context = LocalProxy(lambda: _security.pwd_context)
|
_pwd_context = LocalProxy(lambda: _security.pwd_context)
|
||||||
|
|
||||||
|
|
||||||
def login_user(user, remember=True):
|
def login_user(user, remember=None):
|
||||||
"""Performs the login and sends the appropriate signal."""
|
"""Performs the login and sends the appropriate signal."""
|
||||||
|
|
||||||
|
if remember is None:
|
||||||
|
remember = config_value('DEFAULT_REMEMBER_ME')
|
||||||
|
|
||||||
if not _login_user(user, remember):
|
if not _login_user(user, remember):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -144,11 +148,18 @@ def url_for_security(endpoint, **values):
|
|||||||
return url_for(endpoint, **values)
|
return url_for(endpoint, **values)
|
||||||
|
|
||||||
|
|
||||||
def get_post_login_redirect():
|
def get_post_action_redirect(config_key):
|
||||||
"""Returns the URL to redirect to after a user logs in successfully."""
|
|
||||||
return (get_url(request.args.get('next')) or
|
return (get_url(request.args.get('next')) or
|
||||||
get_url(request.form.get('next')) or
|
get_url(request.form.get('next')) or
|
||||||
find_redirect('SECURITY_POST_LOGIN_VIEW'))
|
find_redirect(config_key))
|
||||||
|
|
||||||
|
|
||||||
|
def get_post_login_redirect():
|
||||||
|
return get_post_action_redirect('SECURITY_POST_LOGIN_VIEW')
|
||||||
|
|
||||||
|
|
||||||
|
def get_post_register_redirect():
|
||||||
|
return get_post_action_redirect('SECURITY_POST_REGISTER_VIEW')
|
||||||
|
|
||||||
|
|
||||||
def find_redirect(key):
|
def find_redirect(key):
|
||||||
|
|||||||
+11
-14
@@ -10,24 +10,23 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from flask import current_app, redirect, request, render_template, jsonify, \
|
from flask import current_app, redirect, request, render_template, jsonify, \
|
||||||
after_this_request, Blueprint
|
after_this_request, Blueprint
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from werkzeug.datastructures import MultiDict
|
from werkzeug.datastructures import MultiDict
|
||||||
from werkzeug.local import LocalProxy
|
from werkzeug.local import LocalProxy
|
||||||
|
|
||||||
from .confirmable import send_confirmation_instructions, \
|
from .confirmable import send_confirmation_instructions, \
|
||||||
confirm_user, confirm_email_token_status
|
confirm_user, confirm_email_token_status
|
||||||
from .decorators import login_required, anonymous_user_required
|
from .decorators import login_required, anonymous_user_required
|
||||||
from .passwordless import send_login_instructions, \
|
from .passwordless import send_login_instructions, \
|
||||||
login_token_status
|
login_token_status
|
||||||
from .recoverable import reset_password_token_status, \
|
from .recoverable import reset_password_token_status, \
|
||||||
send_reset_password_instructions, update_password
|
send_reset_password_instructions, update_password
|
||||||
from .changeable import change_user_password
|
from .changeable import change_user_password
|
||||||
from .registerable import register_user
|
from .registerable import register_user
|
||||||
from .utils import get_url, get_post_login_redirect, do_flash, \
|
from .utils import config_value, do_flash, get_url, get_post_login_redirect, \
|
||||||
get_message, login_user, logout_user, url_for_security as url_for, \
|
get_post_register_redirect, get_message, login_user, logout_user, \
|
||||||
config_value
|
url_for_security as url_for
|
||||||
|
|
||||||
|
|
||||||
# Convenient references
|
# Convenient references
|
||||||
_security = LocalProxy(lambda: current_app.extensions['security'])
|
_security = LocalProxy(lambda: current_app.extensions['security'])
|
||||||
@@ -123,9 +122,7 @@ def register():
|
|||||||
login_user(user)
|
login_user(user)
|
||||||
|
|
||||||
if not request.json:
|
if not request.json:
|
||||||
post_register_url = get_url(_security.post_register_view)
|
return redirect(get_post_register_redirect())
|
||||||
post_login_url = get_url(_security.post_login_view)
|
|
||||||
return redirect(post_register_url or post_login_url)
|
|
||||||
|
|
||||||
if request.json:
|
if request.json:
|
||||||
return _render_json(form)
|
return _render_json(form)
|
||||||
@@ -173,7 +170,7 @@ def token_login(token):
|
|||||||
if invalid or expired:
|
if invalid or expired:
|
||||||
return redirect(url_for('login'))
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
login_user(user, True)
|
login_user(user)
|
||||||
after_this_request(_commit)
|
after_this_request(_commit)
|
||||||
do_flash(*get_message('PASSWORDLESS_LOGIN_SUCCESSFUL'))
|
do_flash(*get_message('PASSWORDLESS_LOGIN_SUCCESSFUL'))
|
||||||
|
|
||||||
@@ -221,7 +218,7 @@ def confirm_email(token):
|
|||||||
url_for('send_confirmation'))
|
url_for('send_confirmation'))
|
||||||
|
|
||||||
confirm_user(user)
|
confirm_user(user)
|
||||||
login_user(user, True)
|
login_user(user)
|
||||||
after_this_request(_commit)
|
after_this_request(_commit)
|
||||||
do_flash(*get_message('EMAIL_CONFIRMED'))
|
do_flash(*get_message('EMAIL_CONFIRMED'))
|
||||||
|
|
||||||
@@ -272,7 +269,7 @@ def reset_password(token):
|
|||||||
after_this_request(_commit)
|
after_this_request(_commit)
|
||||||
update_password(user, form.password.data)
|
update_password(user, form.password.data)
|
||||||
do_flash(*get_message('PASSWORD_RESET'))
|
do_flash(*get_message('PASSWORD_RESET'))
|
||||||
login_user(user, True)
|
login_user(user)
|
||||||
return redirect(get_url(_security.post_reset_view) or
|
return redirect(get_url(_security.post_reset_view) or
|
||||||
get_url(_security.post_login_view))
|
get_url(_security.post_login_view))
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from setuptools import setup
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='Flask-Security',
|
name='Flask-Security',
|
||||||
version='1.6.3',
|
version='1.6.4',
|
||||||
url='https://github.com/mattupstate/flask-security',
|
url='https://github.com/mattupstate/flask-security',
|
||||||
license='MIT',
|
license='MIT',
|
||||||
author='Matt Wright',
|
author='Matt Wright',
|
||||||
@@ -35,10 +35,10 @@ setup(
|
|||||||
platforms='any',
|
platforms='any',
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'Flask>=0.9',
|
'Flask>=0.9',
|
||||||
'Flask-Login>=0.1.3',
|
'Flask-Login==0.2.3',
|
||||||
'Flask-Mail>=0.7.3',
|
'Flask-Mail==0.7.3',
|
||||||
'Flask-Principal>=0.3.3',
|
'Flask-Principal==0.3.3',
|
||||||
'Flask-WTF>=0.8',
|
'Flask-WTF==0.8',
|
||||||
'itsdangerous>=0.17',
|
'itsdangerous>=0.17',
|
||||||
'passlib>=1.6.1',
|
'passlib>=1.6.1',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -68,6 +68,14 @@ class ConfiguredSecurityTests(SecurityTest):
|
|||||||
r = self._post('/register', data=data, follow_redirects=True)
|
r = self._post('/register', data=data, follow_redirects=True)
|
||||||
self.assertIn('Post Register', r.data)
|
self.assertIn('Post Register', r.data)
|
||||||
|
|
||||||
|
def test_register_with_next_querystring_argument(self):
|
||||||
|
data = dict(email='dude@lp.com',
|
||||||
|
password='password',
|
||||||
|
password_confirm='password')
|
||||||
|
|
||||||
|
r = self._post('/register?next=/page1', data=data, follow_redirects=True)
|
||||||
|
self.assertIn('Page 1', r.data)
|
||||||
|
|
||||||
def test_register_json(self):
|
def test_register_json(self):
|
||||||
data = '{ "email": "dude@lp.com", "password": "password", "csrf_token":"%s" }' % self.csrf_token
|
data = '{ "email": "dude@lp.com", "password": "password", "csrf_token":"%s" }' % self.csrf_token
|
||||||
r = self._post('/register', data=data, content_type='application/json')
|
r = self._post('/register', data=data, content_type='application/json')
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class DefaultSecurityTests(SecurityTest):
|
|||||||
|
|
||||||
def test_unauthorized_access(self):
|
def test_unauthorized_access(self):
|
||||||
r = self._get('/profile', follow_redirects=True)
|
r = self._get('/profile', follow_redirects=True)
|
||||||
self.assertIn('<li class="message">Please log in to access this page.</li>', r.data)
|
self.assertIn('<li class="info">Please log in to access this page.</li>', r.data)
|
||||||
|
|
||||||
def test_authorized_access(self):
|
def test_authorized_access(self):
|
||||||
self.authenticate()
|
self.authenticate()
|
||||||
|
|||||||
+12
-5
@@ -15,7 +15,14 @@ def compare_user(a, b):
|
|||||||
return a.id == b.id and a.email == b.email and a.password == b.password
|
return a.id == b.id and a.email == b.email and a.password == b.password
|
||||||
|
|
||||||
|
|
||||||
class RegisterableSignalsTests(SecurityTest):
|
class SignalTest(SecurityTest):
|
||||||
|
|
||||||
|
def _create_app(self, auth_config, **kwargs):
|
||||||
|
from tests.test_app.mongoengine import create_app
|
||||||
|
return create_app(auth_config, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class RegisterableSignalsTests(SignalTest):
|
||||||
|
|
||||||
AUTH_CONFIG = {
|
AUTH_CONFIG = {
|
||||||
'SECURITY_CONFIRMABLE': True,
|
'SECURITY_CONFIRMABLE': True,
|
||||||
@@ -42,7 +49,7 @@ class RegisterableSignalsTests(SecurityTest):
|
|||||||
self.assertEqual(mocks.signals_sent(), set())
|
self.assertEqual(mocks.signals_sent(), set())
|
||||||
|
|
||||||
|
|
||||||
class ConfirmableSignalsTests(SecurityTest):
|
class ConfirmableSignalsTests(SignalTest):
|
||||||
|
|
||||||
AUTH_CONFIG = {
|
AUTH_CONFIG = {
|
||||||
'SECURITY_CONFIRMABLE': True,
|
'SECURITY_CONFIRMABLE': True,
|
||||||
@@ -103,7 +110,7 @@ class ConfirmableSignalsTests(SecurityTest):
|
|||||||
self.assertEqual(mocks.signals_sent(), set())
|
self.assertEqual(mocks.signals_sent(), set())
|
||||||
|
|
||||||
|
|
||||||
class RecoverableSignalsTests(SecurityTest):
|
class RecoverableSignalsTests(SignalTest):
|
||||||
|
|
||||||
AUTH_CONFIG = {
|
AUTH_CONFIG = {
|
||||||
'SECURITY_RECOVERABLE': True,
|
'SECURITY_RECOVERABLE': True,
|
||||||
@@ -153,7 +160,7 @@ class RecoverableSignalsTests(SecurityTest):
|
|||||||
self.assertEqual(mocks.signals_sent(), set())
|
self.assertEqual(mocks.signals_sent(), set())
|
||||||
|
|
||||||
|
|
||||||
class ChangeableSignalsTests(SecurityTest):
|
class ChangeableSignalsTests(SignalTest):
|
||||||
|
|
||||||
AUTH_CONFIG = {
|
AUTH_CONFIG = {
|
||||||
'SECURITY_CHANGEABLE': True,
|
'SECURITY_CHANGEABLE': True,
|
||||||
@@ -204,7 +211,7 @@ class ChangeableSignalsTests(SecurityTest):
|
|||||||
self.assertEqual(mocks.signals_sent(), set())
|
self.assertEqual(mocks.signals_sent(), set())
|
||||||
|
|
||||||
|
|
||||||
class PasswordlessTests(SecurityTest):
|
class PasswordlessTests(SignalTest):
|
||||||
|
|
||||||
AUTH_CONFIG = {
|
AUTH_CONFIG = {
|
||||||
'SECURITY_PASSWORDLESS': True
|
'SECURITY_PASSWORDLESS': True
|
||||||
|
|||||||
@@ -113,6 +113,10 @@ def create_app(config):
|
|||||||
def invalid_role():
|
def invalid_role():
|
||||||
return 'success' if ds.find_role('bogus') is None else 'failure'
|
return 'success' if ds.find_role('bogus') is None else 'failure'
|
||||||
|
|
||||||
|
@app.route('/page1')
|
||||||
|
def page_1():
|
||||||
|
return 'Page 1'
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user