mirror of
https://github.com/wassname/flask-security.git
synced 2026-07-05 17:30:14 +08:00
Polish up some code and add some signals
This commit is contained in:
@@ -5,10 +5,11 @@ from flask import current_app, request, url_for
|
||||
from flask.ext.security.exceptions import UserNotFoundError, \
|
||||
ConfirmationError, TokenExpiredError
|
||||
from flask.ext.security.utils import generate_token, send_mail
|
||||
from flask.ext.security.signals import user_confirmed, \
|
||||
confirm_instructions_sent
|
||||
from werkzeug.local import LocalProxy
|
||||
|
||||
security = LocalProxy(lambda: current_app.security)
|
||||
|
||||
logger = LocalProxy(lambda: current_app.logger)
|
||||
|
||||
|
||||
@@ -28,6 +29,8 @@ def send_confirmation_instructions(user):
|
||||
'confirmation_instructions',
|
||||
dict(user=user, confirmation_link=confirmation_link))
|
||||
|
||||
confirm_instructions_sent.send(user, app=current_app._get_current_object())
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -89,6 +92,7 @@ def confirm_by_token(token):
|
||||
|
||||
security.datastore._save_model(user)
|
||||
|
||||
user_confirmed.send(user, app=current_app._get_current_object())
|
||||
return user
|
||||
|
||||
|
||||
|
||||
@@ -302,6 +302,9 @@ class ForgotPasswordForm(Form):
|
||||
email = TextField("Email Address",
|
||||
validators=[Required(message="Email not provided")])
|
||||
|
||||
def to_dict(self):
|
||||
return dict(email=self.email.data)
|
||||
|
||||
|
||||
class LoginForm(Form):
|
||||
"""The default login form"""
|
||||
@@ -334,13 +337,18 @@ class RegisterForm(Form):
|
||||
|
||||
|
||||
class ResetPasswordForm(Form):
|
||||
reset_password_token = HiddenField(validators=[Required()])
|
||||
token = HiddenField(validators=[Required()])
|
||||
email = HiddenField(validators=[Required()])
|
||||
password = PasswordField("Password",
|
||||
validators=[Required(message="Password not provided")])
|
||||
password_confirm = PasswordField("Retype Password",
|
||||
validators=[EqualTo('password', message="Passwords do not match")])
|
||||
|
||||
def to_dict(self):
|
||||
return dict(token=self.token.data,
|
||||
email=self.email.data,
|
||||
password=self.password.data)
|
||||
|
||||
|
||||
class AuthenticationProvider(object):
|
||||
"""The default authentication provider implementation.
|
||||
|
||||
@@ -4,12 +4,12 @@ from datetime import datetime
|
||||
from flask import current_app, request, url_for
|
||||
from flask.ext.security.exceptions import ResetPasswordError, \
|
||||
UserNotFoundError, TokenExpiredError
|
||||
from flask.ext.security.signals import password_reset_requested
|
||||
from flask.ext.security.signals import password_reset, \
|
||||
password_reset_requested, confirm_instructions_sent
|
||||
from flask.ext.security.utils import generate_token, send_mail
|
||||
from werkzeug.local import LocalProxy
|
||||
|
||||
security = LocalProxy(lambda: current_app.security)
|
||||
|
||||
logger = LocalProxy(lambda: current_app.logger)
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ def send_reset_password_instructions(user):
|
||||
'reset_instructions',
|
||||
dict(user=user, reset_link=reset_link))
|
||||
|
||||
confirm_instructions_sent.send(user, app=current_app._get_current_object())
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -75,6 +77,8 @@ def reset_by_token(token, email, password):
|
||||
|
||||
send_mail('Your password has been reset', user.email, 'reset_notice')
|
||||
|
||||
password_reset.send(user, app=current_app._get_current_object())
|
||||
|
||||
return user
|
||||
|
||||
|
||||
|
||||
@@ -4,4 +4,12 @@ signals = blinker.Namespace()
|
||||
|
||||
user_registered = signals.signal("user-registered")
|
||||
|
||||
user_confirmed = signals.signal("user-confirmed")
|
||||
|
||||
confirm_instructions_sent = signals.signal("confirm-instructions-sent")
|
||||
|
||||
password_reset = signals.signal("password-reset")
|
||||
|
||||
password_reset_requested = signals.signal("password-reset-requested")
|
||||
|
||||
reset_instructions_sent = signals.signal("reset-instructions-sent")
|
||||
|
||||
+33
-25
@@ -24,7 +24,7 @@ from werkzeug.local import LocalProxy
|
||||
|
||||
|
||||
security = LocalProxy(lambda: current_app.security)
|
||||
|
||||
datastore = LocalProxy(lambda: current_app.security.datastore)
|
||||
logger = LocalProxy(lambda: current_app.logger)
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ def authenticate():
|
||||
msg = 'Unknown authentication error'
|
||||
|
||||
do_flash(msg, 'error')
|
||||
|
||||
logger.debug('Unsuccessful authentication attempt: %s' % msg)
|
||||
|
||||
return redirect(request.referrer or security.login_manager.login_view)
|
||||
@@ -81,10 +80,9 @@ def logout():
|
||||
identity=AnonymousIdentity())
|
||||
|
||||
logout_user()
|
||||
|
||||
logger.debug('User logged out')
|
||||
|
||||
return redirect(request.args.get('next', None) or \
|
||||
return redirect(request.args.get('next', None) or
|
||||
security.post_logout_view)
|
||||
|
||||
|
||||
@@ -99,24 +97,26 @@ def register():
|
||||
form = security.RegisterForm(csrf_enabled=not current_app.testing)
|
||||
|
||||
# Exit early if the form doesn't validate
|
||||
if not form.validate_on_submit():
|
||||
return redirect(request.referrer or security.register_url)
|
||||
if form.validate_on_submit():
|
||||
# Create user and send signal
|
||||
user = datastore.create_user(**form.to_dict())
|
||||
app = current_app._get_current_object()
|
||||
|
||||
# Create user and send signal
|
||||
user = security.datastore.create_user(**form.to_dict())
|
||||
user_registered.send(user, app=current_app._get_current_object())
|
||||
user_registered.send(user, app=app)
|
||||
|
||||
# Send confirmation instructions if necessary
|
||||
if security.confirm_email:
|
||||
send_confirmation_instructions(user)
|
||||
# Send confirmation instructions if necessary
|
||||
if security.confirm_email:
|
||||
send_confirmation_instructions(user)
|
||||
|
||||
logger.debug('User %s registered' % user)
|
||||
logger.debug('User %s registered' % user)
|
||||
|
||||
# Login the user if allowed
|
||||
if (not security.confirm_email) or security.login_without_confirmation:
|
||||
_do_login(user)
|
||||
# Login the user if allowed
|
||||
if not security.confirm_email or security.login_without_confirmation:
|
||||
_do_login(user)
|
||||
|
||||
return redirect(security.post_register_view or security.post_login_view)
|
||||
return redirect(security.post_register_view or security.post_login_view)
|
||||
|
||||
return redirect(request.referrer or security.register_url)
|
||||
|
||||
|
||||
def confirm():
|
||||
@@ -140,7 +140,6 @@ def confirm():
|
||||
security.confirm_email_within_text, e.user.email)
|
||||
|
||||
do_flash(msg, 'error')
|
||||
|
||||
return redirect('/') # TODO: Don't redirect to root
|
||||
|
||||
logger.debug('User %s confirmed' % user)
|
||||
@@ -150,35 +149,44 @@ def confirm():
|
||||
|
||||
|
||||
def forgot():
|
||||
"""View function that handles the generation of a password reset token.
|
||||
"""
|
||||
|
||||
form = security.ForgotPasswordForm(csrf_enabled=not current_app.testing)
|
||||
|
||||
if form.validate_on_submit():
|
||||
try:
|
||||
user = security.datastore.find_user(email=form.email.data)
|
||||
user = datastore.find_user(**form.to_dict())
|
||||
|
||||
reset_password_reset_token(user)
|
||||
do_flash('Instructions to reset your password have been sent to %s' % user.email, 'success')
|
||||
|
||||
do_flash('Instructions to reset your password have been '
|
||||
'sent to %s' % user.email, 'success')
|
||||
|
||||
except UserNotFoundError:
|
||||
do_flash('The email you provided could not be found', 'error')
|
||||
|
||||
return redirect(security.post_forgot_view)
|
||||
|
||||
return render_template('security/passwords/new.html', forgot_password_form=form)
|
||||
return render_template('security/passwords/new.html',
|
||||
forgot_password_form=form)
|
||||
|
||||
|
||||
def reset():
|
||||
"""View function that handles the reset of a user's password.
|
||||
"""
|
||||
|
||||
form = security.ResetPasswordForm(csrf_enabled=not current_app.testing)
|
||||
|
||||
if form.validate_on_submit():
|
||||
try:
|
||||
reset_by_token(token=form.reset_password_token.data,
|
||||
email=form.email.data,
|
||||
password=form.password.data)
|
||||
reset_by_token(**form.to_dict())
|
||||
|
||||
except ResetPasswordError, e:
|
||||
do_flash(str(e), 'error')
|
||||
|
||||
except TokenExpiredError, e:
|
||||
do_flash('You did not reset your password within %s.' % security.reset_password_within_text)
|
||||
do_flash('You did not reset your password within'
|
||||
'%s.' % security.reset_password_within_text)
|
||||
|
||||
return redirect(request.referrer or security.reset_password_error_view)
|
||||
|
||||
@@ -236,7 +236,7 @@ class RecoverableTests(SecurityTest):
|
||||
|
||||
r = self.client.post('/reset', data={
|
||||
'email': u.email,
|
||||
'reset_password_token': u.reset_password_token,
|
||||
'token': u.reset_password_token,
|
||||
'password': 'newpassword',
|
||||
'password_confirm': 'newpassword'
|
||||
})
|
||||
@@ -251,7 +251,7 @@ class RecoverableTests(SecurityTest):
|
||||
|
||||
data = {
|
||||
'email': u.email,
|
||||
'reset_password_token': u.reset_password_token,
|
||||
'token': u.reset_password_token,
|
||||
'password': 'newpassword',
|
||||
'password_confirm': 'newpassword'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user