From 38732a8a6fa0e138ccc1993ca1c61a2c27b7ad2d Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Fri, 3 Aug 2018 17:33:28 -0700 Subject: [PATCH] Lyft view - amundsen edition (cherry picked from commit 9b3420c8ef51739206282514ca4a69fb01a2066f) (cherry picked from commit 2df0fb8d286616cd4d5b9f582d337c726edd1d7a) (cherry picked from commit 2829eadd7f3d534710bfc53a735c08efb1487516) (cherry picked from commit ac9dbef4a2fadfc82a617787112bfa336ee100bc) (cherry picked from commit 0c32389cf30ebd31bc6e34f1a78aa41774d80099) (cherry picked from commit 5aceb0a8f544298237c62b1e1ecbc7d75a0e7129) (cherry picked from commit b7ca416a103ee8d51b75d3a94481295f47820fc7) --- superset/views/__init__.py | 1 + superset/views/core.py | 3 ++ superset/views/lyft.py | 74 ++++++++++++++++++++++++++++++++++++++ tests/security_tests.py | 3 ++ 4 files changed, 81 insertions(+) create mode 100644 superset/views/lyft.py diff --git a/superset/views/__init__.py b/superset/views/__init__.py index 386e16e75f222..f00a26cf0f19f 100644 --- a/superset/views/__init__.py +++ b/superset/views/__init__.py @@ -14,6 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +from . import lyft # noqa from . import base # noqa from . import api # noqa from . import core # noqa diff --git a/superset/views/core.py b/superset/views/core.py index f7672f68e9966..aca096a4fe1e5 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -2464,6 +2464,9 @@ def stop_query(self): @expose('/sql_json/', methods=['POST', 'GET']) @log_this def sql_json(self): + return self.sql_json_call(request) + + def sql_json_call(self, request): """Runs arbitrary sql and returns and json""" async_ = request.form.get('runAsync') == 'true' sql = request.form.get('sql') diff --git a/superset/views/lyft.py b/superset/views/lyft.py new file mode 100644 index 0000000000000..a9b5171e007b2 --- /dev/null +++ b/superset/views/lyft.py @@ -0,0 +1,74 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# pylint: disable=C,R,W +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals + +from flask import g, request, Response +from flask_appbuilder import expose +from flask_appbuilder.security.decorators import has_access_api + +from superset import app, appbuilder, security_manager +from superset.exceptions import SupersetException +import superset.models.core as models +from superset.views.core import Superset +from .base import json_error_response + +config = app.config +stats_logger = config.get('STATS_LOGGER') +log_this = models.Log.log_this +DAR = models.DatasourceAccessRequest + + +class UserDontExistException(SupersetException): + pass + + +def json_success(json_msg, status=200): + return Response(json_msg, status=status, mimetype='application/json') + + +class Lyft(Superset): + @staticmethod + def authorize(): + """Provides access if token, impersonates if specified""" + if not security_manager.has_tom_key(): + raise SupersetException('Wrong key') + + email = request.headers.get('IMPERSONATE') + if email: + user = security_manager.find_user(email=email) + if not user: + raise UserDontExistException('Email to impersonate not found') + g.user = user + + @has_access_api + @expose('/sql_json/', methods=['POST', 'GET']) + @log_this + def sql_json(self): + try: + Lyft.authorize() + except UserDontExistException as e: + return json_error_response('{}'.format(e), status=412) + except SupersetException as e: + return json_error_response('{}'.format(e)) + return self.sql_json_call(request) + + +appbuilder.add_view_no_menu(Lyft) diff --git a/tests/security_tests.py b/tests/security_tests.py index 423b58bee133b..55afc0b48d61c 100644 --- a/tests/security_tests.py +++ b/tests/security_tests.py @@ -247,6 +247,9 @@ def test_views_are_secured(self): ['Superset', 'log'], ['Superset', 'theme'], ['Superset', 'welcome'], + ['Lyft', 'log'], + ['Lyft', 'theme'], + ['Lyft', 'welcome'], ] unsecured_views = [] for view_class in appbuilder.baseviews: