We can use string interpolation in the file rather than building it when making the config. Adding the value to the config allows us to override it with an environment variable, if we want to (as we do for the UAT environment).
193 lines
5.7 KiB
Python
193 lines
5.7 KiB
Python
import os
|
|
import re
|
|
import pathlib
|
|
from configparser import ConfigParser
|
|
from flask import Flask, request, g
|
|
from flask_session import Session
|
|
import redis
|
|
from unipath import Path
|
|
from flask_wtf.csrf import CSRFProtect
|
|
|
|
from atst.database import db
|
|
from atst.assets import environment as assets_environment
|
|
from atst.filters import register_filters
|
|
from atst.routes import bp
|
|
from atst.routes.workspaces import bp as workspace_routes
|
|
from atst.routes.requests import requests_bp
|
|
from atst.routes.dev import bp as dev_routes
|
|
from atst.routes.users import bp as user_routes
|
|
from atst.routes.errors import make_error_pages
|
|
from atst.domain.authnid.crl import CRLCache
|
|
from atst.domain.auth import apply_authentication
|
|
from atst.domain.authz import Authorization
|
|
from atst.models.permissions import Permissions
|
|
from atst.eda_client import MockEDAClient
|
|
from atst.uploader import Uploader
|
|
from atst.utils import mailer
|
|
from atst.queue import queue
|
|
|
|
|
|
ENV = os.getenv("FLASK_ENV", "dev")
|
|
|
|
|
|
def make_app(config):
|
|
|
|
parent_dir = Path().parent
|
|
|
|
app = Flask(
|
|
__name__,
|
|
template_folder=parent_dir.child("templates").absolute(),
|
|
static_folder=parent_dir.child("static").absolute(),
|
|
)
|
|
make_redis(app, config)
|
|
csrf = CSRFProtect()
|
|
|
|
app.config.update(config)
|
|
app.config.update({"SESSION_REDIS": app.redis})
|
|
|
|
make_flask_callbacks(app)
|
|
if app.config.get("REQUIRE_CRLS"):
|
|
make_crl_validator(app)
|
|
register_filters(app)
|
|
make_eda_client(app)
|
|
make_upload_storage(app)
|
|
make_mailer(app)
|
|
queue.init_app(app)
|
|
|
|
db.init_app(app)
|
|
csrf.init_app(app)
|
|
Session(app)
|
|
assets_environment.init_app(app)
|
|
|
|
make_error_pages(app)
|
|
app.register_blueprint(bp)
|
|
app.register_blueprint(workspace_routes)
|
|
app.register_blueprint(requests_bp)
|
|
app.register_blueprint(user_routes)
|
|
if ENV != "prod":
|
|
app.register_blueprint(dev_routes)
|
|
|
|
apply_authentication(app)
|
|
|
|
return app
|
|
|
|
|
|
def make_flask_callbacks(app):
|
|
@app.before_request
|
|
def _set_globals():
|
|
g.current_user = None
|
|
g.dev = os.getenv("FLASK_ENV", "dev") == "dev"
|
|
g.matchesPath = lambda href: re.match("^" + href, request.path)
|
|
g.modal = request.args.get("modal", None)
|
|
g.Authorization = Authorization
|
|
g.Permissions = Permissions
|
|
|
|
@app.after_request
|
|
def _cleanup(response):
|
|
g.current_user = None
|
|
return response
|
|
|
|
|
|
def map_config(config):
|
|
return {
|
|
**config["default"],
|
|
"ENV": config["default"]["ENVIRONMENT"],
|
|
"DEBUG": config["default"].getboolean("DEBUG"),
|
|
"PORT": int(config["default"]["PORT"]),
|
|
"SQLALCHEMY_DATABASE_URI": config["default"]["DATABASE_URI"],
|
|
"SQLALCHEMY_TRACK_MODIFICATIONS": False,
|
|
"WTF_CSRF_ENABLED": config.getboolean("default", "WTF_CSRF_ENABLED"),
|
|
"PERMANENT_SESSION_LIFETIME": config.getint(
|
|
"default", "PERMANENT_SESSION_LIFETIME"
|
|
),
|
|
"REQUIRE_CRLS": config.getboolean("default", "REQUIRE_CRLS"),
|
|
"RQ_REDIS_URL": config["default"]["REDIS_URI"],
|
|
"RQ_QUEUES": [config["default"]["RQ_QUEUES"]],
|
|
}
|
|
|
|
|
|
def make_config():
|
|
BASE_CONFIG_FILENAME = os.path.join(os.path.dirname(__file__), "../config/base.ini")
|
|
ENV_CONFIG_FILENAME = os.path.join(
|
|
os.path.dirname(__file__), "../config/", "{}.ini".format(ENV.lower())
|
|
)
|
|
OVERRIDE_CONFIG_FILENAME = os.getenv("OVERRIDE_CONFIG_FULLPATH")
|
|
|
|
config = ConfigParser()
|
|
config.optionxform = str
|
|
|
|
config_files = [BASE_CONFIG_FILENAME, ENV_CONFIG_FILENAME]
|
|
if OVERRIDE_CONFIG_FILENAME:
|
|
config_files.append(OVERRIDE_CONFIG_FILENAME)
|
|
|
|
config_files = [BASE_CONFIG_FILENAME, ENV_CONFIG_FILENAME]
|
|
if OVERRIDE_CONFIG_FILENAME:
|
|
config_files.append(OVERRIDE_CONFIG_FILENAME)
|
|
|
|
# ENV_CONFIG will override values in BASE_CONFIG.
|
|
config.read(config_files)
|
|
|
|
# Check for ENV variables as a final source of overrides
|
|
for confsetting in config.options("default"):
|
|
env_override = os.getenv(confsetting.upper())
|
|
if env_override:
|
|
config.set("default", confsetting, env_override)
|
|
|
|
# Assemble DATABASE_URI value
|
|
database_uri = (
|
|
"postgres://"
|
|
+ config.get("default", "PGUSER")
|
|
+ ":"
|
|
+ config.get("default", "PGPASSWORD")
|
|
+ "@"
|
|
+ config.get("default", "PGHOST")
|
|
+ ":"
|
|
+ config.get("default", "PGPORT")
|
|
+ "/"
|
|
+ config.get("default", "PGDATABASE")
|
|
)
|
|
config.set("default", "DATABASE_URI", database_uri)
|
|
|
|
return map_config(config)
|
|
|
|
|
|
def make_redis(app, config):
|
|
r = redis.Redis.from_url(config["REDIS_URI"])
|
|
app.redis = r
|
|
|
|
|
|
def make_crl_validator(app):
|
|
crl_locations = []
|
|
for filename in pathlib.Path(app.config["CRL_DIRECTORY"]).glob("*.crl"):
|
|
crl_locations.append(filename.absolute())
|
|
app.crl_cache = CRLCache(app.config["CA_CHAIN"], crl_locations, logger=app.logger)
|
|
|
|
|
|
def make_eda_client(app):
|
|
app.eda_client = MockEDAClient()
|
|
|
|
|
|
def make_upload_storage(app):
|
|
uploader = Uploader(
|
|
provider=app.config.get("STORAGE_PROVIDER"),
|
|
container=app.config.get("STORAGE_CONTAINER"),
|
|
key=app.config.get("STORAGE_KEY"),
|
|
secret=app.config.get("STORAGE_SECRET"),
|
|
)
|
|
app.uploader = uploader
|
|
|
|
|
|
def make_mailer(app):
|
|
if app.config["DEBUG"]:
|
|
mailer_connection = mailer.RedisConnection(app.redis)
|
|
else:
|
|
mailer_connection = mailer.SMTPConnection(
|
|
server=app.config.get("MAIL_SERVER"),
|
|
port=app.config.get("MAIL_PORT"),
|
|
username=app.config.get("MAIL_SENDER"),
|
|
password=app.config.get("MAIL_PASSWORD"),
|
|
use_tls=app.config.get("MAIL_TLS"),
|
|
)
|
|
sender = app.config.get("MAIL_SENDER")
|
|
app.mailer = mailer.Mailer(mailer_connection, sender)
|