mirror of
https://github.com/wassname/flask-security.git
synced 2026-07-19 11:23:28 +08:00
Make most messages configurable
This commit is contained in:
@@ -16,7 +16,7 @@ from flask import current_app as app, request, url_for
|
||||
from werkzeug.local import LocalProxy
|
||||
|
||||
from .exceptions import UserNotFoundError, ConfirmationError
|
||||
from .utils import send_mail, get_max_age, md5
|
||||
from .utils import send_mail, get_max_age, md5, get_message
|
||||
from .signals import user_confirmed, confirm_instructions_sent
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ def confirm_by_token(token):
|
||||
raise UserNotFoundError()
|
||||
|
||||
if user.confirmed_at:
|
||||
raise ConfirmationError('Account has already been confirmed')
|
||||
raise ConfirmationError(get_message('ALREADY_CONFIRMED'))
|
||||
|
||||
user.confirmed_at = datetime.utcnow()
|
||||
_datastore._save_model(user)
|
||||
@@ -102,10 +102,10 @@ def confirm_by_token(token):
|
||||
user=_datastore.find_user(id=data[0]))
|
||||
|
||||
except BadSignature:
|
||||
raise ConfirmationError('Invalid confirmation token')
|
||||
raise ConfirmationError(get_message('INVALID_CONFIRMATION_TOKEN'))
|
||||
|
||||
except UserNotFoundError:
|
||||
raise ConfirmationError('Invalid confirmation token')
|
||||
raise ConfirmationError(get_message('INVALID_CONFIRMATION_TOKEN'))
|
||||
|
||||
|
||||
def reset_confirmation_token(user):
|
||||
|
||||
@@ -60,6 +60,19 @@ _default_config = {
|
||||
'DEFAULT_HTTP_AUTH_REALM': 'Login Required'
|
||||
}
|
||||
|
||||
#: Default Flask-Security flash messages
|
||||
_default_flash_messages = {
|
||||
'UNAUTHORIZED': 'You do not have permission to view this resource.',
|
||||
'ACCOUNT_CONFIRMED': 'Your account has been confirmed. You may now log in.',
|
||||
'ALREADY_CONFIRMED': 'Your account has already been confirmed',
|
||||
'INVALID_CONFIRMATION_TOKEN': 'Invalid confirmation token',
|
||||
'PASSWORD_RESET_REQUEST': 'Instructions to reset your password have been sent to %(email)s.',
|
||||
'PASSWORD_RESET_EXPIRED': 'You did not reset your password within %(within)s. New instructions have been sent to %(email)s.',
|
||||
'INVALID_RESET_PASSWORD_TOKEN': 'Invalid reset password token',
|
||||
'CONFIRMATION_REQUEST': 'A new confirmation code has been sent to %(email)s.',
|
||||
'CONFIRMATION_EXPIRED': 'You did not confirm your account within %(within)s. New instructions to confirm your account have been sent to %(email)s.'
|
||||
}
|
||||
|
||||
|
||||
def _user_loader(user_id):
|
||||
try:
|
||||
@@ -233,6 +246,9 @@ class Security(object):
|
||||
for key, value in _default_config.items():
|
||||
app.config.setdefault('SECURITY_' + key, value)
|
||||
|
||||
for key, value in _default_flash_messages.items():
|
||||
app.config.setdefault('SECURITY_MSG_' + key, value)
|
||||
|
||||
self.datastore = datastore
|
||||
self.auth_provider = AuthenticationProvider()
|
||||
self.login_manager = _get_login_manager(app)
|
||||
|
||||
@@ -26,7 +26,7 @@ _security = LocalProxy(lambda: current_app.security)
|
||||
_logger = LocalProxy(lambda: current_app.logger)
|
||||
|
||||
|
||||
_default_unauthorized_txt = """
|
||||
_default_unauthorized_html = """
|
||||
<h1>Unauthorized</h1>
|
||||
<p>The server could not verify that you are authorized to access the URL
|
||||
requested. You either supplied the wrong credentials (e.g. a bad password),
|
||||
@@ -35,14 +35,14 @@ _default_unauthorized_txt = """
|
||||
|
||||
|
||||
def _get_unauthorized_response(text=None, headers=None):
|
||||
text = text or _default_unauthorized_txt
|
||||
text = text or _default_unauthorized_html
|
||||
headers = headers or {}
|
||||
return Response(_default_unauthorized_txt, 401, headers)
|
||||
return Response(text, 401, headers)
|
||||
|
||||
|
||||
def _get_unauthorized_view():
|
||||
cv = utils.get_url(utils.config_value('UNAUTHORIZED_VIEW'))
|
||||
utils.do_flash('You do not have permission to view this resource', 'error')
|
||||
utils.do_flash(utils.get_message('UNAUTHORIZED'), 'error')
|
||||
return redirect(cv or request.referrer or '/')
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ from werkzeug.local import LocalProxy
|
||||
from .exceptions import ResetPasswordError, UserNotFoundError
|
||||
from .signals import password_reset, password_reset_requested, \
|
||||
reset_instructions_sent
|
||||
from .utils import send_mail, get_max_age, md5
|
||||
from .utils import send_mail, get_max_age, md5, get_message
|
||||
|
||||
|
||||
# Convenient references
|
||||
@@ -100,10 +100,10 @@ def reset_by_token(token, password):
|
||||
user=_datastore.find_user(id=data[0]))
|
||||
|
||||
except BadSignature:
|
||||
raise ResetPasswordError('Invalid reset password token')
|
||||
raise ResetPasswordError(get_message('INVALID_RESET_PASSWORD_TOKEN'))
|
||||
|
||||
except UserNotFoundError:
|
||||
raise ResetPasswordError('Invalid reset password token')
|
||||
raise ResetPasswordError(get_message('INVALID_RESET_PASSWORD_TOKEN'))
|
||||
|
||||
|
||||
def reset_password_reset_token(user):
|
||||
|
||||
@@ -95,6 +95,10 @@ def get_config(app):
|
||||
return dict([strip_prefix(i) for i in items if i[0].startswith(prefix)])
|
||||
|
||||
|
||||
def get_message(key, **kwargs):
|
||||
return config_value('MSG_' + key) % kwargs
|
||||
|
||||
|
||||
def config_value(key, app=None, default=None):
|
||||
"""Get a Flask-Security configuration value.
|
||||
|
||||
|
||||
+15
-10
@@ -28,7 +28,7 @@ from .recoverable import reset_by_token, \
|
||||
from .signals import user_registered
|
||||
from .tokens import generate_authentication_token
|
||||
from .utils import get_url, get_post_login_redirect, do_flash, \
|
||||
get_remember_token
|
||||
get_remember_token, get_message
|
||||
|
||||
|
||||
# Convenient references
|
||||
@@ -181,7 +181,8 @@ def send_confirmation():
|
||||
|
||||
_logger.debug('%s request confirmation instructions' % user)
|
||||
|
||||
msg = 'A new confirmation code has been sent to ' + user.email
|
||||
msg = get_message('CONFIRMATION_REQUEST', email=user.email)
|
||||
|
||||
do_flash(msg, 'info')
|
||||
|
||||
else:
|
||||
@@ -205,15 +206,16 @@ def confirm_account(token):
|
||||
|
||||
if e.user:
|
||||
reset_confirmation_token(e.user)
|
||||
msg = ('You did not confirm your email within %s. '
|
||||
'A new confirmation code has been sent to %s' % (
|
||||
_security.confirm_email_within, e.user.email))
|
||||
|
||||
msg = get_message('CONFIRMATION_EXPIRED',
|
||||
within=_security.confirm_email_within,
|
||||
email=e.user.email)
|
||||
|
||||
do_flash(msg, 'error')
|
||||
|
||||
return redirect(get_url(_security.confirm_error_view))
|
||||
|
||||
do_flash('Your email has been confirmed. You may now log in.', 'success')
|
||||
do_flash(get_message('ACCOUNT_CONFIRMED'), 'success')
|
||||
|
||||
return redirect(_security.post_confirm_view or _security.post_login_view)
|
||||
|
||||
@@ -230,8 +232,8 @@ def forgot_password():
|
||||
|
||||
_logger.debug('%s requested to reset their password' % user)
|
||||
|
||||
do_flash('Instructions to reset your password have been '
|
||||
'sent to %s' % user.email, 'success')
|
||||
msg = get_message('PASSWORD_RESET_REQUEST', email=user.email)
|
||||
do_flash(msg, 'success')
|
||||
|
||||
return redirect(_security.post_forgot_view)
|
||||
|
||||
@@ -262,8 +264,11 @@ def reset_password(token):
|
||||
_logger.debug('Password reset error: ' + msg)
|
||||
|
||||
if e.user:
|
||||
msg = ('You did not reset your password within '
|
||||
'%s.' % _security.reset_password_within)
|
||||
reset_password_reset_token(e.user)
|
||||
|
||||
msg = get_message('PASSWORD_RESET_EXPIRED',
|
||||
within=_security.reset_password_within,
|
||||
email=e.user.email)
|
||||
|
||||
do_flash(msg, 'error')
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ class DefaultSecurityTests(SecurityTest):
|
||||
|
||||
def test_inactive_user(self):
|
||||
r = self.authenticate("tiya@lp.com", "password")
|
||||
self.assertIn("Inactive user", r.data)
|
||||
self.assertIn("Account is disabled", r.data)
|
||||
|
||||
def test_logout(self):
|
||||
self.authenticate()
|
||||
@@ -237,7 +237,7 @@ class ConfirmableTests(SecurityTest):
|
||||
token = registrations[0]['confirm_token']
|
||||
|
||||
r = self.client.get('/confirm/' + token, follow_redirects=True)
|
||||
self.assertIn('Your email has been confirmed. You may now log in.', r.data)
|
||||
self.assertIn('Your account has been confirmed. You may now log in.', r.data)
|
||||
|
||||
def test_confirm_email_twice_flashes_already_confirmed_message(self):
|
||||
e = 'dude@lp.com'
|
||||
@@ -249,7 +249,7 @@ class ConfirmableTests(SecurityTest):
|
||||
url = '/confirm/' + token
|
||||
self.client.get(url, follow_redirects=True)
|
||||
r = self.client.get(url, follow_redirects=True)
|
||||
self.assertIn('Account has already been confirmed', r.data)
|
||||
self.assertIn('Your account has already been confirmed', r.data)
|
||||
|
||||
def test_invalid_token_when_confirming_email(self):
|
||||
r = self.client.get('/confirm/bogus', follow_redirects=True)
|
||||
@@ -280,7 +280,7 @@ class ExpiredConfirmationTest(SecurityTest):
|
||||
self.assertNotIn(token, outbox[0].html)
|
||||
|
||||
expire_text = self.app.security.confirm_email_within
|
||||
text = 'You did not confirm your email within %s' % expire_text
|
||||
text = 'You did not confirm your account within %s' % expire_text
|
||||
|
||||
self.assertIn(text, r.data)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user