diff --git a/redash/controllers.py b/redash/controllers.py index 7c845445ef..73fc066cfe 100644 --- a/redash/controllers.py +++ b/redash/controllers.py @@ -343,7 +343,7 @@ class QueryAPI(BaseResource): @require_permission('edit_query') def post(self, query_id): query = models.Query.get_by_id(query_id) - + query_def = request.get_json(force=True) for field in ['id', 'created_at', 'api_key', 'visualizations', 'latest_query_data', 'user', 'last_modified_by']: query_def.pop(field, None) @@ -395,7 +395,7 @@ def post(self): kwargs = request.get_json(force=True) kwargs['options'] = json.dumps(kwargs['options']) kwargs['query'] = kwargs.pop('query_id') - + vis = models.Visualization(**kwargs) vis.save() @@ -488,6 +488,22 @@ def csv_response(query_result): headers.update(cache_headers) return make_response(s.getvalue(), 200, headers) + @staticmethod + def add_access_control_allow_origin_header(headers): + if 'Origin' in request.headers: + origin = request.headers['Origin'] + + if origin in settings.QUERIES_RESULT_CORS: + headers['Access-Control-Allow-Origin'] = origin + headers['Access-Control-Allow-Credentials'] = 'true' + if request.method == 'OPTIONS': + headers['Access-Control-Request-Method'] = 'GET, POST, PUT' + headers['Access-Control-Allow-Headers'] = 'Content-Type' + + @require_permission('view_query') + def options(self, query_id=None, query_result_id=None, filetype='json'): + self.add_access_control_allow_origin_header(request.headers) + @require_permission('view_query') def get(self, query_id=None, query_result_id=None, filetype='json'): if query_result_id is None and query_id is not None: @@ -517,9 +533,15 @@ def get(self, query_id=None, query_result_id=None, filetype='json'): record_event.delay(event) + headers = {} + + if len(settings.QUERIES_RESULT_CORS) > 0: + self.add_access_control_allow_origin_header(headers) + if filetype == 'json': data = json.dumps({'query_result': query_result.to_dict()}, cls=utils.JSONEncoder) - return make_response(data, 200, cache_headers) + headers.update(cache_headers) + return make_response(data, 200, headers) else: return self.csv_response(query_result) @@ -559,6 +581,3 @@ def send_static(filename): if __name__ == '__main__': app.run(debug=True) - - - diff --git a/redash/settings.py b/redash/settings.py index 2bef79cda1..1f3cf8c485 100644 --- a/redash/settings.py +++ b/redash/settings.py @@ -81,6 +81,8 @@ def parse_boolean(str): CLIENT_SIDE_METRICS = parse_boolean(os.environ.get("REDASH_CLIENT_SIDE_METRICS", "false")) ANALYTICS = os.environ.get("REDASH_ANALYTICS", "") +QUERIES_RESULT_CORS = set_from_string(os.environ.get("REDASH_QUERIES_RESULT_CORS", "")) + # Query Runners QUERY_RUNNERS = array_from_string(os.environ.get("REDASH_ENABLED_QUERY_RUNNERS", ",".join([ 'redash.query_runner.big_query',