Warning
This document is for an old release of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.
Source code for galaxy.webapps.galaxy.services.library_folder_contents
import logging
from dataclasses import dataclass
from typing import List
from galaxy import (
exceptions,
model,
util,
)
from galaxy.managers import base as managers_base
from galaxy.managers.context import ProvidesUserContext
from galaxy.managers.folders import FolderManager
from galaxy.managers.hdas import HDAManager
from galaxy.model import tags
from galaxy.model.security import GalaxyRBACAgent
from galaxy.schema.fields import LibraryFolderDatabaseIdField
from galaxy.schema.schema import (
AnyLibraryFolderItem,
CreateLibraryFilePayload,
FileLibraryFolderItem,
FolderLibraryFolderItem,
LibraryFolderContentsIndexQueryPayload,
LibraryFolderContentsIndexResult,
LibraryFolderMetadata,
)
from galaxy.security.idencoding import IdEncodingHelper
from galaxy.webapps.base.controller import UsesLibraryMixinItems
from galaxy.webapps.galaxy.services.base import ServiceBase
log = logging.getLogger(__name__)
[docs]class LibraryFolderContentsService(ServiceBase, UsesLibraryMixinItems):
"""
Interface/service shared by controllers for interacting with the contents of a library folder.
"""
[docs] def __init__(self, security: IdEncodingHelper, hda_manager: HDAManager, folder_manager: FolderManager):
super().__init__(security)
self.hda_manager = hda_manager
self.folder_manager = folder_manager
[docs] def get_object(self, trans, id, class_name, check_ownership=False, check_accessible=False, deleted=None):
"""
Convenience method to get a model object with the specified checks.
"""
return managers_base.get_object(
trans, id, class_name, check_ownership=check_ownership, check_accessible=check_accessible, deleted=deleted
)
[docs] def index(
self,
trans: ProvidesUserContext,
folder_id: LibraryFolderDatabaseIdField,
payload: LibraryFolderContentsIndexQueryPayload,
) -> LibraryFolderContentsIndexResult:
"""
Displays a collection (list) of a folder's contents (files and folders). Encoded folder ID is prepended
with 'F' if it is a folder as opposed to a data set which does not have it. Full path is provided in
response as a separate object providing data for breadcrumb path building.
"""
folder: model.LibraryFolder = self.folder_manager.get(trans, folder_id)
current_user_roles = trans.get_current_user_roles()
user_permissions = self._retrieve_user_permissions_on_folder(trans, current_user_roles, folder)
tag_manager = tags.GalaxyTagHandler(trans.sa_session)
folder_contents: List[AnyLibraryFolderItem] = []
contents, total_rows = self.folder_manager.get_contents(trans, folder, payload)
for content_item in contents:
if isinstance(content_item, model.LibraryFolder):
folder_contents.append(self._serialize_library_folder(user_permissions, content_item))
elif isinstance(content_item, model.LibraryDataset):
folder_contents.append(
self._serialize_library_dataset(trans, current_user_roles, tag_manager, content_item)
)
metadata = self._serialize_library_folder_metadata(trans, folder, user_permissions, total_rows)
return LibraryFolderContentsIndexResult(metadata=metadata, folder_contents=folder_contents)
[docs] def create(
self,
trans: ProvidesUserContext,
folder_id: LibraryFolderDatabaseIdField,
payload: CreateLibraryFilePayload,
):
"""
Create a new library file from an HDA/HDCA.
"""
if trans.user_is_bootstrap_admin:
raise exceptions.RealUserRequiredException("Only real users can create a new library file.")
self.check_user_is_authenticated(trans)
decoded_hda_id = payload.from_hda_id
decoded_hdca_id = payload.from_hdca_id
ldda_message = payload.ldda_message
try:
if decoded_hda_id:
return self._copy_hda_to_library_folder(
trans, self.hda_manager, decoded_hda_id, folder_id, ldda_message
)
if decoded_hdca_id:
return self._copy_hdca_to_library_folder(
trans, self.hda_manager, decoded_hdca_id, folder_id, ldda_message
)
except Exception as exc:
# TODO handle exceptions better within the mixins
exc_message = util.unicodify(exc)
if (
"not accessible to the current user" in exc_message
or "You are not allowed to access this dataset" in exc_message
):
raise exceptions.ItemAccessibilityException("You do not have access to the requested item")
else:
log.exception(exc)
raise exc
def _retrieve_user_permissions_on_folder(
self, trans: ProvidesUserContext, current_user_roles: List[model.Role], folder: model.LibraryFolder
) -> UserFolderPermissions:
"""Returns the permissions of the user for the given folder.
Raises an ObjectNotFound exception if the user has no access to the parent library.
"""
if trans.user_is_admin:
return UserFolderPermissions(access=True, modify=True, add=True, manage=True)
security_agent: GalaxyRBACAgent = trans.app.security_agent
can_access_library = security_agent.can_access_library(current_user_roles, folder.parent_library)
if can_access_library:
return UserFolderPermissions(
access=True, # Access to the parent library means access to any sub-folder
modify=security_agent.can_modify_library_item(current_user_roles, folder),
add=security_agent.can_add_library_item(current_user_roles, folder),
manage=security_agent.can_manage_library_item(current_user_roles, folder),
)
warning_message = (
f"SECURITY: User (id: {trans.user.id}) without proper access rights is trying to load folder with ID of {folder.id}"
if trans.user
else f"SECURITY: Anonymous user is trying to load restricted folder with ID of {folder.id}"
)
log.warning(warning_message)
raise exceptions.ObjectNotFound(f"Folder with the id provided ( F{self.encode_id(folder.id)} ) was not found")
def _serialize_library_dataset(
self,
trans: ProvidesUserContext,
current_user_roles: List[model.Role],
tag_manager: tags.GalaxyTagHandler,
library_dataset: model.LibraryDataset,
) -> FileLibraryFolderItem:
security_agent = trans.app.security_agent
is_admin = trans.user_is_admin
ldda = library_dataset.library_dataset_dataset_association
dataset = ldda.dataset
# Access rights are checked on the dataset level, not on the ld or ldda level to maintain consistency
is_unrestricted = security_agent.dataset_is_public(dataset)
raw_size = int(ldda.get_size())
library_dataset_dict = library_dataset.to_dict()
dataset_item = FileLibraryFolderItem(
id=library_dataset.id,
name=library_dataset.name,
type="file",
create_time=library_dataset.create_time.isoformat(),
update_time=ldda.update_time.isoformat(),
can_manage=is_admin or bool(trans.user and security_agent.can_manage_dataset(current_user_roles, dataset)),
deleted=library_dataset.deleted,
file_ext=library_dataset_dict["file_ext"],
date_uploaded=library_dataset_dict["date_uploaded"],
# Is the dataset public or private?
# When both are False the dataset is 'restricted'
is_unrestricted=is_unrestricted,
is_private=not is_unrestricted and trans.user and security_agent.dataset_is_private_to_user(trans, dataset),
state=library_dataset_dict["state"],
file_size=util.nice_size(raw_size),
raw_size=raw_size,
ldda_id=ldda.id,
tags=tag_manager.get_tags_list(ldda.tags),
message=ldda.message or ldda.info,
)
return dataset_item
def _serialize_library_folder(
self, user_permissions: UserFolderPermissions, folder: model.LibraryFolder
) -> FolderLibraryFolderItem:
folder_item = FolderLibraryFolderItem(
id=folder.id,
name=folder.name,
type="folder",
create_time=folder.create_time.isoformat(),
update_time=folder.update_time.isoformat(),
can_manage=user_permissions.manage,
deleted=folder.deleted,
can_modify=user_permissions.modify,
description=folder.description,
)
return folder_item
def _serialize_library_folder_metadata(
self,
trans: ProvidesUserContext,
folder: model.LibraryFolder,
user_permissions: UserFolderPermissions,
total_rows: int,
) -> LibraryFolderMetadata:
full_path = self.folder_manager.build_folder_path(trans.sa_session, folder)
parent_library_id = folder.parent_library.id if folder.parent_library else None
metadata = LibraryFolderMetadata(
full_path=full_path,
total_rows=total_rows,
can_add_library_item=user_permissions.add,
can_modify_folder=user_permissions.modify,
folder_name=folder.name,
folder_description=folder.description,
parent_library_id=parent_library_id,
)
return metadata