diff --git a/example/app.py b/example/app.py index 9d5d285..1d7b596 100644 --- a/example/app.py +++ b/example/app.py @@ -41,6 +41,38 @@ def populate_data(): create_users() +def add_ctx_processors(app): + s = app.security + + @s.context_processor + def for_all(): + return dict() + + @s.forgot_password_context_processor + def forgot_password(): + return dict() + + @s.login_context_processor + def login(): + return dict() + + @s.register_context_processor + def register(): + return dict() + + @s.reset_password_context_processor + def reset_password(): + return dict() + + @s.send_confirmation_context_processor + def send_confirmation(): + return dict() + + @s.send_login_context_processor + def send_login(): + return dict() + + def create_app(auth_config): app = Flask(__name__) app.debug = True @@ -192,6 +224,8 @@ def create_sqlalchemy_app(auth_config=None, register_blueprint=True): db.create_all() populate_data() + add_ctx_processors(app) + return app @@ -228,6 +262,8 @@ def create_mongoengine_app(auth_config=None): Role.drop_collection() populate_data() + add_ctx_processors(app) + return app if __name__ == '__main__': diff --git a/flask_security/core.py b/flask_security/core.py index 19dc343..b548b29 100644 --- a/flask_security/core.py +++ b/flask_security/core.py @@ -219,6 +219,49 @@ class _SecurityState(object): for key, value in kwargs.items(): setattr(self, key.lower(), value) + def _add_ctx_processor(self, endpoint, fn): + c = self.context_processors + + if endpoint not in c: + c[endpoint] = [] + + if fn not in c[endpoint]: + c[endpoint].append(fn) + + def _run_ctx_processor(self, endpoint): + fns = [] + rv = {} + + for g in ['all', endpoint]: + if g in self.context_processors: + fns += self.context_processors[g] + + for fn in fns: + rv.update(fn()) + + return rv + + def context_processor(self, fn): + self._add_ctx_processor('all', fn) + + def forgot_password_context_processor(self, fn): + self._add_ctx_processor('forgot_password', fn) + + def login_context_processor(self, fn): + self._add_ctx_processor('login', fn) + + def register_context_processor(self, fn): + self._add_ctx_processor('register', fn) + + def reset_password_context_processor(self, fn): + self._add_ctx_processor('reset_password', fn) + + def send_confirmation_context_processor(self, fn): + self._add_ctx_processor('send_confirmation', fn) + + def send_login_context_processor(self, fn): + self._add_ctx_processor('send_login', fn) + class Security(object): """The :class:`Security` class initializes the Flask-Security extension. @@ -286,6 +329,8 @@ class Security(object): ('token_auth_serializer', _get_token_auth_serializer(app))]: kwargs[key] = value + kwargs['context_processors'] = {} + kwargs['login_serializer'] = ( _get_login_serializer(app) if kwargs['passwordless'] else None) diff --git a/flask_security/templates/security/reset_password.html b/flask_security/templates/security/reset_password.html index b383df0..0adcad8 100644 --- a/flask_security/templates/security/reset_password.html +++ b/flask_security/templates/security/reset_password.html @@ -1,7 +1,7 @@ {% from "security/_macros.html" import render_field_with_errors, render_field %} {% include "security/_messages.html" %}