2021-03-14 19:09:21 +02:00
|
|
|
""" Mailu admin app
|
|
|
|
"""
|
|
|
|
|
2016-06-25 12:57:47 +02:00
|
|
|
import flask
|
|
|
|
import flask_bootstrap
|
2016-02-20 14:57:26 +02:00
|
|
|
|
2018-11-08 22:29:30 +02:00
|
|
|
from mailu import utils, debug, models, manage, configuration
|
2022-12-29 15:14:53 +02:00
|
|
|
from gunicorn import glogging
|
|
|
|
import logging
|
2018-10-18 15:57:43 +02:00
|
|
|
|
2021-02-07 18:58:19 +02:00
|
|
|
import hmac
|
2018-10-18 15:57:43 +02:00
|
|
|
|
2022-12-29 15:14:53 +02:00
|
|
|
class NoPingFilter(logging.Filter):
|
|
|
|
def filter(self, record):
|
2023-05-04 00:14:44 +02:00
|
|
|
if (record.args['{host}i'] == 'localhost' and record.args['r'] == 'GET /ping HTTP/1.1'):
|
|
|
|
return False
|
|
|
|
if record.args['r'].endswith(' /internal/rspamd/local_domains HTTP/1.1'):
|
|
|
|
return False
|
|
|
|
return True
|
2022-12-29 15:14:53 +02:00
|
|
|
|
|
|
|
class Logger(glogging.Logger):
|
|
|
|
def setup(self, cfg):
|
|
|
|
super().setup(cfg)
|
|
|
|
|
|
|
|
# Add filters to Gunicorn logger
|
|
|
|
logger = logging.getLogger("gunicorn.access")
|
|
|
|
logger.addFilter(NoPingFilter())
|
|
|
|
|
2018-10-18 15:57:43 +02:00
|
|
|
def create_app_from_config(config):
|
|
|
|
""" Create a new application based on the given configuration
|
|
|
|
"""
|
2021-10-27 20:36:50 +02:00
|
|
|
app = flask.Flask(__name__, static_folder='static', static_url_path='/static')
|
2018-11-08 22:29:30 +02:00
|
|
|
app.cli.add_command(manage.mailu)
|
2018-10-18 15:57:43 +02:00
|
|
|
|
2021-09-02 22:49:36 +02:00
|
|
|
# Bootstrap is used for error display and flash messages
|
2018-10-18 15:57:43 +02:00
|
|
|
app.bootstrap = flask_bootstrap.Bootstrap(app)
|
|
|
|
|
|
|
|
# Initialize application extensions
|
2018-10-18 17:55:07 +02:00
|
|
|
config.init_app(app)
|
2018-10-18 15:57:43 +02:00
|
|
|
models.db.init_app(app)
|
2021-04-04 14:35:31 +02:00
|
|
|
utils.session.init_app(app)
|
2018-10-18 15:57:43 +02:00
|
|
|
utils.limiter.init_app(app)
|
|
|
|
utils.babel.init_app(app)
|
|
|
|
utils.login.init_app(app)
|
2018-11-08 21:29:52 +02:00
|
|
|
utils.login.user_loader(models.User.get)
|
2021-10-27 23:51:49 +02:00
|
|
|
utils.proxy.init_app(app)
|
2018-11-08 21:29:52 +02:00
|
|
|
utils.migrate.init_app(app, models.db)
|
2018-10-18 15:57:43 +02:00
|
|
|
|
2021-09-23 18:40:49 +02:00
|
|
|
app.device_cookie_key = hmac.new(bytearray(app.secret_key, 'utf-8'), bytearray('DEVICE_COOKIE_KEY', 'utf-8'), 'sha256').digest()
|
2021-02-07 18:58:19 +02:00
|
|
|
app.temp_token_key = hmac.new(bytearray(app.secret_key, 'utf-8'), bytearray('WEBMAIL_TEMP_TOKEN_KEY', 'utf-8'), 'sha256').digest()
|
2021-10-01 15:00:10 +02:00
|
|
|
app.srs_key = hmac.new(bytearray(app.secret_key, 'utf-8'), bytearray('SRS_KEY', 'utf-8'), 'sha256').digest()
|
2023-05-04 00:14:44 +02:00
|
|
|
app.truncated_pw_key = hmac.new(bytearray(app.secret_key, 'utf-8'), bytearray('TRUNCATED_PW_KEY', 'utf-8'), 'sha256').digest()
|
2021-02-07 18:58:19 +02:00
|
|
|
|
2021-09-02 22:49:36 +02:00
|
|
|
# Initialize list of translations
|
2021-11-03 23:21:26 +02:00
|
|
|
app.config.translations = {
|
2021-09-02 22:49:36 +02:00
|
|
|
str(locale): locale
|
|
|
|
for locale in sorted(
|
|
|
|
utils.babel.list_translations(),
|
|
|
|
key=lambda l: l.get_language_name().title()
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2018-10-18 15:57:43 +02:00
|
|
|
# Initialize debugging tools
|
2018-10-18 17:55:07 +02:00
|
|
|
if app.config.get("DEBUG"):
|
2018-10-18 15:57:43 +02:00
|
|
|
debug.toolbar.init_app(app)
|
2022-11-04 16:15:19 +02:00
|
|
|
if app.config.get("DEBUG_PROFILER"):
|
|
|
|
debug.profiler.init_app(app)
|
|
|
|
if assets := app.config.get('DEBUG_ASSETS'):
|
|
|
|
app.static_folder = assets
|
2023-05-04 00:14:44 +02:00
|
|
|
app.logger.setLevel(app.config.get('LOG_LEVEL'))
|
2018-10-18 15:57:43 +02:00
|
|
|
|
|
|
|
# Inject the default variables in the Jinja parser
|
2018-10-18 17:55:07 +02:00
|
|
|
# TODO: move this to blueprints when needed
|
2018-10-18 15:57:43 +02:00
|
|
|
@app.context_processor
|
|
|
|
def inject_defaults():
|
|
|
|
signup_domains = models.Domain.query.filter_by(signup_enabled=True).all()
|
|
|
|
return dict(
|
2021-09-02 22:49:36 +02:00
|
|
|
signup_domains= signup_domains,
|
|
|
|
config = app.config,
|
2022-11-03 16:34:05 +02:00
|
|
|
get_locale = utils.get_locale,
|
2018-10-18 15:57:43 +02:00
|
|
|
)
|
|
|
|
|
2021-11-11 13:20:52 +02:00
|
|
|
# Jinja filters
|
2021-11-03 22:52:59 +02:00
|
|
|
@app.template_filter()
|
|
|
|
def format_date(value):
|
|
|
|
return utils.flask_babel.format_date(value) if value else ''
|
|
|
|
|
2021-11-11 13:20:52 +02:00
|
|
|
@app.template_filter()
|
|
|
|
def format_datetime(value):
|
|
|
|
return utils.flask_babel.format_datetime(value) if value else ''
|
|
|
|
|
2022-12-29 15:14:53 +02:00
|
|
|
def ping():
|
|
|
|
return ''
|
|
|
|
app.route('/ping')(ping)
|
|
|
|
|
2018-10-18 15:57:43 +02:00
|
|
|
# Import views
|
2021-01-06 18:05:21 +02:00
|
|
|
from mailu import ui, internal, sso, api
|
2021-10-27 20:36:50 +02:00
|
|
|
app.register_blueprint(ui.ui, url_prefix=app.config['WEB_ADMIN'])
|
2018-10-18 15:57:43 +02:00
|
|
|
app.register_blueprint(internal.internal, url_prefix='/internal')
|
2021-09-02 13:36:42 +02:00
|
|
|
app.register_blueprint(sso.sso, url_prefix='/sso')
|
2023-01-25 17:26:10 +02:00
|
|
|
api.register(app, web_api_root=app.config.get('WEB_API'))
|
2018-10-18 15:57:43 +02:00
|
|
|
return app
|
|
|
|
|
|
|
|
|
|
|
|
def create_app():
|
2021-03-14 19:09:21 +02:00
|
|
|
""" Create a new application based on the config module
|
2018-10-18 15:57:43 +02:00
|
|
|
"""
|
|
|
|
config = configuration.ConfigManager()
|
|
|
|
return create_app_from_config(config)
|
2021-10-29 14:26:23 +02:00
|
|
|
|