about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--etc/default_settings.py10
-rw-r--r--wqflask/wqflask/__init__.py15
-rw-r--r--wqflask/wqflask/startup.py43
-rw-r--r--wqflask/wqflask/templates/startup_errors.html20
4 files changed, 81 insertions, 7 deletions
diff --git a/etc/default_settings.py b/etc/default_settings.py
index 38c0a110..0ffe6ae9 100644
--- a/etc/default_settings.py
+++ b/etc/default_settings.py
@@ -27,7 +27,7 @@ import sys
 with open("../etc/VERSION", "r") as version_file:
     GN_VERSION = version_file.read()
 
-SECRET_KEY = "pleaseChangeThisToSomethingSecretInAnExternalConfigFileOrEnvvars"
+SECRET_KEY = ""
 
 # Redis
 REDIS_URL = "redis://:@localhost:6379/0"
@@ -43,6 +43,7 @@ GN_PROXY_URL="https://genenetwork.org/gn3-proxy/"
 SQL_URI = "mysql://gn2:mysql_password@localhost/db_webqtl_s"
 SQL_ALCHEMY_POOL_RECYCLE = 3600
 GN_SERVER_URL = "http://localhost:8880/api/" # REST API server
+AUTH_SERVER_URL="https://auth.genenetwork.org/"
 GN2_BASE_URL = "http://genenetwork.org/" # to pick up REST API
 GN2_BRANCH_URL = GN2_BASE_URL
 
@@ -55,12 +56,7 @@ SECURITY_RECOVERABLE = True
 SECURITY_EMAIL_SENDER = "no-reply@genenetwork.org"
 SECURITY_POST_LOGIN_VIEW = "/thank_you"
 
-# ---- SERVER_PORT needs an override before firing up the server
-SERVER_PORT = os.environ['SERVER_PORT']
-if isinstance(SERVER_PORT, str):
-    SERVER_PORT = int(SERVER_PORT)        # don't do this for other settings!
-else:
-    SERVER_PORT = 5003
+SERVER_PORT = 5003
 
 SECRET_HMAC_CODE = '\x08\xdf\xfa\x93N\x80\xd9\\H@\\\x9f`\x98d^\xb4a;\xc6OM\x946a\xbc\xfc\x80:*\xebc'
 
diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py
index 9a608474..f4599a0b 100644
--- a/wqflask/wqflask/__init__.py
+++ b/wqflask/wqflask/__init__.py
@@ -3,6 +3,7 @@
 import time
 import datetime
 from typing import Tuple
+from pathlib import Path
 from urllib.parse import urljoin, urlparse
 
 import redis
@@ -36,11 +37,19 @@ from wqflask.oauth2.request_utils import user_details, authserver_authorise_uri
 
 from wqflask.jupyter_notebooks import jupyter_notebooks
 
+from wqflask.startup import (
+    StartupError,
+    startup_errors,
+    check_mandatory_configs)
+
 app = Flask(__name__)
 
 
 # See http://flask.pocoo.org/docs/config/#configuring-from-files
 # Note no longer use the badly named WQFLASK_OVERRIDES (nyi)
+default_settings_file = Path(Path(__file__).parent.parent.parent,
+                             "etc/default_settings.py")
+app.config.from_pyfile(default_settings_file)
 app.config.from_envvar('GN2_SETTINGS')
 
 app.jinja_env.globals.update(
@@ -54,6 +63,7 @@ app.jinja_env.globals.update(
 
 app.config["SESSION_REDIS"] = redis.from_url(app.config["REDIS_URL"])
 
+
 # Registering blueprints
 app.register_blueprint(glossary_blueprint, url_prefix="/glossary")
 app.register_blueprint(references_blueprint, url_prefix="/references")
@@ -74,6 +84,11 @@ app.register_blueprint(oauth2, url_prefix="/oauth2")
 from wqflask.decorators import AuthorisationError
 from wqflask.app_errors import handle_authorisation_error
 app.register_error_handler(AuthorisationError, handle_authorisation_error)
+try:
+    check_mandatory_configs(app)
+except StartupError as serr:
+    app.startup_error = serr
+    app.register_blueprint(startup_errors, url_prefix="/")
 
 server_session = Session(app)
 
diff --git a/wqflask/wqflask/startup.py b/wqflask/wqflask/startup.py
new file mode 100644
index 00000000..e531aacb
--- /dev/null
+++ b/wqflask/wqflask/startup.py
@@ -0,0 +1,43 @@
+"""Checks to do before the application is started."""
+from typing import Tuple
+
+from flask import Blueprint, current_app, render_template
+
+class StartupError(Exception):
+    """Base class for Application Check Errors."""
+
+class MissingConfigurationError(StartupError):
+    """Raised in case of a missing required setting."""
+
+    def __init__(self, missing=Tuple[str, ...]):
+        """Initialise the MissingConfigurationError object."""
+        super().__init__("At least one required configuration is missing.")
+        self.missing = missing
+
+startup_errors = Blueprint("app_check_errors", __name__)
+__MANDATORY_CONFIGURATIONS__ = (
+    "SECRET_KEY",
+    "REDIS_URL", # URI to Redis server
+    "SQL_URI", # URI to MariaDB server
+    "GN_SERVER_URL", # REST API Server
+    "AUTH_SERVER_URL" # Auth(entic/oris)ation Server
+)
+
+def check_mandatory_configs(app):
+    """Check that all mandatory configuration settings are defined."""
+    missing = tuple(
+        setting for setting in __MANDATORY_CONFIGURATIONS__
+        if (setting not in app.config
+            or app.config.get(setting) is None
+            or app.config.get(setting).strip() == ""))
+    if len(missing) > 0:
+        print(missing)
+        raise MissingConfigurationError(missing)
+
+@startup_errors.route("/")
+def error_index():
+    """Display errors experienced at application startup"""
+    return render_template(
+        "startup_errors.html",
+        error_type = type(current_app.startup_error).__name__,
+        error_value = current_app.startup_error)
diff --git a/wqflask/wqflask/templates/startup_errors.html b/wqflask/wqflask/templates/startup_errors.html
new file mode 100644
index 00000000..82d85572
--- /dev/null
+++ b/wqflask/wqflask/templates/startup_errors.html
@@ -0,0 +1,20 @@
+{%extends "base.html"%}
+{%block title%}Startup Error{%endblock%}
+{%block content %}
+{%if error_type == "MissingConfigurationError"%}
+
+<div class="container">
+  <h1>Startup Error</h1>
+
+  <p>
+    The application could not start due to the missing configuration settings
+    below:
+    <ul>
+      {%for setting in error_value.missing%}
+      <li class="text-danger"><strong>{{setting}}</strong></li>
+      {%endfor%}
+    </ul>
+  </p>
+</div>
+{%endif%}
+{%endblock%}