Added a config hook for secret key into the app. (#1304)

* Added a config hook for secret key into the app.

the server first looks in an environment variable,
then looks in a config file.

For the cellxgene launch app, a default key is used if none is provided.
For the eb app, a secret key must be provided.
This commit is contained in:
bmccandless
2020-03-26 15:03:08 -07:00
committed by GitHub
parent a398f85ccc
commit 8c0480b0bc
5 changed files with 31 additions and 2 deletions
+2 -2
View File
@@ -207,8 +207,8 @@ class Server:
self.app.permanent_session_lifetime = datetime.timedelta(days=50 * 365)
# Config
SECRET_KEY = os.environ.get("CXG_SECRET_KEY", default="SparkleAndShine")
self.app.config.update(SECRET_KEY=SECRET_KEY)
secret_key = app_config.server__flask_secret_key
self.app.config.update(SECRET_KEY=secret_key)
self.app.register_blueprint(webbp)
+5
View File
@@ -275,6 +275,7 @@ class CliLaunchServer(Server):
"""
the CLI runs a local web server, and needs to enable a few more features.
"""
def __init__(self, matrix_data_cache_manager, annotations, app_config):
super().__init__(matrix_data_cache_manager, annotations, app_config)
@@ -394,6 +395,10 @@ def launch(
app_config.complete_config(matrix_data_cache_manager, messagefn)
# Use a default secret if one is not provided
if not app_config.server__flask_secret_key:
app_config.server__flask_secret_key = "SparkleAndShine"
except (ConfigurationError, DatasetAccessError) as e:
raise click.ClickException(e)
+16
View File
@@ -65,28 +65,37 @@ class AppConfig(object):
self.server__about_legal_tos = dc["server"]["about_legal_tos"]
self.server__about_legal_privacy = dc["server"]["about_legal_privacy"]
self.server__force_https = dc["server"]["force_https"]
self.server__flask_secret_key = dc["server"]["flask_secret_key"]
self.multi_dataset__dataroot = dc["multi_dataset"]["dataroot"]
self.multi_dataset__index = dc["multi_dataset"]["index"]
self.multi_dataset__allowed_matrix_types = dc["multi_dataset"]["allowed_matrix_types"]
self.multi_dataset__matrix_cache__max_datasets = dc["multi_dataset"]["matrix_cache"]["max_datasets"]
self.single_dataset__datapath = dc["single_dataset"]["datapath"]
self.single_dataset__obs_names = dc["single_dataset"]["obs_names"]
self.single_dataset__var_names = dc["single_dataset"]["var_names"]
self.single_dataset__about = dc["single_dataset"]["about"]
self.single_dataset__title = dc["single_dataset"]["title"]
self.user_annotations__enable = dc["user_annotations"]["enable"]
self.user_annotations__type = dc["user_annotations"]["type"]
self.user_annotations__local_file_csv__directory = dc["user_annotations"]["local_file_csv"]["directory"]
self.user_annotations__local_file_csv__file = dc["user_annotations"]["local_file_csv"]["file"]
self.user_annotations__ontology__enable = dc["user_annotations"]["ontology"]["enable"]
self.user_annotations__ontology__obo_location = dc["user_annotations"]["ontology"]["obo_location"]
self.presentation__max_categories = dc["presentation"]["max_categories"]
self.embeddings__names = dc["embeddings"]["names"]
self.embeddings__enable_reembedding = dc["embeddings"]["enable_reembedding"]
self.diffexp__enable = dc["diffexp"]["enable"]
self.diffexp__lfc_cutoff = dc["diffexp"]["lfc_cutoff"]
self.adaptor__cxg_adaptor__tiledb_ctx = dc["adaptor"]["cxg_adaptor"]["tiledb_ctx"]
self.adaptor__anndata_adaptor__backed = dc["adaptor"]["anndata_adaptor"]["backed"]
except KeyError as e:
raise ConfigurationError(f"Unexpected config: {str(e)}")
@@ -184,6 +193,8 @@ class AppConfig(object):
self.__check_attr("server__port", (type(None), int))
self.__check_attr("server__scripts", (list, tuple))
self.__check_attr("server__open_browser", bool)
self.__check_attr("server__force_https", bool)
self.__check_attr("server__flask_secret_key", (type(None), str))
if self.server__port:
if not is_port_available(self.server__host, self.server__port):
@@ -203,6 +214,11 @@ class AppConfig(object):
if not self.server__verbose:
sys.tracebacklimit = 0
# secret key:
# first, from CXG_SECRET_KEY environment variable
# second, from config file
self.server__flask_secret_key = environ.get("CXG_SECRET_KEY", self.server__flask_secret_key)
def handle_presentation(self, context):
self.__check_attr("presentation__max_categories", int)
+1
View File
@@ -13,6 +13,7 @@ server:
about_legal_tos: null
about_legal_privacy: null
force_https: false
flask_secret_key: null
presentation:
max_categories: 1000
+7
View File
@@ -77,6 +77,13 @@ try:
matrix_data_cache_manager = MatrixDataCacheManager()
app_config.complete_config(matrix_data_cache_manager, logging.info)
if not app_config.server__flask_secret_key:
logging.critical(
f"flask_secret_key is not provided. Either set in config file, or in CXG_SECRET_KEY environment variable"
)
sys.exit(1)
user_annotations = app_config.user_annotations
server = WSGIServer(matrix_data_cache_manager, user_annotations, app_config)