Make most messages configurable

This commit is contained in:
Matt Wright
2012-07-12 15:24:57 -04:00
parent 3df4c4d14a
commit 18c7a838b0
7 changed files with 50 additions and 25 deletions
+4 -4
View File
@@ -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):
+16
View File
@@ -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)
+4 -4
View File
@@ -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 '/')
+3 -3
View File
@@ -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):
+4
View File
@@ -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
View File
@@ -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')
+4 -4
View File
@@ -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)