zephyring commented on code in PR #20081:
URL: https://github.com/apache/superset/pull/20081#discussion_r933544268
##########
superset/security/manager.py:
##########
@@ -933,6 +941,222 @@ def _is_granter_pvm( # pylint: disable=no-self-use
return pvm.permission.name in {"can_override_role_permissions",
"can_approve"}
+ def database_after_delete(
+ self,
+ mapper: Mapper,
+ connection: Connection,
+ target: "Database",
+ ) -> None:
+ self._delete_vm_database_access(
+ mapper, connection, target.id, target.database_name
+ )
+
+ def _delete_vm_database_access(
+ self,
+ mapper: Mapper,
+ connection: Connection,
+ database_id: int,
+ database_name: str,
+ ) -> None:
+ view_menu_table = self.viewmenu_model.__table__ # pylint:
disable=no-member
+ permission_view_menu_table = (
+ self.permissionview_model.__table__ # pylint: disable=no-member
+ )
+ view_menu_name = self.get_database_perm(database_id, database_name)
+ # Clean database access permission
+ db_pvm = self.find_permission_view_menu("database_access",
view_menu_name)
+ if not db_pvm:
+ logger.warning(
+ "Could not find previous database permission %s",
+ view_menu_name,
+ )
+ return
+ connection.execute(
+ permission_view_menu_table.delete().where(
+ permission_view_menu_table.c.id == db_pvm.id
+ )
+ )
+ self.on_permission_after_delete(mapper, connection, db_pvm)
+ connection.execute(
+ view_menu_table.delete().where(view_menu_table.c.id ==
db_pvm.view_menu_id)
+ )
+
+ # Clean database schema permissions
+ schema_pvms = (
+ self.get_session.query(self.permissionview_model)
+ .join(self.permission_model)
+ .join(self.viewmenu_model)
+ .filter(self.permission_model.name == "schema_access")
+ .filter(self.viewmenu_model.name.like(f"[{database_name}].[%]"))
+ .all()
+ )
+ for schema_pvm in schema_pvms:
+ connection.execute(
+ permission_view_menu_table.delete().where(
+ permission_view_menu_table.c.id == schema_pvm.id
+ )
+ )
+ self.on_permission_after_delete(mapper, connection, schema_pvm)
+ connection.execute(
+ view_menu_table.delete().where(
+ view_menu_table.c.id == schema_pvm.view_menu_id
+ )
+ )
+
+ def _update_vm_database_access(
+ self,
+ mapper: Mapper,
+ connection: Connection,
+ old_database_name: str,
+ target: "Database",
+ ) -> Optional[ViewMenu]:
+ view_menu_table = self.viewmenu_model.__table__ # pylint:
disable=no-member
+ new_database_name = target.database_name
+ old_view_menu_name = self.get_database_perm(target.id,
old_database_name)
+ new_view_menu_name = self.get_database_perm(target.id,
new_database_name)
+ db_pvm = self.find_permission_view_menu("database_access",
old_view_menu_name)
+ if not db_pvm:
+ logger.warning(
+ "Could not find previous database permission %s",
+ old_view_menu_name,
+ )
+ return None
+ new_updated_pvm = self.find_permission_view_menu(
+ "database_access", new_view_menu_name
+ )
+ if new_updated_pvm:
+ logger.info(
+ "New permission [%s] already exists, deleting the previous",
+ new_view_menu_name,
+ )
+ self._delete_vm_database_access(
+ mapper, connection, target.id, old_database_name
+ )
+ return None
+ connection.execute(
+ view_menu_table.update()
+ .where(view_menu_table.c.id == db_pvm.view_menu_id)
+ .values(name=new_view_menu_name)
+ )
+ new_db_view_menu = self.find_view_menu(new_view_menu_name)
+
+ self.on_view_menu_after_update(mapper, connection, new_db_view_menu)
+ return new_db_view_menu
+
+ def _update_vm_datasources_access( # pylint: disable=too-many-locals
+ self,
+ mapper: Mapper,
+ connection: Connection,
+ old_database_name: str,
+ target: "Database",
+ ) -> List[ViewMenu]:
+ """
+ Updates all datasource access permission when a database name changes
+
+ :param connection: Current connection (called on SQLAlchemy event
listener scope)
+ :param old_database_name: the old database name
+ :param target: The new database name
+ :return: A list of changed view menus (permission resource names)
+ """
+ from superset.connectors.sqla.models import ( # pylint:
disable=import-outside-toplevel
+ SqlaTable,
+ )
+ from superset.models.slice import ( # pylint:
disable=import-outside-toplevel
+ Slice,
+ )
+
+ view_menu_table = self.viewmenu_model.__table__ # pylint:
disable=no-member
+ sqlatable_table = SqlaTable.__table__ # pylint: disable=no-member
+ chart_table = Slice.__table__ # pylint: disable=no-member
+ new_database_name = target.database_name
+ datasets = (
+ self.get_session.query(SqlaTable)
+ .filter(SqlaTable.database_id == target.id)
+ .all()
+ )
+ updated_view_menus: List[ViewMenu] = []
+ for dataset in datasets:
+ old_dataset_vm_name = self.get_dataset_perm(
+ dataset.id, dataset.table_name, old_database_name
+ )
+ new_dataset_vm_name = self.get_dataset_perm(
+ dataset.id, dataset.table_name, new_database_name
+ )
+ new_dataset_view_menu = self.find_view_menu(new_dataset_vm_name)
+ if new_dataset_view_menu:
+ continue
+ connection.execute(
+ view_menu_table.update()
+ .where(view_menu_table.c.name == old_dataset_vm_name)
+ .values(name=new_dataset_vm_name)
+ )
+ # Update dataset (SqlaTable perm field)
+ connection.execute(
+ sqlatable_table.update()
+ .where(
+ sqlatable_table.c.id == dataset.id,
+ sqlatable_table.c.perm == old_dataset_vm_name,
Review Comment:
I think this line is unnecessary as you already filter by id
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]