Skip to content

Commit

Permalink
fix: dataset name change and permission change (apache#21161)
Browse files Browse the repository at this point in the history
* fix: dataset name change and permission change

(cherry picked from commit 3f2e894)
  • Loading branch information
dpgaspar authored and zef committed Sep 15, 2022
1 parent e7b23de commit 309d506
Show file tree
Hide file tree
Showing 9 changed files with 1,278 additions and 384 deletions.
7 changes: 4 additions & 3 deletions superset/connectors/sqla/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2266,11 +2266,11 @@ def after_insert(
For more context: https://github.com/apache/superset/issues/14909
"""
security_manager.set_perm(mapper, connection, sqla_table)
security_manager.dataset_after_insert(mapper, connection, sqla_table)
sqla_table.write_shadow_dataset()

@staticmethod
def after_delete( # pylint: disable=unused-argument
def after_delete(
mapper: Mapper,
connection: Connection,
sqla_table: "SqlaTable",
Expand All @@ -2287,6 +2287,7 @@ def after_delete( # pylint: disable=unused-argument
For more context: https://github.com/apache/superset/issues/14909
"""
security_manager.dataset_after_delete(mapper, connection, sqla_table)
session = inspect(sqla_table).session
dataset = (
session.query(NewDataset).filter_by(uuid=sqla_table.uuid).one_or_none()
Expand All @@ -2313,7 +2314,7 @@ def after_update(
For more context: https://github.com/apache/superset/issues/14909
"""
# set permissions
security_manager.set_perm(mapper, connection, sqla_table)
security_manager.dataset_after_update(mapper, connection, sqla_table)

inspector = inspect(sqla_table)
session = inspector.session
Expand Down
34 changes: 34 additions & 0 deletions superset/databases/commands/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from superset.databases.dao import DatabaseDAO
from superset.extensions import db, security_manager
from superset.models.core import Database
from superset.utils.core import DatasourceType

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -66,8 +67,10 @@ def run(self) -> Model:
except Exception as ex:
db.session.rollback()
raise DatabaseConnectionFailedError() from ex

# Update database schema permissions
new_schemas: List[str] = []

for schema in schemas:
old_view_menu_name = security_manager.get_schema_perm(
old_database_name, schema
Expand All @@ -81,6 +84,10 @@ def run(self) -> Model:
# Update the schema permission if the database name changed
if schema_pvm and old_database_name != database.database_name:
schema_pvm.view_menu.name = new_view_menu_name

self._propagate_schema_permissions(
old_view_menu_name, new_view_menu_name
)
else:
new_schemas.append(schema)
for schema in new_schemas:
Expand All @@ -94,6 +101,33 @@ def run(self) -> Model:
raise DatabaseUpdateFailedError() from ex
return database

@staticmethod
def _propagate_schema_permissions(
old_view_menu_name: str, new_view_menu_name: str
) -> None:
from superset.connectors.sqla.models import ( # pylint: disable=import-outside-toplevel
SqlaTable,
)
from superset.models.slice import ( # pylint: disable=import-outside-toplevel
Slice,
)

# Update schema_perm on all datasets
datasets = (
db.session.query(SqlaTable)
.filter(SqlaTable.schema_perm == old_view_menu_name)
.all()
)
for dataset in datasets:
dataset.schema_perm = new_view_menu_name
charts = db.session.query(Slice).filter(
Slice.datasource_type == DatasourceType.TABLE,
Slice.datasource_id == dataset.id,
)
# Update schema_perm on all charts
for chart in charts:
chart.schema_perm = new_view_menu_name

def validate(self) -> None:
exceptions: List[ValidationError] = []
# Validate/populate model exists
Expand Down
11 changes: 1 addition & 10 deletions superset/datasets/commands/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
TableNotFoundValidationError,
)
from superset.datasets.dao import DatasetDAO
from superset.extensions import db, security_manager
from superset.extensions import db

logger = logging.getLogger(__name__)

Expand All @@ -47,15 +47,6 @@ def run(self) -> Model:
dataset = DatasetDAO.create(self._properties, commit=False)
# Updates columns and metrics from the dataset
dataset.fetch_metadata(commit=False)
# Add datasource access permission
security_manager.add_permission_view_menu(
"datasource_access", dataset.get_perm()
)
# Add schema access permission if exists
if dataset.schema:
security_manager.add_permission_view_menu(
"schema_access", dataset.schema_perm
)
db.session.commit()
except (SQLAlchemyError, DAOCreateFailedError) as ex:
logger.warning(ex, exc_info=True)
Expand Down
24 changes: 0 additions & 24 deletions superset/datasets/commands/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,6 @@ def run(self) -> Model:
self.validate()
try:
dataset = DatasetDAO.delete(self._model, commit=False)

view_menu = (
security_manager.find_view_menu(self._model.get_perm())
if self._model
else None
)

if view_menu:
permission_views = (
db.session.query(security_manager.permissionview_model)
.filter_by(view_menu=view_menu)
.all()
)

for permission_view in permission_views:
db.session.delete(permission_view)
if view_menu:
db.session.delete(view_menu)
else:
if not view_menu:
logger.error(
"Could not find the data access permission for the dataset",
exc_info=True,
)
db.session.commit()
except (SQLAlchemyError, DAODeleteFailedError) as ex:
logger.exception(ex)
Expand Down
2 changes: 1 addition & 1 deletion superset/models/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ def get_dialect(self) -> Dialect:
return sqla_url.get_dialect()()


sqla.event.listen(Database, "after_insert", security_manager.set_perm)
sqla.event.listen(Database, "after_insert", security_manager.database_after_insert)
sqla.event.listen(Database, "after_update", security_manager.database_after_update)
sqla.event.listen(Database, "after_delete", security_manager.database_after_delete)

Expand Down

0 comments on commit 309d506

Please sign in to comment.