def _load_role(self, trans, role_name): """ Method loads the role from the DB based on the given role name. :param role_name: name of the role to load from the DB :type role_name: string :rtype: Role :returns: the loaded Role object :raises: InconsistentDatabase, RequestParameterInvalidException, InternalServerError """ try: role = trans.sa_session.query(trans.app.model.Role).filter( trans.model.Role.table.c.name == role_name).one() except MultipleResultsFound: raise exceptions.InconsistentDatabase( 'Multiple roles found with the same name. Name: ' + str(role_name)) except NoResultFound: raise exceptions.RequestParameterInvalidException( 'No role found with the name provided. Name: ' + str(role_name)) except Exception, e: raise exceptions.InternalServerError( 'Error loading from the database.' + str(e))
def get(self, trans, decoded_library_id, check_accessible=True): """ Get the library from the DB. :param decoded_library_id: decoded library id :type decoded_library_id: int :param check_accessible: flag whether to check that user can access item :type check_accessible: bool :returns: the requested library :rtype: galaxy.model.Library """ try: library = trans.sa_session.query(trans.app.model.Library).filter( trans.app.model.Library.table.c.id == decoded_library_id).one() except MultipleResultsFound: raise exceptions.InconsistentDatabase( 'Multiple libraries found with the same id.') except NoResultFound: raise exceptions.RequestParameterInvalidException( 'No library found with the id provided.') except Exception as e: raise exceptions.InternalServerError( 'Error loading from the database.' + str(e)) library = self.secure(trans, library, check_accessible) return library
def get(self, trans, decoded_folder_id, check_manageable=False, check_accessible=True): """ Get the folder from the DB. :param decoded_folder_id: decoded folder id :type decoded_folder_id: int :param check_manageable: flag whether the check that user can manage item :type check_manageable: bool :param check_accessible: flag whether to check that user can access item :type check_accessible: bool :returns: the requested folder :rtype: LibraryFolder """ try: folder = trans.sa_session.query( trans.app.model.LibraryFolder).filter( trans.app.model.LibraryFolder.table.c.id == decoded_folder_id).one() except MultipleResultsFound: raise exceptions.InconsistentDatabase( 'Multiple folders found with the same id.') except NoResultFound: raise exceptions.RequestParameterInvalidException( 'No folder found with the id provided.') except Exception, e: raise exceptions.InternalServerError( 'Error loading from the database.' + str(e))
def get_api_key(self, trans, **kwd): """ def get_api_key( self, trans, **kwd ) * GET /api/authenticate/baseauth returns an API key for authenticated user based on BaseAuth headers :returns: api_key in json format :rtype: dict :raises: ObjectNotFound, HTTPBadRequest """ email, password = self._decode_baseauth( trans.environ.get('HTTP_AUTHORIZATION')) user = trans.sa_session.query(trans.app.model.User).filter( trans.app.model.User.table.c.email == email).all() if len(user) == 0: raise exceptions.ObjectNotFound('The user does not exist.') elif len(user) > 1: # DB is inconsistent and we have more users with the same email. raise exceptions.InconsistentDatabase( 'An error occured, please contact your administrator.') else: user = user[0] is_valid_user = self.app.auth_manager.check_password( user, password) if is_valid_user: key = self.api_keys_manager.get_or_create_api_key(user) return dict(api_key=key) else: raise exceptions.AuthenticationFailed('Invalid password.')
def workflow_request_to_run_config( work_request_context, workflow_invocation ): param_types = model.WorkflowRequestInputParameter.types history = workflow_invocation.history replacement_dict = {} inputs = {} param_map = {} copy_inputs_to_history = None for parameter in workflow_invocation.input_parameters: parameter_type = parameter.type if parameter_type == param_types.REPLACEMENT_PARAMETERS: replacement_dict[ parameter.name ] = parameter.value elif parameter_type == param_types.META_PARAMETERS: if parameter.name == "copy_inputs_to_history": copy_inputs_to_history = (parameter.value == "true") for input_association in workflow_invocation.input_datasets: inputs[ input_association.workflow_step_id ] = input_association.dataset for input_association in workflow_invocation.input_dataset_collections: inputs[ input_association.workflow_step_id ] = input_association.dataset_collection for input_association in workflow_invocation.input_step_parameters: inputs[ input_association.workflow_step_id ] = input_association.parameter_value if copy_inputs_to_history is None: raise exceptions.InconsistentDatabase("Failed to find copy_inputs_to_history parameter loading workflow_invocation from database.") workflow_run_config = WorkflowRunConfig( target_history=history, replacement_dict=replacement_dict, inputs=inputs, param_map=param_map, copy_inputs_to_history=copy_inputs_to_history, ) return workflow_run_config
def index( self, trans, library_id, **kwd ): """ index( self, trans, library_id, **kwd ) * GET /api/libraries/{library_id}/contents: Returns a list of library files and folders. .. note:: May be slow! Returns all content traversing recursively through all folders. .. seealso:: :class:`galaxy.webapps.galaxy.api.FolderContentsController.index` for a non-recursive solution :param library_id: the encoded id of the library :type library_id: str :returns: list of dictionaries of the form: * id: the encoded id of the library item * name: the 'library path' or relationship of the library item to the root * type: 'file' or 'folder' * url: the url to get detailed information on the library item :rtype: list :raises: MalformedId, InconsistentDatabase, RequestParameterInvalidException, InternalServerError """ rval = [] current_user_roles = trans.get_current_user_roles() def traverse( folder ): admin = trans.user_is_admin() rval = [] for subfolder in folder.active_folders: if not admin: can_access, folder_ids = trans.app.security_agent.check_folder_contents( trans.user, current_user_roles, subfolder ) if (admin or can_access) and not subfolder.deleted: subfolder.api_path = folder.api_path + '/' + subfolder.name subfolder.api_type = 'folder' rval.append( subfolder ) rval.extend( traverse( subfolder ) ) for ld in folder.datasets: if not admin: can_access = trans.app.security_agent.can_access_dataset( current_user_roles, ld.library_dataset_dataset_association.dataset ) if (admin or can_access) and not ld.deleted: ld.api_path = folder.api_path + '/' + ld.name ld.api_type = 'file' rval.append( ld ) return rval try: decoded_library_id = self.decode_id( library_id ) except Exception: raise exceptions.MalformedId( 'Malformed library id ( %s ) specified, unable to decode.' % library_id ) try: library = trans.sa_session.query( trans.app.model.Library ).filter( trans.app.model.Library.table.c.id == decoded_library_id ).one() except MultipleResultsFound: raise exceptions.InconsistentDatabase( 'Multiple libraries found with the same id.' ) except NoResultFound: raise exceptions.RequestParameterInvalidException( 'No library found with the id provided.' ) except Exception, e: raise exceptions.InternalServerError( 'Error loading from the database.' + str(e))
def _one_with_recast_errors(self, query): """ Call sqlalchemy's one and recast errors to serializable errors if any. :raises exceptions.ObjectNotFound: if no model is found :raises exceptions.InconsistentDatabase: if more than one model is found """ # overridden to raise serializable errors try: return query.one() except sqlalchemy.orm.exc.NoResultFound: raise exceptions.ObjectNotFound(self.model_class.__name__ + ' not found') except sqlalchemy.orm.exc.MultipleResultsFound: raise exceptions.InconsistentDatabase('found more than one ' + self.model_class.__name__)
def workflow_request_to_run_config(work_request_context, workflow_invocation): param_types = model.WorkflowRequestInputParameter.types history = workflow_invocation.history replacement_dict = {} inputs = {} param_map = {} resource_params = {} copy_inputs_to_history = None use_cached_job = False for parameter in workflow_invocation.input_parameters: parameter_type = parameter.type if parameter_type == param_types.REPLACEMENT_PARAMETERS: replacement_dict[parameter.name] = parameter.value elif parameter_type == param_types.META_PARAMETERS: if parameter.name == "copy_inputs_to_history": copy_inputs_to_history = (parameter.value == "true") if parameter.name == 'use_cached_job': use_cached_job = (parameter.value == 'true') elif parameter_type == param_types.RESOURCE_PARAMETERS: resource_params[parameter.name] = parameter.value elif parameter_type == param_types.STEP_PARAMETERS: param_map[int(parameter.name)] = json.loads(parameter.value) for input_association in workflow_invocation.input_datasets: inputs[input_association.workflow_step_id] = input_association.dataset for input_association in workflow_invocation.input_dataset_collections: inputs[input_association. workflow_step_id] = input_association.dataset_collection for input_association in workflow_invocation.input_step_parameters: parameter_value = input_association.parameter_value inputs[input_association.workflow_step_id] = parameter_value step_label = input_association.workflow_step.label if step_label and step_label not in replacement_dict: replacement_dict[step_label] = str(parameter_value) if copy_inputs_to_history is None: raise exceptions.InconsistentDatabase( "Failed to find copy_inputs_to_history parameter loading workflow_invocation from database." ) workflow_run_config = WorkflowRunConfig( target_history=history, replacement_dict=replacement_dict, inputs=inputs, param_map=param_map, copy_inputs_to_history=copy_inputs_to_history, use_cached_job=use_cached_job, resource_params=resource_params, ) return workflow_run_config
def get( self, trans, decoded_role_id): """ Method loads the role from the DB based on the given role id. :param decoded_role_id: id of the role to load from the DB :type decoded_role_id: int :returns: the loaded Role object :rtype: Role :raises: InconsistentDatabase, RequestParameterInvalidException, InternalServerError """ try: role = trans.sa_session.query( trans.app.model.Role ).filter( trans.model.Role.table.c.id == decoded_role_id ).one() except MultipleResultsFound: raise exceptions.InconsistentDatabase( 'Multiple roles found with the same id.' ) except NoResultFound: raise exceptions.RequestParameterInvalidException( 'No role found with the id provided.' ) except Exception, e: raise exceptions.InternalServerError( 'Error loading from the database.' + str(e) )
def index(self, trans, library_id, **kwd): """ GET /api/libraries/{library_id}/contents: Return a list of library files and folders. .. note:: This endpoint is slow for large libraries. Returns all content traversing recursively through all folders. .. seealso:: :class:`galaxy.webapps.galaxy.api.FolderContentsController.index` for a faster non-recursive solution :param library_id: the encoded id of the library :type library_id: str :returns: list of dictionaries of the form: * id: the encoded id of the library item * name: the 'library path' or relationship of the library item to the root * type: 'file' or 'folder' * url: the url to get detailed information on the library item :rtype: list :raises: MalformedId, InconsistentDatabase, RequestParameterInvalidException, InternalServerError """ rval = [] current_user_roles = trans.get_current_user_roles() def traverse(folder): admin = trans.user_is_admin rval = [] for subfolder in folder.active_folders: if not admin: can_access, folder_ids = trans.app.security_agent.check_folder_contents( trans.user, current_user_roles, subfolder) if (admin or can_access) and not subfolder.deleted: subfolder.api_path = folder.api_path + '/' + subfolder.name subfolder.api_type = 'folder' rval.append(subfolder) rval.extend(traverse(subfolder)) for ld in folder.datasets: if not admin: can_access = trans.app.security_agent.can_access_dataset( current_user_roles, ld.library_dataset_dataset_association.dataset) if (admin or can_access) and not ld.deleted: ld.api_path = folder.api_path + '/' + ld.name ld.api_type = 'file' rval.append(ld) return rval decoded_library_id = self.decode_id(library_id) try: library = trans.sa_session.query(trans.app.model.Library).filter( trans.app.model.Library.table.c.id == decoded_library_id).one() except MultipleResultsFound: raise exceptions.InconsistentDatabase( 'Multiple libraries found with the same id.') except NoResultFound: raise exceptions.RequestParameterInvalidException( 'No library found with the id provided.') except Exception as e: raise exceptions.InternalServerError( 'Error loading from the database.' + util.unicodify(e)) if not (trans.user_is_admin or trans.app.security_agent.can_access_library( current_user_roles, library)): raise exceptions.RequestParameterInvalidException( 'No library found with the id provided.') encoded_id = 'F' + trans.security.encode_id(library.root_folder.id) # appending root folder rval.append( dict(id=encoded_id, type='folder', name='/', url=url_for('library_content', library_id=library_id, id=encoded_id))) library.root_folder.api_path = '' # appending all other items in the library recursively for content in traverse(library.root_folder): encoded_id = trans.security.encode_id(content.id) if content.api_type == 'folder': encoded_id = 'F' + encoded_id rval.append( dict(id=encoded_id, type=content.api_type, name=content.api_path, url=url_for( 'library_content', library_id=library_id, id=encoded_id, ))) return rval
def index( self, trans, folder_id, **kwd ): """ GET /api/folders/{encoded_folder_id}/contents 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. :param folder_id: encoded ID of the folder which contents should be library_dataset_dict :type folder_id: encoded string :param kwd: keyword dictionary with other params :type kwd: dict :returns: dictionary containing all items and metadata :type: dict :raises: MalformedId, InconsistentDatabase, ObjectNotFound, InternalServerError """ deleted = kwd.get( 'include_deleted', 'missing' ) try: deleted = util.asbool( deleted ) except ValueError: deleted = False if ( len( folder_id ) == 17 and folder_id.startswith( 'F' ) ): try: decoded_folder_id = trans.security.decode_id( folder_id[ 1: ] ) except TypeError: raise exceptions.MalformedId( 'Malformed folder id ( %s ) specified, unable to decode.' % str( folder_id ) ) else: raise exceptions.MalformedId( 'Malformed folder id ( %s ) specified, unable to decode.' % str( folder_id ) ) try: folder = trans.sa_session.query( trans.app.model.LibraryFolder ).filter( trans.app.model.LibraryFolder.table.c.id == decoded_folder_id ).one() except MultipleResultsFound: raise exceptions.InconsistentDatabase( 'Multiple folders with same id found.' ) except NoResultFound: raise exceptions.ObjectNotFound( 'Folder with the id provided ( %s ) was not found' % str( folder_id ) ) except Exception: raise exceptions.InternalServerError( 'Error loading from the database.' ) current_user_roles = trans.get_current_user_roles() # Special level of security on top of libraries. if trans.app.security_agent.can_access_library( current_user_roles, folder.parent_library ): pass else: if trans.user: log.warning( "SECURITY: User (id: %s) without proper access rights is trying to load folder with ID of %s" % ( trans.user.id, decoded_folder_id ) ) else: log.warning( "SECURITY: Anonymous user is trying to load restricted folder with ID of %s" % ( decoded_folder_id ) ) raise exceptions.ObjectNotFound( 'Folder with the id provided ( %s ) was not found' % str( folder_id ) ) # if not ( trans.user_is_admin() or trans.app.security_agent.can_access_library_item( current_user_roles, folder, trans.user ) ): # log.debug('folder parent id: ' + str(folder.parent_id)) # if folder.parent_id is None: # try: # library = trans.sa_session.query( trans.app.model.Library ).filter( trans.app.model.Library.table.c.root_folder_id == decoded_folder_id ).one() # except Exception: # raise exceptions.InternalServerError( 'Error loading from the database.' ) # if trans.app.security_agent.library_is_unrestricted( library ): # pass # else: # if trans.user: # log.warning( "SECURITY: User (id: %s) without proper access rights is trying to load folder with ID of %s" % ( trans.user.id, decoded_folder_id ) ) # else: # log.warning( "SECURITY: Anonymous user without proper access rights is trying to load folder with ID of %s" % ( decoded_folder_id ) ) # raise exceptions.ObjectNotFound( 'Folder with the id provided ( %s ) was not found' % str( folder_id ) ) # else: # if trans.user: # log.warning( "SECURITY: User (id: %s) without proper access rights is trying to load folder with ID of %s" % ( trans.user.id, decoded_folder_id ) ) # else: # log.debug('PARENT ID IS NOT NONE') # log.warning( "SECURITY: Anonymous user without proper access rights is trying to load folder with ID of %s" % ( decoded_folder_id ) ) # raise exceptions.ObjectNotFound( 'Folder with the id provided ( %s ) was not found' % str( folder_id ) ) folder_contents = [] update_time = '' create_time = '' # Go through every accessible item (folders, datasets) in the folder and include its meta-data. for content_item in self._load_folder_contents( trans, folder, deleted ): return_item = {} encoded_id = trans.security.encode_id( content_item.id ) update_time = content_item.update_time.strftime( "%Y-%m-%d %I:%M %p" ) create_time = content_item.create_time.strftime( "%Y-%m-%d %I:%M %p" ) if content_item.api_type == 'folder': encoded_id = 'F' + encoded_id # Check whether user can modify current folder can_modify = False if trans.user_is_admin(): can_modify = True elif trans.user: can_modify = trans.app.security_agent.can_modify_library_item( current_user_roles, folder ) return_item.update( dict( can_modify=can_modify ) ) if content_item.api_type == 'file': # Is the dataset public or private? # When both are False the dataset is 'restricted' is_private = False is_unrestricted = False if trans.app.security_agent.dataset_is_public( content_item.library_dataset_dataset_association.dataset ): is_unrestricted = True else: is_unrestricted = False if trans.user: is_private = trans.app.security_agent.dataset_is_private_to_user( trans, content_item ) # Can user manage the permissions on the dataset? can_manage = False if trans.user_is_admin(): can_manage = True elif trans.user: can_manage = trans.app.security_agent.can_manage_dataset( current_user_roles, content_item.library_dataset_dataset_association.dataset ) nice_size = util.nice_size( int( content_item.library_dataset_dataset_association.get_size() ) ) library_dataset_dict = content_item.to_dict() return_item.update( dict( data_type=library_dataset_dict[ 'data_type' ], date_uploaded=library_dataset_dict[ 'date_uploaded' ], is_unrestricted=is_unrestricted, is_private=is_private, can_manage=can_manage, file_size=nice_size ) ) # For every item include the default meta-data return_item.update( dict( id=encoded_id, type=content_item.api_type, name=content_item.name, update_time=update_time, create_time=create_time, deleted=content_item.deleted ) ) folder_contents.append( return_item ) # Return the reversed path so it starts with the library node. full_path = self.build_path( trans, folder )[ ::-1 ] # Check whether user can add items to the current folder can_add_library_item = trans.user_is_admin() or trans.app.security_agent.can_add_library_item( current_user_roles, folder ) # Check whether user can modify current folder can_modify_folder = trans.app.security_agent.can_modify_library_item( current_user_roles, folder ) metadata = dict( full_path=full_path, can_add_library_item=can_add_library_item, can_modify_folder=can_modify_folder ) folder_container = dict( metadata=metadata, folder_contents=folder_contents ) return folder_container
def create(self, trans, encoded_parent_folder_id, **kwd): """ create( self, trans, encoded_parent_folder_id, **kwd ) *POST /api/folders/{encoded_parent_folder_id} Create a new folder object underneath the one specified in the parameters. :param encoded_parent_folder_id: the parent folder's id (required) :type encoded_parent_folder_id: an encoded id string (should be prefixed by 'F') :param name: the name of the new folder (required) :type name: str :param description: the description of the new folder :type description: str :returns: information about newly created folder, notably including ID :rtype: dictionary :raises: RequestParameterMissingException, MalformedId, InternalServerError """ payload = kwd.get('payload', None) if payload is None: raise exceptions.RequestParameterMissingException( "Missing required parameters 'encoded_parent_folder_id' and 'name'." ) name = payload.get('name', None) description = payload.get('description', '') if encoded_parent_folder_id is None: raise exceptions.RequestParameterMissingException( "Missing required parameter 'encoded_parent_folder_id'.") elif name is None: raise exceptions.RequestParameterMissingException( "Missing required parameter 'name'.") # encoded_parent_folder_id should be prefixed by 'F' encoded_parent_folder_id = self.__cut_the_prefix( encoded_parent_folder_id) try: decoded_parent_folder_id = trans.security.decode_id( encoded_parent_folder_id) except ValueError: raise exceptions.MalformedId( "Malformed folder id ( %s ) specified, unable to decode" % (str(id))) try: parent_folder = trans.sa_session.query( trans.app.model.LibraryFolder).filter( trans.app.model.LibraryFolder.table.c.id == decoded_parent_folder_id).one() except MultipleResultsFound: raise exceptions.InconsistentDatabase( 'Multiple folders found with the same id.') except NoResultFound: raise exceptions.RequestParameterInvalidException( 'No folder found with the id provided.') except Exception, e: raise exceptions.InternalServerError( 'Error loading from the database.' + str(e))