diff --git a/.travis.yml b/.travis.yml
index 5d1f570a..d59e8bf9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -61,7 +61,7 @@ deploy:
secure: xzhkM+54+dmI7aFxWdMxTkHcMfOzuAxcGOpBanY367MyETtmNZUQx1VAQh5381UHiQ0+mg433srWrR4V1h0tsSB31KZAPazeh44zxpJRCv9b5Fx+46PmYW6ZpY8+vqUpFrKCcaLX5ZmEf62xXY3cvMbp0ubAURiV6N+hHyuH90w+3xucrSnFOuVHVuI3Eqp5Bz6zxEKscrIaZiT9CPh0F2jBpGZT8qXCYT1N8xeyH0SCszvKsIIoaPitpQDnoSkBfy6VHiNU6Tznseer6uLzrW80ynKu5mZwjT4mGT0j/rBUcbIpAYHajnsHXL27Gu32mli7beOkgd2vEpb14x5JygkPoYoUnSJlwhRUgAkNZVR5teNOcP87wU6ZAdv1jhfuQA/NUUpZucVpzASojAxf2996krT4hjYz7KJ2z5lSOww016EZ5mxyktGF23KXH9zrCWUv24r1K9JOUH+6OuQHFF40q1YiL2ro63raUdLm/Y3DLgeO6oDXZPMI2DFdRFCSpY2sGI6ZBrU89MuCJhju5Y838hOWQS330UcA71MpcsnmSZDsJ9o+Rrty6wowOdMqx4bmrm0G8ILNK4MosO7KwXZUMj/iV4SLUQjhBLhOTS+vLO8sa7PCZssK7z8C+378Y4Q+hrfsctCCGVBgRhuIr5KSLtKeD3bObQ/4VfIdK9E=
distributions: "compile_catalog sdist bdist_wheel"
on:
- repo: inveniosoftware/flask-security-fork
+ repo: mattupstate/flask-security
tags: true
python: "2.7"
condition: $REQUIREMENTS = release
diff --git a/CHANGES b/CHANGES
index 82a53d95..50d52f4d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,24 +1,18 @@
-Flask-Security-Fork Changelog
-=============================
+Flask-Security Changelog
+========================
-Here you can see the full list of changes between each Flask-Security-Fork release.
+Here you can see the full list of changes between each Flask-Security release.
-Version 2.0.1
+Version 3.0.0
-------------
-Released January 18th 2017
+Released TBD
- Added options `SECURITY_EMAIL_PLAINTEXT` and `SECURITY_EMAIL_HTML`
for sending respecively plaintext and HTML version of email.
- Fixed validation when missing login information.
- Fixed condition for token extraction from JSON body.
- Better support for universal bdist wheel.
-
-Version 2.0.0
--------------
-
-Released January 11th 2017
-
- Added port of CLI using Click configurable using options
`SECURITY_CLI_USERS_NAME` and `SECURITY_CLI_ROLES_NAME`.
- Added new configuration option `SECURITY_DATETIME_FACTORY` which can
@@ -27,30 +21,12 @@ Released January 11th 2017
- Better IP tracking if using Flask 0.12.
- Renamed deprecated Flask-WFT base form class.
- Added tests for custom forms configured using app config.
-
-Version 1.8.2
--------------
-
-Released December 20th 2016
-
- Added validation and tests for next argument in logout endpoint. (see #499)
- Bumped minimal required versions of several packages.
- Extended test matric on Travis CI for minimal and released package versions.
- Added of .editorconfig and forced tests for code style.
-
-Version 1.8.1
--------------
-
-Released November 15th 2016
-
- Fixed a security bug when validating a confirmation token, also checks
if the email that the token was created with matches the user's current email.
-
-Version 1.8.0
--------------
-
-Released October 28th 2016
-
- Replaced token loader with request loader.
- Changed trackable behavior of `login_user` when IP can not be detected from a request from 'untrackable' to `None` value.
- Use ProxyFix instead of inspecting X-Forwarded-For header.
@@ -70,11 +46,6 @@ Released October 28th 2016
- Removed a duplicate line ('retype_password': 'Retype Password') in forms.py.
- Various documentation improvement.
-Flask-Security Changelog
-========================
-
-Here you can see the full list of changes between each Flask-Security release.
-
Version 1.7.5
-------------
diff --git a/README.rst b/README.rst
index 28243de3..443106fb 100644
--- a/README.rst
+++ b/README.rst
@@ -1,30 +1,28 @@
-Flask-Security-Fork
+Flask-Security
===================
-.. image:: https://img.shields.io/travis/inveniosoftware/flask-security-fork.svg
- :target: https://travis-ci.org/inveniosoftware/flask-security-fork
+.. image:: https://img.shields.io/travis/mattupstate/flask-security.svg
+ :target: https://travis-ci.org/mattupstate/flask-security
-.. image:: https://img.shields.io/coveralls/inveniosoftware/flask-security-fork.svg
- :target: https://coveralls.io/r/inveniosoftware/flask-security-fork
+.. image:: https://img.shields.io/coveralls/mattupstate/flask-security.svg
+ :target: https://coveralls.io/r/mattupstate/flask-security
-.. image:: https://img.shields.io/github/tag/inveniosoftware/flask-security-fork.svg
- :target: https://github.com/inveniosoftware/flask-security-fork/releases
+.. image:: https://img.shields.io/github/tag/mattupstate/flask-security.svg
+ :target: https://github.com/mattupstate/flask-security/releases
-.. image:: https://img.shields.io/pypi/dm/flask-security-fork.svg
- :target: https://pypi.python.org/pypi/flask-security-fork
+.. image:: https://img.shields.io/pypi/dm/flask-security.svg
+ :target: https://pypi.python.org/pypi/flask-security
:alt: Downloads
-.. image:: https://img.shields.io/github/license/inveniosoftware/flask-security-fork.svg
- :target: https://github.com/inveniosoftware/flask-security-fork/blob/master/LICENSE
+.. image:: https://img.shields.io/github/license/mattupstate/flask-security.svg
+ :target: https://github.com/mattupstate/flask-security/blob/master/LICENSE
:alt: License
-This is a fork of the official Flask-Security extension.
-
It quickly adds security features to your Flask application.
Resources
---------
-- `Documentation `_
+- `Documentation `_
- `Issue Tracker `_
-- `Code `_
+- `Code `_
diff --git a/docs/conf.py b/docs/conf.py
index 7b53817c..84fa5310 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -100,7 +100,7 @@
# further. For a list of options available for each theme, see the
# documentation.
html_theme_options = {
- # 'github_fork': 'mattupstate/flask-security',
+ 'github_fork': 'mattupstate/flask-security',
# 'index_logo': False
'touch_icon': 'touch-icon.png',
'index_logo': 'logo-full.png'
diff --git a/docs/features.rst b/docs/features.rst
index e28bea2f..1b427682 100644
--- a/docs/features.rst
+++ b/docs/features.rst
@@ -129,8 +129,8 @@ Run ``flask --help`` and look for users and roles.
.. _Click: http://packages.python.org/Click/
-.. _Flask-Login: http://packages.python.org/Flask-Login/
-.. _alternative token: http://packages.python.org/Flask-Login/#alternative-tokens
+.. _Flask-Login: https://flask-login.readthedocs.org/en/latest/
+.. _alternative token: https://flask-login.readthedocs.io/en/latest/#alternative-tokens
.. _Flask-Principal: http://packages.python.org/Flask-Principal/
.. _documentation on this topic: http://packages.python.org/Flask-Principal/#granular-resource-protection
.. _passlib: http://packages.python.org/passlib/
diff --git a/docs/index.rst b/docs/index.rst
index 3c1633c6..585908fa 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -18,7 +18,7 @@ Flask application. They include:
Many of these features are made possible by integrating various Flask extensions
and libraries. They include:
-1. `Flask-Login `_
+1. `Flask-Login `_
2. `Flask-Mail `_
3. `Flask-Principal `_
4. `Flask-WTF `_
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index a279be4e..2910e429 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -17,7 +17,7 @@ SQLAlchemy Install requirements
::
$ mkvirtualenv
- $ pip install flask-security-fork flask-sqlalchemy
+ $ pip install flask-security flask-sqlalchemy
SQLAlchemy Application
@@ -90,7 +90,7 @@ SQLAlchemy Install requirements
::
$ mkvirtualenv
- $ pip install flask-security-fork sqlalchemy
+ $ pip install flask-security sqlalchemy
Also, you can use the extension `Flask-SQLAlchemy-Session documentation
`_.
@@ -206,7 +206,7 @@ MongoEngine Install requirements
::
$ mkvirtualenv
- $ pip install flask-security-fork flask-mongoengine
+ $ pip install flask-security flask-mongoengine
MongoEngine Application
~~~~~~~~~~~~~~~~~~~~~~~
@@ -273,7 +273,7 @@ Peewee Install requirements
::
$ mkvirtualenv
- $ pip install flask-security-fork flask-peewee
+ $ pip install flask-security flask-peewee
Peewee Application
~~~~~~~~~~~~~~~~~~
diff --git a/flask_security/core.py b/flask_security/core.py
index 00133f5b..ccb81821 100644
--- a/flask_security/core.py
+++ b/flask_security/core.py
@@ -250,7 +250,7 @@ def _on_identity_loaded(sender, identity):
if hasattr(current_user, 'id'):
identity.provides.add(UserNeed(current_user.id))
- for role in current_user.roles:
+ for role in getattr(current_user, 'roles', []):
identity.provides.add(RoleNeed(role.name))
identity.user = current_user
diff --git a/flask_security/datastore.py b/flask_security/datastore.py
index 8b86b44b..f8ff7ac7 100644
--- a/flask_security/datastore.py
+++ b/flask_security/datastore.py
@@ -133,6 +133,13 @@ def _prepare_create_user_args(self, **kwargs):
kwargs['roles'] = roles
return kwargs
+ def _is_numeric(self, value):
+ try:
+ int(value)
+ except (TypeError, ValueError):
+ return False
+ return True
+
def get_user(self, id_or_email):
"""Returns a user matching the specified ID or email address."""
raise NotImplementedError
@@ -233,21 +240,15 @@ def __init__(self, db, user_model, role_model):
UserDatastore.__init__(self, user_model, role_model)
def get_user(self, identifier):
- if self._is_numeric(identifier):
- return self.user_model.query.get(identifier)
+ rv = self.user_model.query.get(identifier)
+ if rv is not None:
+ return rv
for attr in get_identity_attributes():
query = getattr(self.user_model, attr).ilike(identifier)
rv = self.user_model.query.filter(query).first()
if rv is not None:
return rv
- def _is_numeric(self, value):
- try:
- int(value)
- except (TypeError, ValueError):
- return False
- return True
-
def find_user(self, **kwargs):
return self.user_model.query.filter_by(**kwargs).first()
@@ -296,10 +297,13 @@ def get_user(self, identifier):
from mongoengine import ValidationError
try:
return self.user_model.objects(id=identifier).first()
- except ValidationError:
+ except (ValidationError, ValueError):
pass
+
+ is_numeric = self._is_numeric(identifier)
+
for attr in get_identity_attributes():
- query_key = '%s__iexact' % attr
+ query_key = attr if is_numeric else '%s__iexact' % attr
query = {query_key: identifier}
rv = self.user_model.objects(**query).first()
if rv is not None:
@@ -347,7 +351,7 @@ def __init__(self, db, user_model, role_model, role_link):
def get_user(self, identifier):
try:
return self.user_model.get(self.user_model.id == identifier)
- except ValueError:
+ except (self.user_model.DoesNotExist, ValueError):
pass
for attr in get_identity_attributes():
@@ -429,22 +433,21 @@ def __init__(self, db, user_model, role_model):
@with_pony_session
def get_user(self, identifier):
- if self._is_numeric(identifier):
+ from pony.orm.core import ObjectNotFound
+ try:
return self.user_model[identifier]
+ except (ObjectNotFound, ValueError):
+ pass
for attr in get_identity_attributes():
# this is a nightmare, tl;dr we need to get the thing that
# corresponds to email (usually)
- user = self.user_model.get(**{attr: identifier})
- if user is not None:
- return user
-
- def _is_numeric(self, value):
- try:
- int(value)
- except ValueError:
- return False
- return True
+ try:
+ user = self.user_model.get(**{attr: identifier})
+ if user is not None:
+ return user
+ except TypeError:
+ pass
@with_pony_session
def find_user(self, **kwargs):
diff --git a/flask_security/translations/da_DK/LC_MESSAGES/messages.po b/flask_security/translations/da_DK/LC_MESSAGES/flask_security.po
similarity index 100%
rename from flask_security/translations/da_DK/LC_MESSAGES/messages.po
rename to flask_security/translations/da_DK/LC_MESSAGES/flask_security.po
diff --git a/flask_security/translations/de_DE/LC_MESSAGES/flask_security.po b/flask_security/translations/de_DE/LC_MESSAGES/flask_security.po
new file mode 100644
index 00000000..64aaed7d
--- /dev/null
+++ b/flask_security/translations/de_DE/LC_MESSAGES/flask_security.po
@@ -0,0 +1,327 @@
+# German translation for Flask-Security (Du/Sie distinction has been avoided)
+# Copyright (C) 2017 ORGANIZATION
+# This file is distributed under the same license as the Flask-Security
+# project.
+# Ingo Kleiber , 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Flask-Security 2.0.1\n"
+"Report-Msgid-Bugs-To: info@inveniosoftware.org\n"
+"POT-Creation-Date: 2017-04-03 08:59+0200\n"
+"PO-Revision-Date: 2017-04-30 17:00+0200\n"
+"Last-Translator: Ingo Kleiber \n"
+"Language-Team: LANGUAGE \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 2.3.4\n"
+
+#: flask_security/core.py:98
+msgid "Login Required"
+msgstr "Login erforderlich"
+
+#: flask_security/core.py:99
+msgid "Welcome"
+msgstr "Willkommen"
+
+#: flask_security/core.py:100
+msgid "Please confirm your email"
+msgstr "Bitte E-Mail Adresse bestätigen"
+
+#: flask_security/core.py:101
+msgid "Login instructions"
+msgstr "Anmeldeinstruktionen"
+
+#: flask_security/core.py:102
+#: flask_security/templates/security/email/reset_notice.html:1
+msgid "Your password has been reset"
+msgstr "Das Passwort wurde zurückgesetzt"
+
+#: flask_security/core.py:103
+msgid "Your password has been changed"
+msgstr "Das Passwort wurde geändert"
+
+#: flask_security/core.py:105
+msgid "Password reset instructions"
+msgstr "Anleitung zur Passwortwiederherstellung"
+
+#: flask_security/core.py:131
+msgid "You do not have permission to view this resource."
+msgstr "Keine Berechtigung um diese Ressource zu sehen."
+
+#: flask_security/core.py:133
+#, python-format
+msgid "Thank you. Confirmation instructions have been sent to %(email)s."
+msgstr "Vielen Dank. Bestätigungsinstruktionen wurden an %(email)s gesendet."
+
+#: flask_security/core.py:137
+msgid "Thank you. Your email has been confirmed."
+msgstr "Vielen Dank. Die E-Mail Adresse wurde bestätigt."
+
+#: flask_security/core.py:139
+msgid "Your email has already been confirmed."
+msgstr "Die E-Mail Adresse wurde bereits bestätigt."
+
+#: flask_security/core.py:141
+msgid "Invalid confirmation token."
+msgstr "Ungültiger Bestätigungscode."
+
+#: flask_security/core.py:143
+#, python-format
+msgid "%(email)s is already associated with an account."
+msgstr "%(email)s is bereits mit einem Konto verknüpft."
+
+#: flask_security/core.py:145
+msgid "Password does not match"
+msgstr "Das Passwort stimmt nicht überein"
+
+#: flask_security/core.py:147
+msgid "Passwords do not match"
+msgstr "Die Passwörter stimmen nicht überein"
+
+#: flask_security/core.py:149
+msgid "Redirections outside the domain are forbidden"
+msgstr "Weiterleitungen außerhalb der Domain sind verboten"
+
+#: flask_security/core.py:151
+#, python-format
+msgid "Instructions to reset your password have been sent to %(email)s."
+msgstr "Instruktionen um das Passwort wiederherzustellen wurden an $(email)s gesendet."
+
+#: flask_security/core.py:154
+#, python-format
+msgid ""
+"You did not reset your password within %(within)s. New instructions have"
+" been sent to %(email)s."
+msgstr ""
+"Das Passwort wurde nicht innerhab von %(within)s zurückgesetzt. Neue Instruktionen"
+" wurden an %(email)s gesendet."
+
+#: flask_security/core.py:157
+msgid "Invalid reset password token."
+msgstr "Ungültiger Passwortwiederherstellungscode."
+
+#: flask_security/core.py:159
+msgid "Email requires confirmation."
+msgstr "Die E-Mail Adresse muss bestätigt werden."
+
+#: flask_security/core.py:161
+#, python-format
+msgid "Confirmation instructions have been sent to %(email)s."
+msgstr "Bestätigungsinstruktionen wurden an %(email)s gesendet."
+
+#: flask_security/core.py:163
+#, python-format
+msgid ""
+"You did not confirm your email within %(within)s. New instructions to "
+"confirm your email have been sent to %(email)s."
+msgstr ""
+"Die E-Mail Adresse wurden nicht innerhalb von %(within)s bestätigt. Neue Instruktionen"
+" wurden an %(email)s gesendet."
+
+
+#: flask_security/core.py:167
+#, python-format
+msgid ""
+"You did not login within %(within)s. New instructions to login have been"
+" sent to %(email)s."
+msgstr ""
+"Die Anmeldung erfolgte nicht in %(within)s. Neue Instruktionen"
+" wurden an %(email)s gesendet."
+
+#: flask_security/core.py:170
+#, python-format
+msgid "Instructions to login have been sent to %(email)s."
+msgstr "Instruktionen zur Anmeldung wurden an %(email)s gesendet."
+
+#: flask_security/core.py:172
+msgid "Invalid login token."
+msgstr "Ungülter Anmeldecode."
+
+#: flask_security/core.py:174
+msgid "Account is disabled."
+msgstr "Konto ist deaktiviert."
+
+#: flask_security/core.py:176
+msgid "Email not provided"
+msgstr "Keine E-Mail Adresse angegeben"
+
+#: flask_security/core.py:178
+msgid "Invalid email address"
+msgstr "Ungültige E-Mail Adresse"
+
+#: flask_security/core.py:180
+msgid "Password not provided"
+msgstr "Kein Passwort angegeben"
+
+#: flask_security/core.py:182
+msgid "No password is set for this user"
+msgstr "Für diesen Benutzer ist kein Passwort gesetzt"
+
+#: flask_security/core.py:184
+msgid "Password must be at least 6 characters"
+msgstr "Das Passwort muss mindestens 6 Zeichen lang sein"
+
+#: flask_security/core.py:186
+msgid "Specified user does not exist"
+msgstr "Spezifizierter Benutzer existiert nicht"
+
+#: flask_security/core.py:188
+msgid "Invalid password"
+msgstr "Ungültiges Passwort"
+
+#: flask_security/core.py:190
+msgid "You have successfully logged in."
+msgstr "Die Anmeldung war erfolgreich."
+
+#: flask_security/core.py:192
+msgid "Forgot password?"
+msgstr "Passwort vergessen?"
+
+#: flask_security/core.py:194
+msgid ""
+"You successfully reset your password and you have been logged in "
+"automatically."
+msgstr ""
+"Das Passwort wurde erfolgreich wiederhergestellt und der Login"
+" erfolgte automatisch."
+
+#: flask_security/core.py:197
+msgid "Your new password must be different than your previous password."
+msgstr "Das neue Passwort muss sich vom vorherigen unterscheiden."
+
+#: flask_security/core.py:200
+msgid "You successfully changed your password."
+msgstr "Das Passwort wurde erfolgreich geändert."
+
+#: flask_security/core.py:202
+msgid "Please log in to access this page."
+msgstr "Bitte Anmelden um diese Seite zu sehen."
+
+#: flask_security/core.py:204
+msgid "Please reauthenticate to access this page."
+msgstr "Bitte neu authentifizieren um auf diese Seite zuzugreifen."
+
+#: flask_security/forms.py:31
+msgid "Email Address"
+msgstr "E-Mail Adresse"
+
+#: flask_security/forms.py:32
+msgid "Password"
+msgstr "Passwort"
+
+#: flask_security/forms.py:33
+msgid "Remember Me"
+msgstr "Erinnern"
+
+#: flask_security/forms.py:34 flask_security/templates/security/_menu.html:4
+#: flask_security/templates/security/login_user.html:3
+#: flask_security/templates/security/send_login.html:3
+msgid "Login"
+msgstr "Anmelden"
+
+#: flask_security/forms.py:35 flask_security/templates/security/_menu.html:6
+#: flask_security/templates/security/register_user.html:3
+msgid "Register"
+msgstr "Registrieren"
+
+#: flask_security/forms.py:36
+msgid "Resend Confirmation Instructions"
+msgstr "Bestätigungsinstruktionen neu senden"
+
+#: flask_security/forms.py:37
+msgid "Recover Password"
+msgstr "Passwort wiederherstellen"
+
+#: flask_security/forms.py:38
+msgid "Reset Password"
+msgstr "Passwort zurücksetzen"
+
+#: flask_security/forms.py:39
+msgid "Retype Password"
+msgstr "Passwort neu eingeben"
+
+#: flask_security/forms.py:40
+msgid "New Password"
+msgstr "Neues Passwort"
+
+#: flask_security/forms.py:41
+msgid "Change Password"
+msgstr "Passwort ändern"
+
+#: flask_security/forms.py:42
+msgid "Send Login Link"
+msgstr "Login-Link versenden"
+
+#: flask_security/templates/security/_menu.html:2
+msgid "Menu"
+msgstr "Menü"
+
+#: flask_security/templates/security/_menu.html:9
+msgid "Forgot password"
+msgstr "Passwort vergessen"
+
+#: flask_security/templates/security/_menu.html:12
+msgid "Confirm account"
+msgstr "Konto bestätigen"
+
+#: flask_security/templates/security/change_password.html:3
+msgid "Change password"
+msgstr "Passwort ändern"
+
+#: flask_security/templates/security/forgot_password.html:3
+msgid "Send password reset instructions"
+msgstr "Senden von Instruktionen zur Passwortzurücksetzung"
+
+#: flask_security/templates/security/reset_password.html:3
+msgid "Reset password"
+msgstr "Passwort zurücksetzen"
+
+#: flask_security/templates/security/send_confirmation.html:3
+msgid "Resend confirmation instructions"
+msgstr "Bestätigungsinstruktionen erneut versenden"
+
+#: flask_security/templates/security/email/change_notice.html:1
+msgid "Your password has been changed."
+msgstr "Das Passwort wurde geändert."
+
+#: flask_security/templates/security/email/change_notice.html:3
+msgid "If you did not change your password,"
+msgstr "Falls das Passwort nicht geändert wurde"
+
+#: flask_security/templates/security/email/change_notice.html:3
+msgid "click here to reset it"
+msgstr "hier klicken um es zurückzusetzen"
+
+#: flask_security/templates/security/email/confirmation_instructions.html:1
+msgid "Please confirm your email through the link below:"
+msgstr "Bitte die E-Mail Adresse durch den Link unten bestätigen:"
+
+#: flask_security/templates/security/email/confirmation_instructions.html:3
+#: flask_security/templates/security/email/welcome.html:6
+msgid "Confirm my account"
+msgstr "Den Account bestätigen"
+
+#: flask_security/templates/security/email/login_instructions.html:1
+#: flask_security/templates/security/email/welcome.html:1
+#, python-format
+msgid "Welcome %(email)s!"
+msgstr "Willkommen %(email)s!"
+
+#: flask_security/templates/security/email/login_instructions.html:3
+msgid "You can log into your through the link below:"
+msgstr "Die Anmeldung kann über den Link unten erfolgen:"
+
+#: flask_security/templates/security/email/login_instructions.html:5
+msgid "Login now"
+msgstr "Jetzt anmelden"
+
+#: flask_security/templates/security/email/reset_instructions.html:1
+msgid "Click here to reset your password"
+msgstr "Hier klicken um das Passwort zurückzusetzen"
+
+#: flask_security/templates/security/email/welcome.html:4
+msgid "You can confirm your email through the link below:"
+msgstr "Die E-Mail Adresse kann über den Link unten bestätigt werden"
+
diff --git a/flask_security/translations/flask_security.pot b/flask_security/translations/flask_security.pot
index 33c198aa..f8679fb0 100644
--- a/flask_security/translations/flask_security.pot
+++ b/flask_security/translations/flask_security.pot
@@ -1,13 +1,13 @@
-# Translations template for Flask-Security-Fork.
+# Translations template for Flask-Security.
# Copyright (C) 2017 CERN
-# This file is distributed under the same license as the Flask-Security-Fork
+# This file is distributed under the same license as the Flask-Security
# project.
# FIRST AUTHOR , 2017.
#
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: Flask-Security-Fork 2.0.1\n"
+"Project-Id-Version: Flask-Security 2.0.1\n"
"Report-Msgid-Bugs-To: info@inveniosoftware.org\n"
"POT-Creation-Date: 2017-04-03 08:59+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
diff --git a/flask_security/translations/ru_RU/LC_MESSAGES/messages.po b/flask_security/translations/ru_RU/LC_MESSAGES/flask_security.po
similarity index 99%
rename from flask_security/translations/ru_RU/LC_MESSAGES/messages.po
rename to flask_security/translations/ru_RU/LC_MESSAGES/flask_security.po
index 5d88faec..467cc2c3 100644
--- a/flask_security/translations/ru_RU/LC_MESSAGES/messages.po
+++ b/flask_security/translations/ru_RU/LC_MESSAGES/flask_security.po
@@ -1,12 +1,12 @@
-# Russian Translations for Flask-Security-Fork.
+# Russian Translations for Flask-Security.
# Copyright (C) 2017 CERN, leovp
-# This file is distributed under the same license as the Flask-Security-Fork
+# This file is distributed under the same license as the Flask-Security
# project.
# FIRST AUTHOR , 2017.
#
msgid ""
msgstr ""
-"Project-Id-Version: Flask-Security-Fork 2.0.1\n"
+"Project-Id-Version: Flask-Security 2.0.1\n"
"Report-Msgid-Bugs-To: info@inveniosoftware.org\n"
"POT-Creation-Date: 2017-04-15 12:38+0300\n"
"PO-Revision-Date: 2017-04-15 15:15+0300\n"
diff --git a/flask_security/utils.py b/flask_security/utils.py
index 3f994030..5e417981 100644
--- a/flask_security/utils.py
+++ b/flask_security/utils.py
@@ -135,7 +135,7 @@ def verify_password(password, password_hash):
:param password_hash: The expected hash value of the password
(usually from your database)
"""
- if use_double_hash():
+ if use_double_hash(password_hash):
password = get_hmac(password)
return _pwd_context.verify(password, password_hash)
@@ -150,11 +150,8 @@ def verify_and_update_password(password, user):
:param password: A plaintext password to verify
:param user: The user to verify against
"""
- if use_double_hash():
- verified = (
- _pwd_context.verify(get_hmac(password), user.password) or
- _pwd_context.verify(password, user.password)
- )
+ if use_double_hash(user.password):
+ verified = _pwd_context.verify(get_hmac(password), user.password)
else:
# Try with original password.
verified = _pwd_context.verify(password, user.password)
@@ -327,7 +324,7 @@ def strip_prefix(tup):
def get_message(key, **kwargs):
rv = config_value('MSG_' + key)
- return _security.i18n_domain.lazy_gettext(rv[0], **kwargs), rv[1]
+ return _security.i18n_domain.gettext(rv[0], **kwargs), rv[1]
def config_value(key, app=None, default=None):
@@ -441,13 +438,19 @@ def get_identity_attributes(app=None):
return attrs
-def use_double_hash():
+def use_double_hash(password_hash=None):
"""Return a bool indicating whether a password should be hashed twice."""
single_hash = config_value('PASSWORD_SINGLE_HASH')
if single_hash and _security.password_salt:
raise RuntimeError('You may not specify a salt with '
'SECURITY_PASSWORD_SINGLE_HASH')
- return not (_security.password_hash == 'plaintext' or single_hash)
+
+ if password_hash is None:
+ is_plaintext = _security.password_hash == 'plaintext'
+ else:
+ is_plaintext = _pwd_context.identify(password_hash) == 'plaintext'
+
+ return not (is_plaintext or single_hash)
@contextmanager
diff --git a/setup.cfg b/setup.cfg
index 9d4554da..415bc3ee 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -13,6 +13,7 @@ upload-dir = docs/_build/html
[compile_catalog]
directory = flask_security/translations/
+domain = flask_security
[extract_messages]
copyright_holder = CERN
@@ -22,9 +23,11 @@ output-file = flask_security/translations/flask_security.pot
add-comments = NOTE
[init_catalog]
+domain = flask_security
input-file = flask_security/translations/flask_security.pot
output-dir = flask_security/translations/
[update_catalog]
+domain = flask_security
input-file = flask_security/translations/flask_security.pot
output-dir = flask_security/translations/
diff --git a/setup.py b/setup.py
index 8ce4793d..2c1c33b2 100755
--- a/setup.py
+++ b/setup.py
@@ -58,7 +58,7 @@
packages = find_packages()
setup(
- name='Flask-Security-Fork',
+ name='Flask-Security',
version='2.0.1',
description=__doc__,
long_description=readme,
@@ -66,7 +66,7 @@
license='MIT',
author='Matt Wright',
author_email='matt@nobien.net',
- url='https://github.com/inveniosoftware/flask-security-fork',
+ url='https://github.com/mattupstate/flask-security',
packages=packages,
zip_safe=False,
include_package_data=True,
diff --git a/tests/conftest.py b/tests/conftest.py
index fcdf9261..cdababc8 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -156,6 +156,7 @@ class User(db.Document, UserMixin):
email = db.StringField(unique=True, max_length=255)
username = db.StringField(max_length=255)
password = db.StringField(required=False, max_length=255)
+ security_number = db.IntField(unique=True)
last_login_at = db.DateTimeField()
current_login_at = db.DateTimeField()
last_login_ip = db.StringField(max_length=100)
@@ -195,6 +196,7 @@ class Role(db.Model, RoleMixin):
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), unique=True)
+ security_number = db.Column(db.Integer, unique=True)
username = db.Column(db.String(255))
password = db.Column(db.String(255))
last_login_at = db.Column(db.DateTime())
@@ -255,6 +257,7 @@ class User(Base, UserMixin):
email = Column(String(255), unique=True)
username = Column(String(255))
password = Column(String(255))
+ security_number = Column(Integer, unique=True)
last_login_at = Column(DateTime())
current_login_at = Column(DateTime())
last_login_ip = Column(String(100))
@@ -296,6 +299,7 @@ class Role(db.Model, RoleMixin):
class User(db.Model, UserMixin):
email = TextField()
username = TextField()
+ security_number = IntegerField(null=True)
password = TextField(null=True)
last_login_at = DateTimeField(null=True)
current_login_at = DateTimeField(null=True)
@@ -338,6 +342,7 @@ class Role(db.Entity):
class User(db.Entity):
email = Required(str)
username = Optional(str)
+ security_number = Optional(int)
password = Optional(str, nullable=True)
last_login_at = Optional(datetime)
current_login_at = Optional(datetime)
diff --git a/tests/test_datastore.py b/tests/test_datastore.py
index e3c0ece9..d8ab0ecd 100644
--- a/tests/test_datastore.py
+++ b/tests/test_datastore.py
@@ -83,7 +83,8 @@ def test_activate_returns_false_if_already_true():
def test_get_user(app, datastore):
init_app_with_options(app, datastore, **{
- 'SECURITY_USER_IDENTITY_ATTRIBUTES': ('email', 'username')
+ 'SECURITY_USER_IDENTITY_ATTRIBUTES': ('email', 'username',
+ 'security_number')
})
with app.app_context():
@@ -98,6 +99,9 @@ def test_get_user(app, datastore):
user = datastore.get_user('matt')
assert user is not None
+ user = datastore.get_user(123456)
+ assert user is not None
+
def test_find_role(app, datastore):
init_app_with_options(app, datastore)
diff --git a/tests/utils.py b/tests/utils.py
index 8d7710a3..ebea02fc 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -48,12 +48,13 @@ def create_roles(ds):
def create_users(ds, count=None):
- users = [('matt@lp.com', 'matt', 'password', ['admin'], True),
- ('joe@lp.com', 'joe', 'password', ['editor'], True),
- ('dave@lp.com', 'dave', 'password', ['admin', 'editor'], True),
- ('jill@lp.com', 'jill', 'password', ['author'], True),
- ('tiya@lp.com', 'tiya', 'password', [], False),
- ('jess@lp.com', 'jess', None, [], True)]
+ users = [('matt@lp.com', 'matt', 'password', ['admin'], True, 123456),
+ ('joe@lp.com', 'joe', 'password', ['editor'], True, 234567),
+ ('dave@lp.com', 'dave', 'password', ['admin', 'editor'], True,
+ 345678),
+ ('jill@lp.com', 'jill', 'password', ['author'], True, 456789),
+ ('tiya@lp.com', 'tiya', 'password', [], False, 567890),
+ ('jess@lp.com', 'jess', None, [], True, 678901)]
count = count or len(users)
for u in users[:count]:
@@ -66,7 +67,8 @@ def create_users(ds, count=None):
email=u[0],
username=u[1],
password=pw,
- active=u[4])
+ active=u[4],
+ security_number=u[5])
ds.commit()
for role in roles:
ds.add_role_to_user(user, role)