canaille-globuzma/canaille/__init__.py

192 lines
5.4 KiB
Python
Raw Normal View History

2021-07-01 09:04:57 +00:00
import datetime
2020-08-17 13:49:48 +00:00
import os
2021-12-20 22:57:27 +00:00
from logging.config import dictConfig
2020-08-17 13:49:48 +00:00
2021-12-20 22:57:27 +00:00
from flask import Flask
from flask import g
from flask import request
2021-12-20 22:57:27 +00:00
from flask import session
from flask_themer import FileSystemThemeLoader
from flask_themer import render_template
from flask_themer import Themer
2023-03-28 18:30:29 +00:00
from flask_wtf.csrf import CSRFProtect
2020-09-01 15:11:30 +00:00
2023-03-28 18:30:29 +00:00
csrf = CSRFProtect()
2020-08-17 13:49:48 +00:00
def setup_backend(app, backend):
2023-06-05 16:10:37 +00:00
from .backends.ldap.backend import Backend
if not backend:
2023-06-05 16:10:37 +00:00
backend = Backend(app.config)
backend.init_app(app)
with app.app_context():
g.backend = backend
app.backend = backend
2023-06-01 15:41:17 +00:00
if app.debug: # pragma: no cover
backend.install(app.config)
def setup_sentry(app): # pragma: no cover
2022-01-11 17:02:23 +00:00
if not app.config.get("SENTRY_DSN"):
return None
try:
2022-01-11 17:02:23 +00:00
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
except Exception:
return None
sentry_sdk.init(dsn=app.config["SENTRY_DSN"], integrations=[FlaskIntegration()])
return sentry_sdk
2021-10-31 13:40:12 +00:00
def setup_logging(app):
log_level = app.config.get("LOGGING", {}).get("LEVEL", "WARNING")
if not app.config.get("LOGGING", {}).get("PATH"):
handler = {
"class": "logging.StreamHandler",
"stream": "ext://flask.logging.wsgi_errors_stream",
"formatter": "default",
}
else:
handler = {
"class": "logging.handlers.WatchedFileHandler",
"filename": app.config["LOGGING"]["PATH"],
"formatter": "default",
}
dictConfig(
{
"version": 1,
"formatters": {
"default": {
"format": "[%(asctime)s] %(levelname)s in %(module)s: %(message)s",
}
},
"handlers": {"wsgi": handler},
"root": {"level": log_level, "handlers": ["wsgi"]},
"disable_existing_loggers": False,
2021-10-31 13:40:12 +00:00
}
)
2021-12-08 17:06:50 +00:00
def setup_jinja(app):
2021-12-10 16:08:43 +00:00
app.jinja_env.filters["len"] = len
app.jinja_env.policies["ext.i18n.trimmed"] = True
2021-12-08 17:06:50 +00:00
2021-12-08 15:10:01 +00:00
def setup_themer(app):
additional_themes_dir = (
os.path.dirname(app.config["THEME"])
if app.config.get("THEME") and os.path.exists(app.config["THEME"])
else None
)
themer = Themer(
app,
loaders=[FileSystemThemeLoader(additional_themes_dir)]
if additional_themes_dir
else None,
)
2021-12-08 15:10:01 +00:00
@themer.current_theme_loader
def get_current_theme():
# if config['THEME'] may be a theme name or an absolute path
return app.config.get("THEME", "default").split("/")[-1]
2020-09-27 15:32:23 +00:00
2021-12-08 15:10:01 +00:00
def setup_blueprints(app):
import canaille.core.account
import canaille.core.admin
import canaille.core.groups
import canaille.oidc.blueprints
2022-01-05 15:30:46 +00:00
2021-12-08 15:10:01 +00:00
app.url_map.strict_slashes = False
app.register_blueprint(canaille.core.account.bp)
app.register_blueprint(canaille.core.admin.bp)
app.register_blueprint(canaille.core.groups.bp)
app.register_blueprint(canaille.oidc.blueprints.bp)
2020-09-27 15:32:23 +00:00
2023-03-28 18:30:29 +00:00
def setup_flask(app):
csrf.init_app(app)
@app.before_request
def make_session_permanent():
session.permanent = True
app.permanent_session_lifetime = datetime.timedelta(days=365)
@app.context_processor
def global_processor():
2023-04-09 13:52:55 +00:00
from canaille.app.flask import current_user
2023-03-28 18:30:29 +00:00
return {
"debug": app.config.get("DEBUG", False) or app.config.get("TESTING", False),
2023-03-28 18:30:29 +00:00
"has_smtp": "SMTP" in app.config,
"has_password_recovery": app.config.get("ENABLE_PASSWORD_RECOVERY", True),
2022-11-01 11:25:21 +00:00
"has_account_lockability": app.backend.get().has_account_lockability(),
2023-03-28 18:30:29 +00:00
"logo_url": app.config.get("LOGO"),
"favicon_url": app.config.get("FAVICON", app.config.get("LOGO")),
"website_name": app.config.get("NAME", "Canaille"),
"user": current_user(),
"menu": True,
"is_boosted": request.headers.get("HX-Boosted", False),
2023-03-28 18:30:29 +00:00
}
@app.errorhandler(400)
def bad_request(error):
return render_template("error.html", description=error, error_code=400), 400
2023-03-28 18:30:29 +00:00
@app.errorhandler(403)
def unauthorized(error):
return render_template("error.html", description=error, error_code=403), 403
2023-03-28 18:30:29 +00:00
@app.errorhandler(404)
def page_not_found(error):
return render_template("error.html", description=error, error_code=404), 404
2023-03-28 18:30:29 +00:00
@app.errorhandler(500)
def server_error(error): # pragma: no cover
return render_template("error.html", description=error, error_code=500), 500
2023-03-28 18:30:29 +00:00
2023-06-28 15:56:49 +00:00
def setup_flask_converters(app):
from canaille.app.flask import model_converter
from canaille.app import models
app.url_map.converters["user"] = model_converter(models.User)
2023-06-28 16:09:25 +00:00
app.url_map.converters["group"] = model_converter(models.Group)
2023-06-28 15:56:49 +00:00
def create_app(config=None, validate=True, backend=None):
from .oidc.oauth import setup_oauth
from .app.i18n import setup_i18n
from .app.configuration import setup_config
2021-12-08 15:10:01 +00:00
app = Flask(__name__)
setup_config(app, config, validate)
2022-01-11 17:02:23 +00:00
sentry_sdk = setup_sentry(app)
2021-12-08 15:10:01 +00:00
try:
setup_logging(app)
setup_backend(app, backend)
2021-12-08 15:10:01 +00:00
setup_oauth(app)
2023-06-28 15:56:49 +00:00
setup_flask_converters(app)
2021-12-08 15:10:01 +00:00
setup_blueprints(app)
2021-12-08 17:06:50 +00:00
setup_jinja(app)
setup_i18n(app)
2021-12-08 15:10:01 +00:00
setup_themer(app)
2023-03-28 18:30:29 +00:00
setup_flask(app)
2020-09-27 15:32:23 +00:00
except Exception as exc: # pragma: no cover
2022-01-11 17:02:23 +00:00
if sentry_sdk:
2020-09-29 16:21:41 +00:00
sentry_sdk.capture_exception(exc)
raise
return app