mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-08 18:48:12 +08:00
CORS and CSP headers (#1286)
* do in-app compression only for CLI * CORS and CSP headers * lint * add --debug to targets * lint * fix botched merge with master
This commit is contained in:
+2
-2
@@ -42,11 +42,11 @@ start-server:
|
|||||||
|
|
||||||
.PHONY: backend-dev
|
.PHONY: backend-dev
|
||||||
backend-dev: server-requirements
|
backend-dev: server-requirements
|
||||||
source ../venv/bin/activate && $(MAKE) start-server
|
source ../venv/bin/activate && CXG_OPTIONS='--debug' $(MAKE) start-server
|
||||||
|
|
||||||
.PHONY: backend-dev-anno-ontology
|
.PHONY: backend-dev-anno-ontology
|
||||||
backend-dev-anno-ontology: server-requirements
|
backend-dev-anno-ontology: server-requirements
|
||||||
CXG_OPTIONS='--experimental-annotations-ontology' \
|
CXG_OPTIONS='--experimental-annotations-ontology --debug' \
|
||||||
$(MAKE) backend-dev
|
$(MAKE) backend-dev
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|||||||
+5
-3
@@ -4,7 +4,6 @@ import logging
|
|||||||
|
|
||||||
from flask import Flask, redirect, current_app, make_response, render_template, abort
|
from flask import Flask, redirect, current_app, make_response, render_template, abort
|
||||||
from flask import Blueprint, request, send_from_directory
|
from flask import Blueprint, request, send_from_directory
|
||||||
from flask_cors import CORS
|
|
||||||
from flask_restful import Api, Resource
|
from flask_restful import Api, Resource
|
||||||
|
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
@@ -204,10 +203,9 @@ class Server:
|
|||||||
def __init__(self, matrix_data_cache_manager, annotations, app_config):
|
def __init__(self, matrix_data_cache_manager, annotations, app_config):
|
||||||
|
|
||||||
self.app = Flask(__name__, static_folder="../common/web/static")
|
self.app = Flask(__name__, static_folder="../common/web/static")
|
||||||
|
self._before_adding_routes(app_config)
|
||||||
self.app.json_encoder = Float32JSONEncoder
|
self.app.json_encoder = Float32JSONEncoder
|
||||||
|
|
||||||
CORS(self.app, supports_credentials=True)
|
|
||||||
|
|
||||||
# enable session data
|
# enable session data
|
||||||
self.app.permanent_session_lifetime = datetime.timedelta(days=50 * 365)
|
self.app.permanent_session_lifetime = datetime.timedelta(days=50 * 365)
|
||||||
|
|
||||||
@@ -238,3 +236,7 @@ class Server:
|
|||||||
self.app.matrix_data_cache_manager = matrix_data_cache_manager
|
self.app.matrix_data_cache_manager = matrix_data_cache_manager
|
||||||
self.app.annotations = annotations
|
self.app.annotations = annotations
|
||||||
self.app.app_config = app_config
|
self.app.app_config = app_config
|
||||||
|
|
||||||
|
def _before_adding_routes(self, app_config):
|
||||||
|
""" will be called before routes are added. Subclass protocol """
|
||||||
|
pass
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import webbrowser
|
|||||||
|
|
||||||
import click
|
import click
|
||||||
from flask_compress import Compress
|
from flask_compress import Compress
|
||||||
|
from flask_cors import CORS
|
||||||
|
|
||||||
from server.common.utils import sort_options
|
from server.common.utils import sort_options
|
||||||
from server.common.errors import DatasetAccessError, ConfigurationError
|
from server.common.errors import DatasetAccessError, ConfigurationError
|
||||||
@@ -276,6 +277,8 @@ class CliLaunchServer(Server):
|
|||||||
"""
|
"""
|
||||||
def __init__(self, matrix_data_cache_manager, annotations, app_config):
|
def __init__(self, matrix_data_cache_manager, annotations, app_config):
|
||||||
super().__init__(matrix_data_cache_manager, annotations, app_config)
|
super().__init__(matrix_data_cache_manager, annotations, app_config)
|
||||||
|
|
||||||
|
def _before_adding_routes(self, app_config):
|
||||||
self.app.config["COMPRESS_MIMETYPES"] = [
|
self.app.config["COMPRESS_MIMETYPES"] = [
|
||||||
"text/html",
|
"text/html",
|
||||||
"text/css",
|
"text/css",
|
||||||
@@ -284,8 +287,9 @@ class CliLaunchServer(Server):
|
|||||||
"application/javascript",
|
"application/javascript",
|
||||||
"application/octet-stream",
|
"application/octet-stream",
|
||||||
]
|
]
|
||||||
compress = Compress(self.app)
|
Compress(self.app)
|
||||||
compress.init_app(self.app)
|
if app_config.server__debug:
|
||||||
|
CORS(self.app, supports_credentials=True)
|
||||||
|
|
||||||
|
|
||||||
@sort_options
|
@sort_options
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ class AppConfig(object):
|
|||||||
self.server__open_browser = dc["server"]["open_browser"]
|
self.server__open_browser = dc["server"]["open_browser"]
|
||||||
self.server__about_legal_tos = dc["server"]["about_legal_tos"]
|
self.server__about_legal_tos = dc["server"]["about_legal_tos"]
|
||||||
self.server__about_legal_privacy = dc["server"]["about_legal_privacy"]
|
self.server__about_legal_privacy = dc["server"]["about_legal_privacy"]
|
||||||
|
self.server__force_https = dc["server"]["force_https"]
|
||||||
self.multi_dataset__dataroot = dc["multi_dataset"]["dataroot"]
|
self.multi_dataset__dataroot = dc["multi_dataset"]["dataroot"]
|
||||||
self.multi_dataset__index = dc["multi_dataset"]["index"]
|
self.multi_dataset__index = dc["multi_dataset"]["index"]
|
||||||
self.multi_dataset__allowed_matrix_types = dc["multi_dataset"]["allowed_matrix_types"]
|
self.multi_dataset__allowed_matrix_types = dc["multi_dataset"]["allowed_matrix_types"]
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ server:
|
|||||||
open_browser: false
|
open_browser: false
|
||||||
about_legal_tos: null
|
about_legal_tos: null
|
||||||
about_legal_privacy: null
|
about_legal_privacy: null
|
||||||
|
force_https: false
|
||||||
|
|
||||||
presentation:
|
presentation:
|
||||||
max_categories: 1000
|
max_categories: 1000
|
||||||
|
|||||||
+13
-2
@@ -3,6 +3,7 @@
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
from flask_talisman import Talisman
|
||||||
|
|
||||||
if os.path.isdir("/opt/python/log"):
|
if os.path.isdir("/opt/python/log"):
|
||||||
# This is the standard location where Amazon EC2 instances store the application logs.
|
# This is the standard location where Amazon EC2 instances store the application logs.
|
||||||
@@ -27,6 +28,16 @@ except Exception:
|
|||||||
logging.critical("Exception importing server modules", exc_info=True)
|
logging.critical("Exception importing server modules", exc_info=True)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
class WSGIServer(Server):
|
||||||
|
def __init__(self, matrix_data_cache_manager, annotations, app_config):
|
||||||
|
super().__init__(matrix_data_cache_manager, annotations, app_config)
|
||||||
|
|
||||||
|
def _before_adding_routes(self, app_config):
|
||||||
|
csp = {"default-src": "'self' 'unsafe-inline' 'unsafe-eval'", "img-src": ["'self'", "data:"]}
|
||||||
|
Talisman(self.app, force_https=app_config.server__force_https, content_security_policy=csp)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dataroot = os.getenv("CXG_DATAROOT")
|
dataroot = os.getenv("CXG_DATAROOT")
|
||||||
app_config = AppConfig()
|
app_config = AppConfig()
|
||||||
@@ -38,7 +49,7 @@ try:
|
|||||||
|
|
||||||
if dataroot:
|
if dataroot:
|
||||||
logging.info(f"Configuration from CXG_DATAROOT")
|
logging.info(f"Configuration from CXG_DATAROOT")
|
||||||
app_config.update(multi_dataset__dataroot=dataroot,)
|
app_config.update(multi_dataset__dataroot=dataroot)
|
||||||
|
|
||||||
# features are unsupported in the current hosted server
|
# features are unsupported in the current hosted server
|
||||||
app_config.update(
|
app_config.update(
|
||||||
@@ -52,7 +63,7 @@ try:
|
|||||||
app_config.complete_config(matrix_data_cache_manager, logging.info)
|
app_config.complete_config(matrix_data_cache_manager, logging.info)
|
||||||
user_annotations = app_config.user_annotations
|
user_annotations = app_config.user_annotations
|
||||||
|
|
||||||
server = Server(matrix_data_cache_manager, user_annotations, app_config)
|
server = WSGIServer(matrix_data_cache_manager, user_annotations, app_config)
|
||||||
|
|
||||||
debug = False
|
debug = False
|
||||||
application = server.app
|
application = server.app
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ Flask-Compress>=1.4.0
|
|||||||
Flask-Cors>=3.0.6
|
Flask-Cors>=3.0.6
|
||||||
Flask-RESTful>=0.3.6
|
Flask-RESTful>=0.3.6
|
||||||
flask-server-timing>=0.1.2
|
flask-server-timing>=0.1.2
|
||||||
|
flask-talisman>=0.7.0
|
||||||
flatbuffers>=1.10.0
|
flatbuffers>=1.10.0
|
||||||
flatten-dict>=0.2.0
|
flatten-dict>=0.2.0
|
||||||
fsspec>=0.4.4
|
fsspec>=0.4.4
|
||||||
|
|||||||
Reference in New Issue
Block a user