Skip to content

Commit

Permalink
Merge branch 'develop' of git://github.com/mattupstate/flask-security…
Browse files Browse the repository at this point in the history
… into develop
  • Loading branch information
jwag956 committed Apr 26, 2019
2 parents 1f8cbb2 + a401fb4 commit 1f17330
Show file tree
Hide file tree
Showing 45 changed files with 2,279 additions and 161 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ Session.vim

.eggs/README.txt

#Idea
.idea
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ addons:
apt:
packages:
- libenchant-dev
- aspell-en
- aspell-da
- aspell-de
- aspell-es
- aspell-fr
- aspell-nl
- aspell-pt
- aspell-ru

matrix:
allow_failures:
Expand Down
53 changes: 52 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,62 @@ Flask-Security Changelog

Here you can see the full list of changes between each Flask-Security release.

Version 3.0.0
Version 3.1.0
-------------

Released TBD

Added:

- (#784) i18n: added Japanese translation (@kantorii)
- (#776) i18n: add Portuguese (Portugal) translation (@micael-grilo)
- (#796) i18n: added Chinese-Simple translation (@Steinkuo)
- (#779) Let User model specify password verification and update methods (@mklassen)
- (#748) i18n: configurable the dirname domain (@escudero)
- (#743) tests: improved translations checks (@jirikuncar)
- (#730) Customizable send_mail (@abulte)
- (#727) Docs for OAauth2-based custom login manager (@Jaza)
- (#717) Allow custom login_manager to be passed in to Flask-Security (@Jaza)
- (#703) Support application factory pattern, simplified keyword arguments (@briancappello)
- (#714) Make SECURITY_PASSWORD_SINGLE_HASH a list of scheme ignoring double hash (@noirbizarre)
- (#697) Add base template to security templates (@grihabor)
- (#691) Documentation/Quickstart: Fix SQLAlchemy app example for missing render method and adding salt (@KshitijKarthick)
- (#713) i18n: add brazilian portuguese translation (@dinorox)
- (#487) Use Security.render_template in mails too (@noirbizarre)
- (#679) Optimize DB accesses by using an SQL JOIN when retrieving a user. Make `roles` in user model query optimization "optional". (@nfvs)

Fixed:
- (#767) docs: fixed proxy import (@biomap)
- (#750) docs: add missing imports (@allanice001)
- (#747) Removed redundant `next` parameter from login_user.html (@rickwest)
- (#439) HTTP Auth now respects SECURITY_USER_IDENTITY_ATTRIBUTES (@pnpnpn)
- (#700) Anchor links in website are not working (@alemangui)
- (#722) password recovery confirmation on deleted user (@kesara)
- (#678) AttributeError: 'NoneType' object has no attribute 'password' (@alemangui, @kesara)
- (#662) bug: User is logged in automatically on email confimation. (@kesara)
- (#692) utils: fix incorrect email sender type (@switowski)
- (#685) Error with email sender (@williamcheng-web)
- (#675) Fix AttributeError in _request_loader (@sbagan)
- (#696) Fixed broken Click link (@williamhatcher)
- (#710) i18n: Spanish translation (@maukoquiroga)
- (#712) Improve German translation (@eseifert)
- (#357) bug: Avoid Timing Attack (@cancan101, fixed @cript0nauta (#676))
- (#693) Making sure we pass the sender address in send_mail() as a string (#695 by @ochronus)
- (#506) bug: WindowsError when running tests under Windows (@reambus in #683)
- (#681) bug: Error when request is JSON but a list rather than an object (#682 by @Morabaraba)
- (#670) bug: _get_unauthorized_view() results in a redirect loop if the referrer is the page we just came from (@nfvs in #671)
- (#669) Fix for Read the Docs. Builds and release dates. (@jirikuncar)
- (#660) `csrf_enabled` deprecation in flask-wtf fix. (@abulte)

Removed:
- (#664) Remove automatic login on email confirmation. (@kesara)


Version 3.0.0
-------------

Released May 29th 2017

- Fixed a bug when user clicking confirmation link after confirmation
and expiration causes confirmation email to resend. (see #556)
- Added support for I18N.
Expand Down
11 changes: 10 additions & 1 deletion docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Core
``SECURITY_URL_PREFIX`` Specifies the URL prefix for the
Flask-Security blueprint. Defaults to
``None``.
``SECURITY_SUBDOMAIN`` Specifies the subdomain for the
``SECURITY_SUBDOMAIN`` Specifies the subdomain for the
Flask-Security blueprint. Defaults to
``None``.
``SECURITY_FLASH_MESSAGES`` Specifies whether or not to flash
Expand All @@ -30,6 +30,10 @@ Core
``SECURITY_I18N_DOMAIN`` Specifies the name for domain
used for translations.
Defaults to ``flask_security``.
``SECURITY_I18N_DIRNAME`` Specifies the directory containing the
``MO`` files used for translations.
Defaults to
``[PATH_LIB]/flask_security/translations``.
``SECURITY_PASSWORD_HASH`` Specifies the password hash algorithm to
use when hashing passwords. Recommended
values for production systems are
Expand All @@ -46,6 +50,11 @@ Core
``SECURITY_PASSWORD_SALT``, and then
with a random salt. May be useful for
integrating with other applications.
It can also be a set of scheme that
should not be hashed twice.
Default to a list of known schemes
not working with double hashing
(`django_{digest}`, `plaintext`).
Defaults to ``False``.
``SECURITY_HASHING_SCHEMES`` List of algorithms used for
creating and validating tokens.
Expand Down
121 changes: 117 additions & 4 deletions docs/customizing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,12 @@ replacement class. This allows you to add extra fields to the
register form or override validators::

from flask_security.forms import RegisterForm
from wtforms import StringField
from wtforms.validators import DataRequired

class ExtendedRegisterForm(RegisterForm):
first_name = StringField('First Name', [Required()])
last_name = StringField('Last Name', [Required()])
first_name = StringField('First Name', [DataRequired()])
last_name = StringField('Last Name', [DataRequired()])

security = Security(app, user_datastore,
register_form=ExtendedRegisterForm)
Expand Down Expand Up @@ -161,7 +163,7 @@ decorator like so::
send_security_email.delay(msg)

If factory method is going to be used for initialization, use ``_SecurityState``
object returned by ``init_app`` method to initialize Celery tasks intead of using
object returned by ``init_app`` method to initialize Celery tasks instead of using
``security.send_mail_task`` directly like so::

from flask import Flask
Expand Down Expand Up @@ -192,7 +194,7 @@ object returned by ``init_app`` method to initialize Celery tasks intead of usin
def delay_flask_security_mail(msg):
send_flask_mail.delay(msg)

# A shortcurt.
# A shortcut.
security_ctx.send_mail_task(send_flask_mail.delay)

return app
Expand All @@ -211,3 +213,114 @@ Celery. The practical way with custom serialization may look like so::
html=msg.html)

.. _Celery: http://www.celeryproject.org/


Custom send_mail method
-----------------------

It's also possible to completely override the ``security.send_mail`` method to
implement your own logic.

For example, you might want to use an alternative email library like `Flask-Emails`:

from flask import Flask
from flask_security import Security, SQLAlchemyUserDatastore
from flask_emails import Message

security = Security()

def create_app(config):
"""Initialize Flask instance."""

app = Flask(__name__)
app.config.from_object(config)

def custom_send_mail(subject, recipient, template, **context):
ctx = ('security/email', template)
message = Message(
subject=subject,
html=_security.render_template('%s/%s.html' % ctx, **context))
message.send(mail_to=[recipient])
datastore = SQLAlchemyUserDatastore(db, User, Role)
security_ctx.send_mail = custom_send_mail

return app

.. note::

The above ``security.send_mail_task`` override will be useless if you
override the entire ``send_mail`` method.


Authorization with OAuth2
-------------------------

Flask-Security can be set up to co-operate with `Flask-OAuthlib`_,
by implementing a custom request loader that authorizes a user based
either on a `Bearer` token in the HTTP `Authorization` header, or on the
Flask-Security standard authorization logic::

from flask_oauthlib.provider import OAuth2Provider
from flask_security import AnonymousUser
from flask_security.core import (
_user_loader as _flask_security_user_loader,
_request_loader as _flask_security_request_loader)
from flask_security.utils import config_value as security_config_value

oauth = OAuth2Provider(app)

def _request_loader(request):
"""
Load user from OAuth2 Authentication header or using
Flask-Security's request loader.
"""
user = None

if hasattr(request, 'oauth'):
user = request.oauth.user
else:
# Need this try stmt in case oauthlib sometimes throws:
# AttributeError: dict object has no attribute startswith
try:
is_valid, oauth_request = oauth.verify_request(scopes=[])
if is_valid:
user = oauth_request.user
except AttributeError:
pass

if not user:
user = _flask_security_request_loader(request)

return user

def _get_login_manager(app, anonymous_user):
"""Prepare a login manager for Flask-Security to use."""
login_manager = LoginManager()

login_manager.anonymous_user = anonymous_user or AnonymousUser
login_manager.login_view = '{0}.login'.format(
security_config_value('BLUEPRINT_NAME', app=app))
login_manager.user_loader(_flask_security_user_loader)
login_manager.request_loader(_request_loader)

if security_config_value('FLASH_MESSAGES', app=app):
(login_manager.login_message,
login_manager.login_message_category) = (
security_config_value('MSG_LOGIN', app=app))
(login_manager.needs_refresh_message,
login_manager.needs_refresh_message_category) = (
security_config_value('MSG_REFRESH', app=app))
else:
login_manager.login_message = None
login_manager.needs_refresh_message = None

login_manager.init_app(app)
return login_manager

security = Security(
app, user_datastore,
login_manager=_get_login_manager(app, anonymous_user=None))


.. _Flask-OAuthlib: https://flask-oauthlib.readthedocs.io/
2 changes: 1 addition & 1 deletion docs/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ registered. They can be completely disabled or their names can be changed.
Run ``flask --help`` and look for users and roles.


.. _Click: http://packages.python.org/Click/
.. _Click: http://click.pocoo.org/
.. _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/
Expand Down
Loading

0 comments on commit 1f17330

Please sign in to comment.