lohart13 opened a new issue, #32872:
URL: https://github.com/apache/superset/issues/32872

   ### Bug description
   
   When the `SupersetSecurityManager.role_model`  is overridden to use a custom 
role, any updates where the `SupersetSecurityManager.find_roles_by_id` function 
is called will cause an error as the update command is using the 
`flask_appbuilder.security.sqla.models.Role` model instead of the user supplied 
`SupersetSecurityManager.role_model`.
   
   Making the below changes to the `SupersetSecurityManager` fixes the issue.
   
   
https://github.com/apache/superset/blob/50fe7483ae3f7fa02a476b9e5e384bd0031359d7/superset/security/manager.py#L1125-L1130
   
   
   ```python
       def find_roles_by_id(self, role_ids: list[int]) -> list[Role]:
           """
           Find a List of models by a list of ids, if defined applies 
`base_filter`
           """
           query = 
self.get_session.query(self.role_model).filter(self.role_model.id.in_(role_ids))
           return query.all()
   ```
   
   ### Screenshots/recordings
   
   _No response_
   
   ### Superset version
   
   master / latest-dev
   
   ### Python version
   
   3.9
   
   ### Node version
   
   18 or greater
   
   ### Browser
   
   Chrome
   
   ### Additional context
   
   ```
   superset  | Attempting to flush an item of type <class 
'flask_appbuilder.security.sqla.models.Role'> as a member of collection 
"Dashboard.roles". Expected an object of type <class 'models.CustomRole'> or a 
polymorphic subclass of this type.
   superset  | Traceback (most recent call last):
   superset  |   File "/app/superset/daos/base.py", line 188, in update
   superset  |     db.session.merge(item)
   superset  |   File "<string>", line 2, in merge
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2971, 
in merge
   superset  |     self._autoflush()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2230, 
in _autoflush
   superset  |     self.flush()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3367, 
in flush
   superset  |     self._flush(objects)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3507, 
in _flush
   superset  |     transaction.rollback(_capture_exception=True)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 
70, in __exit__
   superset  |     compat.raise_(
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, 
in raise_
   superset  |     raise exception
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3467, 
in _flush
   superset  |     flush_context.execute()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 
456, in execute
   superset  |     rec.execute(self)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 
579, in execute
   superset  |     self.dependency_processor.process_saves(uow, states)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
1136, in process_saves
   superset  |     if not self._synchronize(
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
1252, in _synchronize
   superset  |     self._verify_canload(child)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
283, in _verify_canload
   superset  |     raise exc.FlushError(
   superset  | sqlalchemy.orm.exc.FlushError: Attempting to flush an item of 
type <class 'flask_appbuilder.security.sqla.models.Role'> as a member of 
collection "Dashboard.roles". Expected an object of type <class 
'models.CustomRole'> or a polymorphic subclass of this type.
   superset  | 
   superset  | The above exception was the direct cause of the following 
exception:
   superset  | 
   superset  | Traceback (most recent call last):
   superset  |   File "/app/superset/commands/dashboard/update.py", line 54, in 
run
   superset  |     dashboard = DashboardDAO.update(self._model, 
self._properties, commit=False)
   superset  |   File "/app/superset/daos/base.py", line 194, in update
   superset  |     raise DAOUpdateFailedError(exception=ex) from ex
   superset  | superset.daos.exceptions.DAOUpdateFailedError: Update failed
   superset  | 2025-03-27 
00:27:07,447:ERROR:superset.commands.dashboard.update:Attempting to flush an 
item of type <class 'flask_appbuilder.security.sqla.models.Role'> as a member 
of collection "Dashboard.roles". Expected an object of type <class 
'models.CustomRole'> or a polymorphic subclass of this type.
   superset  | Traceback (most recent call last):
   superset  |   File "/app/superset/daos/base.py", line 188, in update
   superset  |     db.session.merge(item)
   superset  |   File "<string>", line 2, in merge
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2971, 
in merge
   superset  |     self._autoflush()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2230, 
in _autoflush
   superset  |     self.flush()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3367, 
in flush
   superset  |     self._flush(objects)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3507, 
in _flush
   superset  |     transaction.rollback(_capture_exception=True)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 
70, in __exit__
   superset  |     compat.raise_(
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, 
in raise_
   superset  |     raise exception
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3467, 
in _flush
   superset  |     flush_context.execute()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 
456, in execute
   superset  |     rec.execute(self)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 
579, in execute
   superset  |     self.dependency_processor.process_saves(uow, states)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
1136, in process_saves
   superset  |     if not self._synchronize(
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
1252, in _synchronize
   superset  |     self._verify_canload(child)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
283, in _verify_canload
   superset  |     raise exc.FlushError(
   superset  | sqlalchemy.orm.exc.FlushError: Attempting to flush an item of 
type <class 'flask_appbuilder.security.sqla.models.Role'> as a member of 
collection "Dashboard.roles". Expected an object of type <class 
'models.CustomRole'> or a polymorphic subclass of this type.
   superset  | 
   superset  | The above exception was the direct cause of the following 
exception:
   superset  | 
   superset  | Traceback (most recent call last):
   superset  |   File "/app/superset/commands/dashboard/update.py", line 54, in 
run
   superset  |     dashboard = DashboardDAO.update(self._model, 
self._properties, commit=False)
   superset  |   File "/app/superset/daos/base.py", line 194, in update
   superset  |     raise DAOUpdateFailedError(exception=ex) from ex
   superset  | superset.daos.exceptions.DAOUpdateFailedError: Update failed
   superset  | Error updating model DashboardRestApi: Dashboard could not be 
updated.
   superset  | Traceback (most recent call last):
   superset  |   File "/app/superset/daos/base.py", line 188, in update
   superset  |     db.session.merge(item)
   superset  |   File "<string>", line 2, in merge
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2971, 
in merge
   superset  |     self._autoflush()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2230, 
in _autoflush
   superset  |     self.flush()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3367, 
in flush
   superset  |     self._flush(objects)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3507, 
in _flush
   superset  |     transaction.rollback(_capture_exception=True)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 
70, in __exit__
   superset  |     compat.raise_(
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, 
in raise_
   superset  |     raise exception
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3467, 
in _flush
   superset  |     flush_context.execute()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 
456, in execute
   superset  |     rec.execute(self)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 
579, in execute
   superset  |     self.dependency_processor.process_saves(uow, states)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
1136, in process_saves
   superset  |     if not self._synchronize(
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
1252, in _synchronize
   superset  |     self._verify_canload(child)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
283, in _verify_canload
   superset  |     raise exc.FlushError(
   superset  | sqlalchemy.orm.exc.FlushError: Attempting to flush an item of 
type <class 'flask_appbuilder.security.sqla.models.Role'> as a member of 
collection "Dashboard.roles". Expected an object of type <class 
'models.CustomRole'> or a polymorphic subclass of this type.
   superset  | 
   superset  | The above exception was the direct cause of the following 
exception:
   superset  | 
   superset  | Traceback (most recent call last):
   superset  |   File "/app/superset/commands/dashboard/update.py", line 54, in 
run
   superset  |     dashboard = DashboardDAO.update(self._model, 
self._properties, commit=False)
   superset  |   File "/app/superset/daos/base.py", line 194, in update
   superset  |     raise DAOUpdateFailedError(exception=ex) from ex
   superset  | superset.daos.exceptions.DAOUpdateFailedError: Update failed
   superset  | 
   superset  | The above exception was the direct cause of the following 
exception:
   superset  | 
   superset  | Traceback (most recent call last):
   superset  |   File "/app/superset/dashboards/api.py", line 566, in put
   superset  |     changed_model = UpdateDashboardCommand(pk, item).run()
   superset  |   File "/app/superset/commands/dashboard/update.py", line 64, in 
run
   superset  |     raise DashboardUpdateFailedError() from ex
   superset  | 
superset.commands.dashboard.exceptions.DashboardUpdateFailedError: Dashboard 
could not be updated.
   superset  | 2025-03-27 00:27:07,448:ERROR:superset.dashboards.api:Error 
updating model DashboardRestApi: Dashboard could not be updated.
   superset  | Traceback (most recent call last):
   superset  |   File "/app/superset/daos/base.py", line 188, in update
   superset  |     db.session.merge(item)
   superset  |   File "<string>", line 2, in merge
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2971, 
in merge
   superset  |     self._autoflush()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 2230, 
in _autoflush
   superset  |     self.flush()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3367, 
in flush
   superset  |     self._flush(objects)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3507, 
in _flush
   superset  |     transaction.rollback(_capture_exception=True)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 
70, in __exit__
   superset  |     compat.raise_(
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, 
in raise_
   superset  |     raise exception
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 3467, 
in _flush
   superset  |     flush_context.execute()
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 
456, in execute
   superset  |     rec.execute(self)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/unitofwork.py", line 
579, in execute
   superset  |     self.dependency_processor.process_saves(uow, states)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
1136, in process_saves
   superset  |     if not self._synchronize(
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
1252, in _synchronize
   superset  |     self._verify_canload(child)
   superset  |   File 
"/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/dependency.py", line 
283, in _verify_canload
   superset  |     raise exc.FlushError(
   superset  | sqlalchemy.orm.exc.FlushError: Attempting to flush an item of 
type <class 'flask_appbuilder.security.sqla.models.Role'> as a member of 
collection "Dashboard.roles". Expected an object of type <class 
'models.CustomRole'> or a polymorphic subclass of this type.
   superset  | 
   superset  | The above exception was the direct cause of the following 
exception:
   superset  | 
   superset  | Traceback (most recent call last):
   superset  |   File "/app/superset/commands/dashboard/update.py", line 54, in 
run
   superset  |     dashboard = DashboardDAO.update(self._model, 
self._properties, commit=False)
   superset  |   File "/app/superset/daos/base.py", line 194, in update
   superset  |     raise DAOUpdateFailedError(exception=ex) from ex
   superset  | superset.daos.exceptions.DAOUpdateFailedError: Update failed
   superset  | 
   superset  | The above exception was the direct cause of the following 
exception:
   superset  | 
   superset  | Traceback (most recent call last):
   superset  |   File "/app/superset/dashboards/api.py", line 566, in put
   superset  |     changed_model = UpdateDashboardCommand(pk, item).run()
   superset  |   File "/app/superset/commands/dashboard/update.py", line 64, in 
run
   superset  |     raise DashboardUpdateFailedError() from ex
   superset  | 
superset.commands.dashboard.exceptions.DashboardUpdateFailedError: Dashboard 
could not be updated.
   
   ### Checklist
   
   - [x] I have searched Superset docs and Slack and didn't find a solution to 
my problem.
   - [x] I have searched the GitHub issue tracker and didn't find a similar bug 
report.
   - [x] I have checked Superset's logs for errors and if I found a relevant 
Python stacktrace, I included it here as text in the "additional context" 
section.


-- 
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: notifications-unsubscr...@superset.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@superset.apache.org
For additional commands, e-mail: notifications-h...@superset.apache.org

Reply via email to