diff --git a/RESOURCES/STANDARD_ROLES.md b/RESOURCES/STANDARD_ROLES.md index aa5654ec62..7e804ca75f 100644 --- a/RESOURCES/STANDARD_ROLES.md +++ b/RESOURCES/STANDARD_ROLES.md @@ -78,7 +78,6 @@ |can sync druid source on Superset|:heavy_check_mark:|O|O|O| |can explore on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| |can fave slices on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| -|can tables on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| |can slice json on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| |can approve on Superset|:heavy_check_mark:|O|O|O| |can explore json on Superset|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|O| diff --git a/UPDATING.md b/UPDATING.md index 2117087908..963e8490cf 100644 --- a/UPDATING.md +++ b/UPDATING.md @@ -34,6 +34,7 @@ assists people when migrating to a new version. ### Breaking Changes +- [24342](https://github.com/apache/superset/pull/24342): Removed deprecated API `/superset/tables///...` - [24335](https://github.com/apache/superset/pull/24335): Removed deprecated API `/superset/filter////` - [24333](https://github.com/apache/superset/pull/24333): Removed deprecated API `/superset/datasources` - [24266](https://github.com/apache/superset/pull/24266) Remove the `ENABLE_ACCESS_REQUEST` config parameter and the associated request/approval workflows. diff --git a/superset/views/core.py b/superset/views/core.py index 5c9ad07ad6..ca3608749e 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -29,7 +29,6 @@ import pandas as pd import simplejson as json from flask import abort, flash, g, redirect, render_template, request, Response from flask_appbuilder import expose -from flask_appbuilder.models.sqla.interface import SQLAInterface from flask_appbuilder.security.decorators import ( has_access, has_access_api, @@ -39,7 +38,6 @@ from flask_appbuilder.security.sqla import models as ab_models from flask_babel import gettext as __, lazy_gettext as _ from sqlalchemy import and_, or_ from sqlalchemy.exc import DBAPIError, NoSuchModuleError, SQLAlchemyError -from sqlalchemy.orm import lazyload, load_only from superset import ( app, @@ -73,7 +71,6 @@ from superset.dashboards.permalink.commands.get import GetDashboardPermalinkComm from superset.dashboards.permalink.exceptions import DashboardPermalinkGetFailedError from superset.databases.commands.exceptions import DatabaseInvalidError from superset.databases.dao import DatabaseDAO -from superset.databases.filters import DatabaseFilter from superset.databases.utils import make_url_safe from superset.datasets.commands.exceptions import DatasetNotFoundError from superset.datasource.dao import DatasourceDAO @@ -887,111 +884,6 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods return json_success(json.dumps(response)) - @api - @has_access_api - @event_logger.log_this - @expose("/tables///") - @expose("/tables////") - @deprecated(new_target="api/v1/database//tables/") - def tables( # pylint: disable=no-self-use - self, - db_id: int, - schema: str, - force_refresh: str = "false", - ) -> FlaskResponse: - """Endpoint to fetch the list of tables for given database""" - - force_refresh_parsed = force_refresh.lower() == "true" - schema_parsed = utils.parse_js_uri_path_item(schema, eval_undefined=True) - - if not schema_parsed: - return json_error_response(_("Schema undefined"), status=422) - - # Guarantees database filtering by security access - database = ( - DatabaseFilter("id", SQLAInterface(Database, db.session)) - .apply( - db.session.query(Database), - None, - ) - .filter_by(id=db_id) - .one_or_none() - ) - - if not database: - return json_error_response( - __("Database not found: %(id)s", id=db_id), status=404 - ) - - try: - tables = security_manager.get_datasources_accessible_by_user( - database=database, - schema=schema_parsed, - datasource_names=sorted( - utils.DatasourceName(*datasource_name) - for datasource_name in database.get_all_table_names_in_schema( - schema=schema_parsed, - force=force_refresh_parsed, - cache=database.table_cache_enabled, - cache_timeout=database.table_cache_timeout, - ) - ), - ) - - views = security_manager.get_datasources_accessible_by_user( - database=database, - schema=schema_parsed, - datasource_names=sorted( - utils.DatasourceName(*datasource_name) - for datasource_name in database.get_all_view_names_in_schema( - schema=schema_parsed, - force=force_refresh_parsed, - cache=database.table_cache_enabled, - cache_timeout=database.table_cache_timeout, - ) - ), - ) - except SupersetException as ex: - return json_error_response(ex.message, ex.status) - - extra_dict_by_name = { - table.name: table.extra_dict - for table in ( - db.session.query(SqlaTable) - .filter( - SqlaTable.database_id == database.id, - SqlaTable.schema == schema_parsed, - ) - .options( - load_only(SqlaTable.schema, SqlaTable.table_name, SqlaTable.extra), - lazyload(SqlaTable.columns), - lazyload(SqlaTable.metrics), - ) - ).all() - } - - options = sorted( - [ - { - "value": table.table, - "type": "table", - "extra": extra_dict_by_name.get(table.table, None), - } - for table in tables - ] - + [ - { - "value": view.table, - "type": "view", - } - for view in views - ], - key=lambda item: item["value"], - ) - - payload = {"tableLength": len(tables) + len(views), "options": options} - return json_success(json.dumps(payload)) - @api @has_access_api @event_logger.log_this diff --git a/tests/integration_tests/core_tests.py b/tests/integration_tests/core_tests.py index 230101b39a..cd994481ad 100644 --- a/tests/integration_tests/core_tests.py +++ b/tests/integration_tests/core_tests.py @@ -151,85 +151,6 @@ class TestCore(SupersetTestCase): self.assertEqual(cache_key_with_groupby, viz.cache_key(qobj)) - def test_get_superset_tables_not_allowed(self): - example_db = superset.utils.database.get_example_database() - schema_name = self.default_schema_backend_map[example_db.backend] - self.login(username="gamma") - uri = f"superset/tables/{example_db.id}/{schema_name}/" - rv = self.client.get(uri) - self.assertEqual(rv.status_code, 404) - - @pytest.mark.usefixtures("load_energy_table_with_slice") - def test_get_superset_tables_allowed(self): - session = db.session - table_name = "energy_usage" - role_name = "dummy_role" - self.logout() - self.login(username="gamma") - gamma_user = security_manager.find_user(username="gamma") - security_manager.add_role(role_name) - dummy_role = security_manager.find_role(role_name) - gamma_user.roles.append(dummy_role) - - tbl_id = self.table_ids.get(table_name) - table = db.session.query(SqlaTable).filter(SqlaTable.id == tbl_id).first() - table_perm = table.perm - - security_manager.add_permission_role( - dummy_role, - security_manager.find_permission_view_menu("datasource_access", table_perm), - ) - - session.commit() - - example_db = utils.get_example_database() - schema_name = self.default_schema_backend_map[example_db.backend] - uri = f"superset/tables/{example_db.id}/{schema_name}/" - rv = self.client.get(uri) - self.assertEqual(rv.status_code, 200) - - # cleanup - gamma_user = security_manager.find_user(username="gamma") - gamma_user.roles.remove(security_manager.find_role(role_name)) - session.commit() - - @pytest.mark.usefixtures("load_energy_table_with_slice") - def test_get_superset_tables_not_allowed_with_out_permissions(self): - session = db.session - role_name = "dummy_role_no_table_access" - self.logout() - self.login(username="gamma") - gamma_user = security_manager.find_user(username="gamma") - security_manager.add_role(role_name) - dummy_role = security_manager.find_role(role_name) - gamma_user.roles.append(dummy_role) - - session.commit() - - example_db = utils.get_example_database() - schema_name = self.default_schema_backend_map[example_db.backend] - uri = f"superset/tables/{example_db.id}/{schema_name}/" - rv = self.client.get(uri) - self.assertEqual(rv.status_code, 404) - - # cleanup - gamma_user = security_manager.find_user(username="gamma") - gamma_user.roles.remove(security_manager.find_role(role_name)) - session.commit() - - def test_get_superset_tables_database_not_found(self): - self.login(username="admin") - uri = f"superset/tables/invalid/public/" - rv = self.client.get(uri) - self.assertEqual(rv.status_code, 404) - - def test_get_superset_tables_schema_undefined(self): - example_db = superset.utils.database.get_example_database() - self.login(username="gamma") - uri = f"superset/tables/{example_db.id}/undefined/" - rv = self.client.get(uri) - self.assertEqual(rv.status_code, 422) - def test_admin_only_menu_views(self): def assert_admin_view_menus_in(role_name, assert_func): role = security_manager.find_role(role_name)