Compare commits

..
19 Commits
Author SHA1 Message Date
Matt Wright 0f46f35981 Bump version number to 1.6.7 2013-07-11 14:58:46 -04:00
Matt Wright c0d9eecf10 Set release date. 2013-07-11 14:58:36 -04:00
Matt Wright 04bb2c4041 Update CHANGES 2013-07-11 14:54:22 -04:00
Matt Wright 8eeb832d2e Conditionally logout the current user when confirming an email address to prevent unnecessary code/signals to be fired. Fixes #133 2013-07-11 14:50:21 -04:00
Matt Wright 8f760aadbd Merge pull request #134 from rxl/email_confirmation_fix
Email confirmation fix
2013-07-11 11:21:05 -07:00
rxl 03d27cd600 add logout_user() to the beginning of confirm_email() 2013-07-11 14:14:50 -04:00
rxl d30a27b3bb remove '@anonymous_user_required' from confirm_email() 2013-07-11 14:14:28 -04:00
Matt Wright 78903fa2e5 Make password length message configurable. 2013-07-02 10:36:22 -04:00
Matt Wright 514de64303 Bump version number to 1.6.6 2013-06-28 17:24:50 -04:00
Matt Wright bad63265f8 Update CHANGES 2013-06-28 17:24:40 -04:00
Matt Wright 66a9dcd2e6 Merge branch 'develop' of github.com:mattupstate/flask-security into develop 2013-06-28 17:23:36 -04:00
Matt Wright df1647f1f9 Fix install_requires in setup.py 2013-06-28 17:23:16 -04:00
Matt Wright 89ecded480 Merge pull request #128 from vkotovv/develop
Fix issue tracker link
2013-06-26 08:04:10 -07:00
Vadim Kotov 2b35b37a66 Update sidebarintro.html
Fixed link to the issue tracker
2013-06-26 18:30:44 +04:00
Matt Wright 4d8a813004 Bump version number to 1.6.5 2013-06-20 16:01:36 -04:00
Matt Wright 06312ef50f Fix typo with _external parameter in confirmable.py. Fixes #126 2013-06-20 16:01:22 -04:00
Matt Wright c3ad5b2fa6 Take --use-mirrors out of pip calls in .travis.yml 2013-06-18 15:53:32 -04:00
Matt Wright 637fc913cd Take Flask-Mail out of .travis.yml 2013-06-18 15:32:32 -04:00
Matt Wright e00522f331 Add SECURITY_CHANGEABLE to docs. Fixes #115 2013-06-18 15:05:32 -04:00
12 changed files with 67 additions and 19 deletions
+2 -2
View File
@@ -6,9 +6,9 @@ python:
- "pypy" - "pypy"
install: install:
- pip install . --quiet --use-mirrors - pip install . --quiet
- "if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install importlib --quiet --use-mirrors; fi" - "if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install importlib --quiet --use-mirrors; fi"
- pip install nose simplejson Flask-SQLAlchemy Flask-MongoEngine Flask-Peewee Flask-Mail py-bcrypt MySQL-python --quiet --use-mirrors - pip install nose simplejson Flask-SQLAlchemy Flask-MongoEngine Flask-Peewee py-bcrypt MySQL-python --quiet
before_script: before_script:
- mysql -e 'create database flask_security_test;' - mysql -e 'create database flask_security_test;'
+24
View File
@@ -3,6 +3,30 @@ 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.7
-------------
Released July 11th 2013
- Made password length form error message configurable
- Fixed email confirmation bug that prevented logged in users from confirming their email
Version 1.6.6
-------------
Released June 28th 2013
- Fixed dependency versions
Version 1.6.5
-------------
Released June 20th 2013
- Fixed bug in `flask.ext.security.confirmable.generate_confirmation_link`
Version 1.6.4 Version 1.6.4
------------- -------------
+1 -1
View File
@@ -9,7 +9,7 @@
<ul> <ul>
<li><a href="http://pypi.python.org/pypi/Flask-Security">Flask-Security @ PyPI</a></li> <li><a href="http://pypi.python.org/pypi/Flask-Security">Flask-Security @ PyPI</a></li>
<li><a href="http://github.com/mattupstate/flask-security">Flask-Security @ github</a></li> <li><a href="http://github.com/mattupstate/flask-security">Flask-Security @ github</a></li>
<li><a href="http://github.com/jfinkels/flask-security/issues">Issue Tracker</a></li> <li><a href="http://github.com/mattupstate/flask-security/issues">Issue Tracker</a></li>
</ul> </ul>
<ul> <ul>
<li><a href="http://pypi.python.org/pypi/Flask-Social">Flask-Social</a></li> <li><a href="http://pypi.python.org/pypi/Flask-Social">Flask-Social</a></li>
+1 -1
View File
@@ -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.4' version = '1.6.7'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = version release = version
+4
View File
@@ -156,6 +156,10 @@ Feature Flags
sent an email with a login link. This feature is sent an email with a login link. This feature is
experimental and should be used with caution. Defaults experimental and should be used with caution. Defaults
to ``False``. to ``False``.
``SECURITY_CHANGEABLE`` Specifies if Flask-Security should enable the
change password endpoint. The URL for this endpoint is
specified by the ``SECURITY_CHANGE_URL`` configuration
option. Defaults to ``False``.
========================= ====================================================== ========================= ======================================================
Email Email
+1 -1
View File
@@ -10,7 +10,7 @@
:license: MIT, see LICENSE for more details. :license: MIT, see LICENSE for more details.
""" """
__version__ = '1.6.4' __version__ = '1.6.7'
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
+1 -1
View File
@@ -27,7 +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)
return url_for_security('confirm_email', token=token, _extenal=True), token return url_for_security('confirm_email', token=token, _external=True), token
def send_confirmation_instructions(user): def send_confirmation_instructions(user):
+1
View File
@@ -110,6 +110,7 @@ _default_messages = {
'EMAIL_NOT_PROVIDED': ('Email not provided', 'error'), 'EMAIL_NOT_PROVIDED': ('Email not provided', 'error'),
'INVALID_EMAIL_ADDRESS': ('Invalid email address', 'error'), 'INVALID_EMAIL_ADDRESS': ('Invalid email address', 'error'),
'PASSWORD_NOT_PROVIDED': ('Password not provided', 'error'), 'PASSWORD_NOT_PROVIDED': ('Password not provided', 'error'),
'PASSWORD_INVALID_LENGTH': ('Password must be at least 6 characters', 'error'),
'USER_DOES_NOT_EXIST': ('Specified user does not exist', 'error'), 'USER_DOES_NOT_EXIST': ('Specified user does not exist', 'error'),
'INVALID_PASSWORD': ('Invalid password', 'error'), 'INVALID_PASSWORD': ('Invalid password', 'error'),
'PASSWORDLESS_LOGIN_SUCCESSFUL': ('You have successfuly logged in.', 'success'), 'PASSWORDLESS_LOGIN_SUCCESSFUL': ('You have successfuly logged in.', 'success'),
+3 -4
View File
@@ -69,6 +69,7 @@ class Length(ValidatorMixin, wtf.Length):
email_required = Required(message='EMAIL_NOT_PROVIDED') email_required = Required(message='EMAIL_NOT_PROVIDED')
email_validator = Email(message='INVALID_EMAIL_ADDRESS') email_validator = Email(message='INVALID_EMAIL_ADDRESS')
password_required = Required(message='PASSWORD_NOT_PROVIDED') password_required = Required(message='PASSWORD_NOT_PROVIDED')
password_length = Length(min=6, max=128, message='PASSWORD_INVALID_LENGTH')
def get_form_field_label(key): def get_form_field_label(key):
@@ -122,8 +123,7 @@ class PasswordFormMixin():
class NewPasswordFormMixin(): class NewPasswordFormMixin():
password = PasswordField(get_form_field_label('password'), password = PasswordField(get_form_field_label('password'),
validators=[password_required, validators=[password_required, password_length])
Length(min=6, max=128)])
class PasswordConfirmFormMixin(): class PasswordConfirmFormMixin():
@@ -256,8 +256,7 @@ class ChangePasswordForm(Form, PasswordFormMixin):
"""The default change password form""" """The default change password form"""
new_password = PasswordField(get_form_field_label('new_password'), new_password = PasswordField(get_form_field_label('new_password'),
validators=[password_required, validators=[password_required, password_length])
Length(min=6, max=128)])
new_password_confirm = PasswordField(get_form_field_label('retype_password'), new_password_confirm = PasswordField(get_form_field_label('retype_password'),
validators=[EqualTo('new_password', message='RETYPE_PASSWORD_MISMATCH')]) validators=[EqualTo('new_password', message='RETYPE_PASSWORD_MISMATCH')])
+4 -2
View File
@@ -200,7 +200,6 @@ def send_confirmation():
**_ctx('send_confirmation')) **_ctx('send_confirmation'))
@anonymous_user_required
def confirm_email(token): def confirm_email(token):
"""View function which handles a email confirmation request.""" """View function which handles a email confirmation request."""
@@ -217,8 +216,11 @@ def confirm_email(token):
return redirect(get_url(_security.confirm_error_view) or return redirect(get_url(_security.confirm_error_view) or
url_for('send_confirmation')) url_for('send_confirmation'))
if user != current_user:
logout_user()
login_user(user)
confirm_user(user) confirm_user(user)
login_user(user)
after_this_request(_commit) after_this_request(_commit)
do_flash(*get_message('EMAIL_CONFIRMED')) do_flash(*get_message('EMAIL_CONFIRMED'))
+5 -5
View File
@@ -20,7 +20,7 @@ from setuptools import setup
setup( setup(
name='Flask-Security', name='Flask-Security',
version='1.6.4', version='1.6.7',
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.2.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',
], ],
+19 -1
View File
@@ -336,6 +336,24 @@ class LoginWithoutImmediateConfirmTests(SecurityTest):
r = self._post('/register', data=data, follow_redirects=True) r = self._post('/register', data=data, follow_redirects=True)
self.assertIn(e, r.data) self.assertIn(e, r.data)
def test_confirm_email_of_user_different_than_current_user(self):
e1 = 'dude@lp.com'
e2 = 'lady@lp.com'
with capture_registrations() as registrations:
self.register(e1)
self.register(e2)
token1 = registrations[0]['confirm_token']
token2 = registrations[1]['confirm_token']
self.client.get('/confirm/' + token1, follow_redirects=True)
self.client.get('/logout')
self.authenticate(email=e1)
r = self.client.get('/confirm/' + token2, follow_redirects=True)
msg = self.app.config['SECURITY_MSG_EMAIL_CONFIRMED'][0]
self.assertIn(msg, r.data)
self.assertIn('Hello %s' % e2, r.data)
class RecoverableTests(SecurityTest): class RecoverableTests(SecurityTest):
@@ -459,7 +477,7 @@ class ChangePasswordTest(SecurityTest):
'new_password_confirm': 'a' 'new_password_confirm': 'a'
}, follow_redirects=True) }, follow_redirects=True)
self.assertNotIn('You successfully changed your password', r.data) self.assertNotIn('You successfully changed your password', r.data)
self.assertIn('Field must be between', r.data) self.assertIn('Password must be at least 6 characters', r.data)
def test_change_password_success(self): def test_change_password_success(self):
self.authenticate() self.authenticate()