mirror of
https://github.com/Mailu/Mailu.git
synced 2024-12-14 10:53:30 +02:00
Lazy loading of KVSessionExtension
- call cleanup_sessions on first kvstore access this allows to run cmdline actions without redis (and makes it faster) - Allow development using DictStore by setting REDIS_ADDRESS to the empty string in env - don't sign 64bit random session id as suggested by nextgens
This commit is contained in:
parent
1fd7a9c578
commit
83b1fbb9d6
@ -1,8 +1,8 @@
|
||||
""" Mailu admin app
|
||||
"""
|
||||
|
||||
import flask
|
||||
import flask_bootstrap
|
||||
import redis
|
||||
from flask_kvsession import KVSessionExtension
|
||||
from simplekv.memory.redisstore import RedisStore
|
||||
|
||||
from mailu import utils, debug, models, manage, configuration
|
||||
|
||||
@ -20,7 +20,8 @@ def create_app_from_config(config):
|
||||
# Initialize application extensions
|
||||
config.init_app(app)
|
||||
models.db.init_app(app)
|
||||
KVSessionExtension(RedisStore(redis.StrictRedis().from_url('redis://{0}/3'.format(config['REDIS_ADDRESS']))), app).cleanup_sessions(app)
|
||||
utils.kvsession.init_kvstore(config)
|
||||
utils.kvsession.init_app(app)
|
||||
utils.limiter.init_app(app)
|
||||
utils.babel.init_app(app)
|
||||
utils.login.init_app(app)
|
||||
@ -53,8 +54,7 @@ def create_app_from_config(config):
|
||||
|
||||
|
||||
def create_app():
|
||||
""" Create a new application based on the config module
|
||||
""" Create a new application based on the config module
|
||||
"""
|
||||
config = configuration.ConfigManager()
|
||||
return create_app_from_config(config)
|
||||
|
||||
|
@ -1,11 +1,18 @@
|
||||
from mailu import models, limiter
|
||||
""" Mailu admin app utilities
|
||||
"""
|
||||
|
||||
from mailu import limiter
|
||||
|
||||
import flask
|
||||
import flask_login
|
||||
import flask_script
|
||||
import flask_migrate
|
||||
import flask_babel
|
||||
import flask_kvsession
|
||||
import redis
|
||||
|
||||
from simplekv.memory import DictStore
|
||||
from simplekv.memory.redisstore import RedisStore
|
||||
from itsdangerous.encoding import want_bytes
|
||||
from werkzeug.contrib import fixers
|
||||
|
||||
|
||||
@ -33,6 +40,10 @@ def get_locale():
|
||||
|
||||
# Proxy fixer
|
||||
class PrefixMiddleware(object):
|
||||
""" fix proxy headers """
|
||||
def __init__(self):
|
||||
self.app = None
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
prefix = environ.get('HTTP_X_FORWARDED_PREFIX', '')
|
||||
if prefix:
|
||||
@ -48,3 +59,53 @@ proxy = PrefixMiddleware()
|
||||
|
||||
# Data migrate
|
||||
migrate = flask_migrate.Migrate()
|
||||
|
||||
|
||||
# session store
|
||||
class NullSigner(object):
|
||||
"""NullSigner does not sign nor unsign"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
def sign(self, value):
|
||||
"""Signs the given string."""
|
||||
return want_bytes(value)
|
||||
def unsign(self, signed_value):
|
||||
"""Unsigns the given string."""
|
||||
return want_bytes(signed_value)
|
||||
|
||||
class KVSessionIntf(flask_kvsession.KVSessionInterface):
|
||||
""" KVSession interface allowing to run int function on first access """
|
||||
def __init__(self, app, init_fn=None):
|
||||
if init_fn:
|
||||
app.kvsession_init = init_fn
|
||||
else:
|
||||
self._first_run(None)
|
||||
def _first_run(self, app):
|
||||
if app:
|
||||
app.kvsession_init()
|
||||
self.open_session = super().open_session
|
||||
self.save_session = super().save_session
|
||||
def open_session(self, app, request):
|
||||
self._first_run(app)
|
||||
return super().open_session(app, request)
|
||||
def save_session(self, app, session, response):
|
||||
self._first_run(app)
|
||||
return super().save_session(app, session, response)
|
||||
|
||||
class KVSessionExt(flask_kvsession.KVSessionExtension):
|
||||
""" Activates Flask-KVSession for an application. """
|
||||
def init_kvstore(self, config):
|
||||
""" Initialize kvstore - fallback to DictStore without REDIS_ADDRESS """
|
||||
if addr := config.get('REDIS_ADDRESS'):
|
||||
self.default_kvstore = RedisStore(redis.StrictRedis().from_url(f'redis://{addr}/3'))
|
||||
else:
|
||||
self.default_kvstore = DictStore()
|
||||
|
||||
def init_app(self, app, session_kvstore=None):
|
||||
""" Initialize application and KVSession. """
|
||||
super().init_app(app, session_kvstore)
|
||||
app.session_interface = KVSessionIntf(app, self.cleanup_sessions)
|
||||
|
||||
kvsession = KVSessionExt()
|
||||
|
||||
flask_kvsession.Signer = NullSigner
|
||||
|
@ -39,6 +39,7 @@ python-editor==1.0.4
|
||||
pytz==2019.1
|
||||
PyYAML==5.1
|
||||
redis==3.2.1
|
||||
simplekv==0.14.1
|
||||
#alpine3:12 provides six==1.15.0
|
||||
#six==1.12.0
|
||||
socrate==0.1.1
|
||||
|
Loading…
Reference in New Issue
Block a user