mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-30 18:13:23 +08:00
Optimize dataset get_edit API by deferring expensive role queries
Move get_legitimate_roles, get_private_role_user_emails_dict, and can_manage_dataset calls into the conditional branch where they are actually needed (only when user is logged in AND dataset has permission actions set). This avoids expensive full-table role/email queries for anonymous users, public datasets, and non-shareable datasets. Also scope get_private_role_user_emails_dict to only fetch email mappings for the specific role IDs returned by get_legitimate_roles, rather than scanning all private roles in the system.
This commit is contained in:
@@ -53,8 +53,14 @@ def get_displayable_roles(session, trans_user, user_is_admin, security_agent):
|
||||
return roles
|
||||
|
||||
|
||||
def get_private_role_user_emails_dict(session) -> dict[int, str]:
|
||||
"""Return a mapping of private role ids to user emails."""
|
||||
def get_private_role_user_emails_dict(session, role_ids: set[int] | None = None) -> dict[int, str]:
|
||||
"""Return a mapping of private role ids to user emails.
|
||||
|
||||
If role_ids is provided, only return mappings for roles in that set,
|
||||
avoiding a full table scan on large instances.
|
||||
"""
|
||||
stmt = select(UserRoleAssociation.role_id, User.email).join(Role).join(User).where(Role.type == Role.types.PRIVATE)
|
||||
if role_ids is not None:
|
||||
stmt = stmt.where(UserRoleAssociation.role_id.in_(role_ids))
|
||||
roleid_email_tuples = session.execute(stmt).all()
|
||||
return dict(roleid_email_tuples)
|
||||
|
||||
@@ -159,17 +159,8 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE
|
||||
]
|
||||
ldatatypes.sort()
|
||||
|
||||
private_role_emails = get_private_role_user_emails_dict(trans.sa_session)
|
||||
role_tuples = []
|
||||
for role in trans.app.security_agent.get_legitimate_roles(trans, data.dataset, "root"):
|
||||
displayed_name = private_role_emails.get(role.id, role.name)
|
||||
role_tuples.append((displayed_name, trans.security.encode_id(role.id)))
|
||||
|
||||
data_metadata = list(data.metadata.spec.items())
|
||||
converters_collection = [(key, value.name) for key, value in data.get_converter_types().items()]
|
||||
can_manage_dataset = trans.app.security_agent.can_manage_dataset(
|
||||
trans.get_current_user_roles(), data.dataset
|
||||
)
|
||||
# attribute editing
|
||||
attribute_inputs = [
|
||||
{"name": "name", "type": "text", "label": "Name", "value": data.get_display_name()},
|
||||
@@ -258,6 +249,18 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE
|
||||
{"name": "not_shareable", "type": "hidden", "label": permission_message, "readonly": True}
|
||||
)
|
||||
elif data.dataset.actions:
|
||||
can_manage_dataset = trans.app.security_agent.can_manage_dataset(
|
||||
trans.get_current_user_roles(), data.dataset
|
||||
)
|
||||
legitimate_roles = trans.app.security_agent.get_legitimate_roles(trans, data.dataset, "root")
|
||||
legitimate_role_ids = {role.id for role in legitimate_roles}
|
||||
private_role_emails = get_private_role_user_emails_dict(
|
||||
trans.sa_session, role_ids=legitimate_role_ids
|
||||
)
|
||||
role_tuples = [
|
||||
(private_role_emails.get(role.id, role.name), trans.security.encode_id(role.id))
|
||||
for role in legitimate_roles
|
||||
]
|
||||
in_roles = {}
|
||||
for action, roles in trans.app.security_agent.get_permissions(data.dataset).items():
|
||||
in_roles[action.action] = [trans.security.encode_id(role.id) for role in roles]
|
||||
|
||||
Reference in New Issue
Block a user