Add already confirmed scenario. Let datastore work without a request context

This commit is contained in:
Matt Wright
2012-08-21 01:50:40 -04:00
parent f2d5028d7c
commit 828a973339
6 changed files with 29 additions and 13 deletions
+2 -1
View File
@@ -19,6 +19,7 @@ from flask.ext.security.datastore import SQLAlchemyUserDatastore, \
from flask.ext.security.decorators import http_auth_required, \
auth_token_required
from flask.ext.security.exceptions import RoleNotFoundError
from flask.ext.security.utils import encrypt_password
def create_roles():
@@ -34,7 +35,7 @@ def create_users():
('jill@lp.com', 'password', ['author'], True),
('tiya@lp.com', 'password', [], False)):
current_app.security.datastore.create_user(
email=u[0], password=u[1], roles=u[2], active=u[3])
email=u[0], password=encrypt_password(u[1]), roles=u[2], active=u[3])
current_app.security.datastore._commit()
+3 -1
View File
@@ -75,6 +75,7 @@ _default_messages = {
'EMAIL_CONFIRMED': ('Thank you. Your email has been confirmed.', 'success'),
'ALREADY_CONFIRMED': ('Your email has already been confirmed.', 'info'),
'INVALID_CONFIRMATION_TOKEN': ('Invalid confirmation token.', 'error'),
'ALREADY_CONFIRMED': ('This email has already been confirmed', 'info'),
'PASSWORD_RESET_REQUEST': ('Instructions to reset your password have been sent to %(email)s.', 'info'),
'PASSWORD_RESET_EXPIRED': ('You did not reset your password within %(within)s. New instructions have been sent to %(email)s.', 'error'),
'INVALID_RESET_PASSWORD_TOKEN': ('Invalid reset password token.', 'error'),
@@ -273,6 +274,7 @@ class Security(object):
:param app: The application.
:param datastore: An instance of a user datastore.
"""
datastore = datastore or self.datastore
for key, value in _default_config.items():
app.config.setdefault('SECURITY_' + key, value)
@@ -290,7 +292,7 @@ class Security(object):
template_folder='templates')
app.register_blueprint(bp)
state = self._get_state(app, datastore or self.datastore)
state = self._get_state(app, datastore)
app.extensions['security'] = state
+3 -7
View File
@@ -28,6 +28,9 @@ class UserDatastore(object):
:param user_model: A user model class definition
:param role_model: A role model class definition
"""
pwd_context = None
default_roles = []
def __init__(self, db, user_model, role_model):
self.db = db
self.user_model = user_model
@@ -82,7 +85,6 @@ class UserDatastore(object):
def _prepare_create_user_args(self, **kwargs):
kwargs.setdefault('active', True)
kwargs.setdefault('roles', _security.default_roles)
roles = kwargs.get('roles', [])
for i, role in enumerate(roles):
@@ -91,12 +93,6 @@ class UserDatastore(object):
roles[i] = self.find_role(rn)
kwargs['roles'] = roles
pwd_context = _security.pwd_context
pw = kwargs['password']
if not pwd_context.identify(pw):
pwd_hash = utils.encrypt_password(pw)
kwargs['password'] = pwd_hash
return kwargs
+2 -1
View File
@@ -129,7 +129,8 @@ class RegisterForm(Form,
submit = SubmitField("Register")
def to_dict(self):
return dict(email=self.email.data, password=self.password.data)
return dict(email=self.email.data,
password=self.password.data)
class ResetPasswordForm(Form,
+7 -3
View File
@@ -204,9 +204,13 @@ def send_confirmation():
if form.validate_on_submit():
user = _datastore.find_user(**form.to_dict())
send_confirmation_instructions(user)
_logger.debug('%s request confirmation instructions' % user)
do_flash(*get_message('CONFIRMATION_REQUEST', email=user.email))
if user.confirmed_at is None:
send_confirmation_instructions(user)
msg = get_message('CONFIRMATION_REQUEST', email=user.email)
_logger.debug('%s request confirmation instructions' % user)
else:
msg = get_message('ALREADY_CONFIRMED')
do_flash(*msg)
return render_template('security/send_confirmation.html',
reset_confirmation_form=form,
+12
View File
@@ -287,6 +287,18 @@ class ConfirmableTests(SecurityTest):
r = self.authenticate(email=e)
self.assertIn(self.get_message('CONFIRMATION_REQUIRED'), r.data)
def test_send_confirmation_of_already_confirmed_account(self):
e = 'dude@lp.com'
with capture_registrations() as registrations:
self.register(e)
token = registrations[0]['confirm_token']
self.client.get('/confirm/' + token, follow_redirects=True)
self.logout()
r = self.client.post('/confirm', data=dict(email=e))
self.assertIn(self.get_message('ALREADY_CONFIRMED'), r.data)
def test_register_sends_confirmation_email(self):
e = 'dude@lp.com'
with self.app.mail.record_messages() as outbox: