Beispiel #1
0
    def create(self, trans, parent_folder_id, new_folder_name, new_folder_description=''):
        """
        Create a new folder under the given folder.

        :param  parent_folder_id:       decoded id
        :type   parent_folder_id:       int
        :param  new_folder_name:        name of the new folder
        :type   new_folder_name:        str
        :param  new_folder_description: description of the folder (optional, defaults to empty string)
        :type   new_folder_description: str

        :returns:   the new folder
        :rtype:     LibraryFolder

        :raises: InsufficientPermissionsException
        """
        parent_folder = self.get(trans, parent_folder_id)
        current_user_roles = trans.get_current_user_roles()
        if not (trans.user_is_admin or trans.app.security_agent.can_add_library_item(current_user_roles, parent_folder)):
            raise InsufficientPermissionsException('You do not have proper permission to create folders under given folder.')
        new_folder = trans.app.model.LibraryFolder(name=new_folder_name, description=new_folder_description)
        # We are associating the last used genome build with folders, so we will always
        # initialize a new folder with the first dbkey in genome builds list which is currently
        # ?    unspecified (?)
        new_folder.genome_build = trans.app.genome_builds.default_value
        parent_folder.add_folder(new_folder)
        trans.sa_session.add(new_folder)
        trans.sa_session.flush()
        # New folders default to having the same permissions as their parent folder
        trans.app.security_agent.copy_library_permissions(trans, parent_folder, new_folder)
        return new_folder
Beispiel #2
0
    def update(self, trans, folder, name=None, description=None):
        """
        Update the given folder's name or description.

        :param  folder:        the model object
        :type   folder:        LibraryFolder
        :param  name:          new name for the library folder
        :type   name:          str
        :param  description:   new description for the library folder
        :type   description:   str

        :returns:   the folder
        :rtype:     LibraryFolder

        :raises: ItemAccessibilityException, InsufficientPermissionsException
        """
        changed = False
        if not trans.user_is_admin:
            if not self.check_manageable(trans, folder):
                raise InsufficientPermissionsException("You do not have proper permission to update the library folder.")
        if folder.deleted is True:
            raise ItemAccessibilityException("You cannot update a deleted library folder. Undelete it first.")
        if name is not None and name != folder.name:
            folder.name = name
            changed = True
        if description is not None and description != folder.description:
            folder.description = description
            changed = True
        if changed:
            trans.sa_session.add(folder)
            trans.sa_session.flush()
        return folder
Beispiel #3
0
    def get_permissions(self,
                        trans,
                        encoded_folder_id,
                        scope=None,
                        page=None,
                        page_limit=None,
                        query=None):
        """
        Load all permissions for the given folder id and return it.

        :param  encoded_folder_id:     the encoded id of the folder
        :type   encoded_folder_id:     an encoded id string

        :param  scope:      either 'current' or 'available'
        :type   scope:      string

        :returns:   dictionary with all applicable permissions' values
        :rtype:     dictionary

        :raises: InsufficientPermissionsException
        """
        current_user_roles = trans.get_current_user_roles()
        is_admin = trans.user_is_admin
        decoded_folder_id = self.folder_manager.cut_and_decode(
            trans, encoded_folder_id)
        folder = self.folder_manager.get(trans, decoded_folder_id)

        if not (is_admin or trans.app.security_agent.can_manage_library_item(
                current_user_roles, folder)):
            raise InsufficientPermissionsException(
                'You do not have proper permission to access permissions of this folder.'
            )

        if scope == 'current' or scope is None:
            return self.folder_manager.get_current_roles(trans, folder)
        #  Return roles that are available to select.
        elif scope == 'available':
            if page is not None:
                page = int(page)
            else:
                page = 1
            if page_limit is not None:
                page_limit = int(page_limit)
            else:
                page_limit = 10
            roles, total_roles = trans.app.security_agent.get_valid_roles(
                trans, folder, query, page, page_limit)
            return_roles = []
            for role in roles:
                role_id = trans.security.encode_id(role.id)
                return_roles.append(
                    dict(id=role_id, name=role.name, type=role.type))
            return dict(roles=return_roles,
                        page=page,
                        page_limit=page_limit,
                        total=total_roles)
        else:
            raise RequestParameterInvalidException(
                "The value of 'scope' parameter is invalid. Alllowed values: current, available"
            )
Beispiel #4
0
    def get_permissions(
        self,
        trans,
        encoded_folder_id: EncodedDatabaseIdField,
        scope: Optional[LibraryPermissionScope] = LibraryPermissionScope.
        current,
        page: Optional[int] = 1,
        page_limit: Optional[int] = 10,
        query: Optional[str] = None,
    ) -> Union[LibraryFolderCurrentPermissions, LibraryAvailablePermissions]:
        """
        Load all permissions for the given folder id and return it.

        :param  encoded_folder_id:     the encoded id of the folder
        :type   encoded_folder_id:     an encoded id string

        :param  scope:      either 'current' or 'available'
        :type   scope:      string

        :returns:   dictionary with all applicable permissions' values
        :rtype:     dictionary

        :raises: InsufficientPermissionsException
        """
        current_user_roles = trans.get_current_user_roles()
        is_admin = trans.user_is_admin
        decoded_folder_id = self.folder_manager.cut_and_decode(
            trans, encoded_folder_id)
        folder = self.folder_manager.get(trans, decoded_folder_id)

        if not (is_admin or trans.app.security_agent.can_manage_library_item(
                current_user_roles, folder)):
            raise InsufficientPermissionsException(
                'You do not have proper permission to access permissions of this folder.'
            )

        if scope is None or scope == LibraryPermissionScope.current:
            current_permissions = self.folder_manager.get_current_roles(
                trans, folder)
            return LibraryFolderCurrentPermissions.parse_obj(
                current_permissions)
        #  Return roles that are available to select.
        elif scope == LibraryPermissionScope.available:
            roles, total_roles = trans.app.security_agent.get_valid_roles(
                trans, folder, query, page, page_limit)
            return_roles = []
            for role in roles:
                role_id = trans.security.encode_id(role.id)
                return_roles.append(
                    dict(id=role_id, name=role.name, type=role.type))
            return LibraryAvailablePermissions(roles=return_roles,
                                               page=page,
                                               page_limit=page_limit,
                                               total=total_roles)
        else:
            raise RequestParameterInvalidException(
                "The value of 'scope' parameter is invalid. Allowed values: current, available"
            )
Beispiel #5
0
    def update( self, trans, id, **kwd ):
        """
        PATCH /api/repositories/{encoded_repository_id}
        Updates information about a repository in the Tool Shed.

        :param id: the encoded id of the Repository object

        :param payload: dictionary structure containing::
            'name':                  repo's name (optional)
            'synopsis':              repo's synopsis (optional)
            'description':           repo's description (optional)
            'remote_repository_url': repo's remote repo (optional)
            'homepage_url':          repo's homepage url (optional)
            'category_ids':          list of existing encoded TS category ids
                                     the updated repo should be associated with (optional)
        :type payload: dict

        :returns:   detailed repository information
        :rtype:     dict

        :raises: RequestParameterInvalidException, InsufficientPermissionsException
        """
        payload = kwd.get( 'payload', None )
        if not payload:
            raise RequestParameterMissingException( "You did not specify any payload." )

        name = payload.get( 'name', None )
        synopsis = payload.get( 'synopsis', None )
        description = payload.get( 'description', None )
        remote_repository_url = payload.get( 'remote_repository_url', None )
        homepage_url = payload.get( 'homepage_url', None )
        category_ids = payload.get( 'category_ids', None )
        if category_ids is not None:
            # We need to know if it was actually passed, and listify turns None into []
            category_ids = util.listify( category_ids )

        update_kwds = dict(
            name=name,
            description=synopsis,
            long_description=description,
            remote_repository_url=remote_repository_url,
            homepage_url=homepage_url,
            category_ids=category_ids,
        )

        repo, message = repository_util.update_repository( app=trans.app, trans=trans, id=id, **update_kwds )
        if repo is None:
            if "You are not the owner" in message:
                raise InsufficientPermissionsException( message )
            else:
                raise ActionInputError( message )

        repository_dict = repo.to_dict( view='element', value_mapper=self.__get_value_mapper( trans ) )
        repository_dict[ 'category_ids' ] = \
            [ trans.security.encode_id( x.category.id ) for x in repo.categories ]
        return repository_dict
Beispiel #6
0
    def check_manageable(self, trans, folder):
        """
        Check whether the user can manage the folder.

        :returns:   the original folder
        :rtype:     LibraryFolder

        :raises: AuthenticationRequired, InsufficientPermissionsException
        """
        if not trans.user:
            raise AuthenticationRequired("Must be logged in to manage Galaxy items.", type='error')
        current_user_roles = trans.get_current_user_roles()
        if not trans.app.security_agent.can_manage_library_item(current_user_roles, folder):
            raise InsufficientPermissionsException("You don't have permissions to manage this folder.", type='error')
        else:
            return folder
Beispiel #7
0
    def check_modifiable(self, trans, ld):
        """
        Check whether the current user has permissions to modify library dataset.

        :param  ld: library dataset
        :type   ld: galaxy.model.LibraryDataset

        :returns:   the original library dataset
        :rtype:     galaxy.model.LibraryDataset

        :raises:    ObjectNotFound
        """
        if ld.deleted:
            raise ObjectNotFound('Library dataset with the id provided is deleted.')
        elif trans.user_is_admin:
            return ld
        if not trans.app.security_agent.can_modify_library_item(trans.get_current_user_roles(), ld):
            raise InsufficientPermissionsException('You do not have proper permission to modify this library dataset.')
        else:
            return ld
Beispiel #8
0
    def set_permissions(self, trans, encoded_folder_id: EncodedDatabaseIdField,
                        payload: dict) -> LibraryFolderCurrentPermissions:
        """
        Set permissions of the given folder to the given role ids.

        :param  encoded_folder_id:      the encoded id of the folder to set the permissions of
        :type   encoded_folder_id:      an encoded id string
        :param   payload: dictionary structure containing:

            :param  action:            (required) describes what action should be performed
            :type   action:            string
            :param  add_ids[]:         list of Role.id defining roles that should have add item permission on the folder
            :type   add_ids[]:         string or list
            :param  manage_ids[]:      list of Role.id defining roles that should have manage permission on the folder
            :type   manage_ids[]:      string or list
            :param  modify_ids[]:      list of Role.id defining roles that should have modify permission on the folder
            :type   modify_ids[]:      string or list

        :type       dictionary
        :returns:   dict of current roles for all available permission types.
        :rtype:     dictionary
        :raises: RequestParameterInvalidException, InsufficientPermissionsException, RequestParameterMissingException
        """

        is_admin = trans.user_is_admin
        current_user_roles = trans.get_current_user_roles()
        decoded_folder_id = self.folder_manager.cut_and_decode(
            trans, encoded_folder_id)
        folder = self.folder_manager.get(trans, decoded_folder_id)
        if not (is_admin or trans.app.security_agent.can_manage_library_item(
                current_user_roles, folder)):
            raise InsufficientPermissionsException(
                'You do not have proper permission to modify permissions of this folder.'
            )

        new_add_roles_ids = util.listify(payload.get('add_ids[]', None))
        new_manage_roles_ids = util.listify(payload.get('manage_ids[]', None))
        new_modify_roles_ids = util.listify(payload.get('modify_ids[]', None))

        action = payload.get('action', None)
        if action is None:
            raise RequestParameterMissingException(
                'The mandatory parameter "action" is missing.')
        elif action == 'set_permissions':

            # ADD TO LIBRARY ROLES
            valid_add_roles = []
            invalid_add_roles_names = []
            for role_id in new_add_roles_ids:
                role = self.role_manager.get(
                    trans, trans.security.decode_id(role_id,
                                                    object_name='role'))
                #  Check whether role is in the set of allowed roles
                valid_roles, total_roles = trans.app.security_agent.get_valid_roles(
                    trans, folder)
                if role in valid_roles:
                    valid_add_roles.append(role)
                else:
                    invalid_add_roles_names.append(role_id)
            if len(invalid_add_roles_names) > 0:
                log.warning(
                    f"The following roles could not be added to the add library item permission: {str(invalid_add_roles_names)}"
                )

            # MANAGE FOLDER ROLES
            valid_manage_roles = []
            invalid_manage_roles_names = []
            for role_id in new_manage_roles_ids:
                role = self.role_manager.get(
                    trans, trans.security.decode_id(role_id,
                                                    object_name='role'))
                #  Check whether role is in the set of allowed roles
                valid_roles, total_roles = trans.app.security_agent.get_valid_roles(
                    trans, folder)
                if role in valid_roles:
                    valid_manage_roles.append(role)
                else:
                    invalid_manage_roles_names.append(role_id)
            if len(invalid_manage_roles_names) > 0:
                log.warning(
                    f"The following roles could not be added to the manage folder permission: {str(invalid_manage_roles_names)}"
                )

            # MODIFY FOLDER ROLES
            valid_modify_roles = []
            invalid_modify_roles_names = []
            for role_id in new_modify_roles_ids:
                role = self.role_manager.get(
                    trans, trans.security.decode_id(role_id,
                                                    object_name='role'))
                #  Check whether role is in the set of allowed roles
                valid_roles, total_roles = trans.app.security_agent.get_valid_roles(
                    trans, folder)
                if role in valid_roles:
                    valid_modify_roles.append(role)
                else:
                    invalid_modify_roles_names.append(role_id)
            if len(invalid_modify_roles_names) > 0:
                log.warning(
                    f"The following roles could not be added to the modify folder permission: {str(invalid_modify_roles_names)}"
                )

            permissions = {
                trans.app.security_agent.permitted_actions.LIBRARY_ADD:
                valid_add_roles
            }
            permissions.update({
                trans.app.security_agent.permitted_actions.LIBRARY_MANAGE:
                valid_manage_roles
            })
            permissions.update({
                trans.app.security_agent.permitted_actions.LIBRARY_MODIFY:
                valid_modify_roles
            })

            trans.app.security_agent.set_all_library_permissions(
                trans, folder, permissions)
        else:
            raise RequestParameterInvalidException(
                'The mandatory parameter "action" has an invalid value.'
                'Allowed values are: "set_permissions"')
        current_permissions = self.folder_manager.get_current_roles(
            trans, folder)
        return LibraryFolderCurrentPermissions.parse_obj(current_permissions)