Exemplo n.º 1
0
    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))
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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))
Exemplo n.º 4
0
    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.')
Exemplo n.º 5
0
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
Exemplo n.º 6
0
    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))
Exemplo n.º 7
0
    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__)
Exemplo n.º 8
0
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
Exemplo n.º 9
0
    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) )
Exemplo n.º 10
0
    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
Exemplo n.º 11
0
    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
Exemplo n.º 12
0
    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))