Exemple #1
0
    def update(self, trans, encoded_dataset_id, payload=None, **kwd):
        """Update the given library dataset (the latest linked ldda).

        * PATCH /api/libraries/datasets/{encoded_dataset_id}

        :param  encoded_dataset_id: the encoded id of the library dataset to update
        :type   encoded_dataset_id: an encoded id string
        :param  payload:            dictionary structure containing::
            :param name:            new ld's name, must be longer than 0
            :type  name:            str
            :param misc_info:       new ld's misc info
            :type  misc_info:       str
            :param file_ext:        new ld's extension, must exist in the Galaxy registry
            :type  file_ext:        str
            :param genome_build:    new ld's genome build
            :type  genome_build:    str
        :type   payload: dict

        :returns:   detailed library dataset information
        :rtype:     dictionary
        """
        library_dataset = self.ld_manager.get(trans, managers_base.decode_id(self.app, encoded_dataset_id))
        updated = self.ld_manager.update(trans, library_dataset, payload)
        serialized = self.ld_manager.serialize(trans, updated)
        return serialized
Exemple #2
0
    def show_version(self, trans, encoded_dataset_id, encoded_ldda_id, **kwd):
        """
        Display a specific version of a library dataset (i.e. ldda).

        * GET /api/libraries/datasets/{encoded_dataset_id}/versions/{encoded_ldda_id}

        :param  encoded_dataset_id:      the encoded id of the related library dataset
        :type   encoded_dataset_id:      an encoded id string

        :param  encoded_ldda_id:      the encoded id of the ldda to query
        :type   encoded_ldda_id:      an encoded id string

        :returns:   dict of ldda's details
        :rtype:     dictionary

        :raises: ObjectNotFound
        """
        library_dataset = self.ld_manager.get(trans, managers_base.decode_id(self.app, encoded_dataset_id))

        try:
            ldda = self.get_library_dataset_dataset_association(trans, id=encoded_ldda_id, check_ownership=False, check_accessible=False)
        except Exception as e:
            raise exceptions.ObjectNotFound('Requested version of library dataset was not found.' + str(e))

        if ldda not in library_dataset.expired_datasets:
            raise exceptions.ObjectNotFound('Given library dataset does not have the requested version.')

        rval = trans.security.encode_all_ids(ldda.to_dict())
        return rval
Exemple #3
0
    def update(self, trans, encoded_dataset_id, payload=None, **kwd):
        """
        PATCH /api/libraries/datasets/{encoded_dataset_id}

        Update the given library dataset (the latest linked ldda).

        :param  encoded_dataset_id: the encoded id of the library dataset to update
        :type   encoded_dataset_id: an encoded id string
        :param  payload:            dictionary structure containing::
            :param name:            new ld's name, must be longer than 0
            :type  name:            str
            :param misc_info:       new ld's misc info
            :type  misc_info:       str
            :param file_ext:        new ld's extension, must exist in the Galaxy registry
            :type  file_ext:        str
            :param genome_build:    new ld's genome build
            :type  genome_build:    str
            :param tags:            list of dataset tags
            :type  tags:            list
        :type   payload: dict

        :returns:   detailed library dataset information
        :rtype:     dictionary
        """
        library_dataset = self.ld_manager.get(trans, managers_base.decode_id(self.app, encoded_dataset_id))
        updated = self.ld_manager.update(trans, library_dataset, payload)
        serialized = self.ld_manager.serialize(trans, updated)
        return serialized
Exemple #4
0
    def create(self, trans, payload, **kwd):
        """
        * POST /api/dataset_collections:
            create a new dataset collection instance.

        :type   payload: dict
        :param  payload: (optional) dictionary structure containing:
            * collection_type: dataset colltion type to create.
            * instance_type:   Instance type - 'history' or 'library'.
            * name:            the new dataset collections's name
            * datasets:        object describing datasets for collection
        :rtype:     dict
        :returns:   element view of new dataset collection
        """
        # TODO: Error handling...
        create_params = api_payload_to_create_params(payload)
        instance_type = payload.pop("instance_type", "history")
        if instance_type == "history":
            history_id = payload.get('history_id')
            history_id = decode_id(self.app, history_id)
            history = self.history_manager.get_owned(history_id, trans.user, current_history=trans.history)
            create_params["parent"] = history
        elif instance_type == "library":
            folder_id = payload.get('folder_id')
            library_folder = self.get_library_folder(trans, folder_id, check_accessible=True)
            self.check_user_can_add_to_library_item(trans, library_folder, check_accessible=False)
            create_params["parent"] = library_folder
        else:
            trans.status = 501
            return
        dataset_collection_instance = self.__service(trans).create(trans=trans, **create_params)
        return dictify_dataset_collection_instance(dataset_collection_instance,
                                                   security=trans.security, parent=create_params["parent"])
Exemple #5
0
    def show_version(self, trans, encoded_dataset_id, encoded_ldda_id, **kwd):
        """
        GET /api/libraries/datasets/{encoded_dataset_id}/versions/{encoded_ldda_id}

        Display a specific version of a library dataset (i.e. ldda).

        :param  encoded_dataset_id:      the encoded id of the related library dataset
        :type   encoded_dataset_id:      an encoded id string

        :param  encoded_ldda_id:      the encoded id of the ldda to query
        :type   encoded_ldda_id:      an encoded id string

        :returns:   dict of ldda's details
        :rtype:     dictionary

        :raises: ObjectNotFound
        """
        library_dataset = self.ld_manager.get(trans, managers_base.decode_id(self.app, encoded_dataset_id))

        try:
            ldda = self.get_library_dataset_dataset_association(trans, id=encoded_ldda_id, check_ownership=False, check_accessible=False)
        except Exception as e:
            raise exceptions.ObjectNotFound(f"Requested version of library dataset was not found.{util.unicodify(e)}")

        if ldda not in library_dataset.expired_datasets:
            raise exceptions.ObjectNotFound('Given library dataset does not have the requested version.')

        rval = trans.security.encode_all_ids(ldda.to_dict())
        return rval
Exemple #6
0
 def _get_user(self, trans: ProvidesAppContext,
               encoded_user_id: EncodedDatabaseIdField) -> model.User:
     decoded_user_id = decode_id(self._app, encoded_user_id)
     user = trans.sa_session.query(model.User).get(decoded_user_id)
     if user is None:
         raise ObjectNotFound(
             f"User with id {encoded_user_id} was not found.")
     return user
Exemple #7
0
 def show(self, trans: ProvidesUserContext, id: str, **kwd):
     """
     GET /api/roles/{encoded_role_id}
     Displays information about a role.
     """
     role_id = decode_id(self.app, id)
     role = self.role_manager.get(trans, role_id)
     return role_to_model(trans, role)
Exemple #8
0
 def _get_group(self, trans: ProvidesAppContext,
                encoded_group_id: EncodedDatabaseIdField) -> Any:
     decoded_group_id = decode_id(self._app, encoded_group_id)
     group = trans.sa_session.query(model.Group).get(decoded_group_id)
     if group is None:
         raise ObjectNotFound(
             f"Group with id {encoded_group_id} was not found.")
     return group
Exemple #9
0
 def _get_role(self, trans: ProvidesAppContext,
               encoded_role_id: EncodedDatabaseIdField) -> model.Role:
     decoded_role_id = decode_id(self._app, encoded_role_id)
     role = trans.sa_session.query(model.Role).get(decoded_role_id)
     if role is None:
         raise ObjectNotFound(
             f"Role with id {encoded_role_id} was not found.")
     return role
Exemple #10
0
    def show_roles(self, trans, encoded_dataset_id, **kwd):
        """
        GET /api/libraries/datasets/{encoded_dataset_id}/permissions

        Display information about current or available roles for a given dataset permission.

        :param  encoded_dataset_id:      the encoded id of the dataset to query
        :type   encoded_dataset_id:      an encoded id string

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

        :returns:   either dict of current roles for all permission types
                    or dict of available roles to choose from (is the same for any permission type)
        :rtype:     dictionary

        :raises: InsufficientPermissionsException
        """
        current_user_roles = trans.get_current_user_roles()
        library_dataset = self.ld_manager.get(
            trans, managers_base.decode_id(self.app, encoded_dataset_id))
        dataset = library_dataset.library_dataset_dataset_association.dataset
        # User has to have manage permissions permission in order to see the roles.
        can_manage = trans.app.security_agent.can_manage_dataset(
            current_user_roles, dataset) or trans.user_is_admin
        if not can_manage:
            raise exceptions.InsufficientPermissionsException(
                'You do not have proper permission to access permissions.')
        scope = kwd.get('scope', None)
        if scope in ['current', None]:
            return self._get_current_roles(trans, library_dataset)
        elif scope in ['available']:
            page = kwd.get('page', None)
            if page is not None:
                page = int(page)
            else:
                page = 1
            page_limit = kwd.get('page_limit', None)
            if page_limit is not None:
                page_limit = int(page_limit)
            else:
                page_limit = 10
            query = kwd.get('q', None)
            roles, total_roles = trans.app.security_agent.get_valid_roles(
                trans, dataset, 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 exceptions.RequestParameterInvalidException(
                "The value of 'scope' parameter is invalid. Alllowed values: current, available"
            )
Exemple #11
0
def get_page_identifiers(item_id, app):
    # Assume if item id is integer and less than 10**15, it's unencoded.
    try:
        decoded_id = int(item_id)
        if decoded_id >= PAGE_MAXRAW:
            raise ValueError("Identifier larger than maximum expected raw int, must be already encoded.")
        encoded_id = app.security.encode_id(item_id)
    except ValueError:
        # It's an encoded id.
        encoded_id = item_id
        decoded_id = base.decode_id(app, item_id)
    return (encoded_id, decoded_id)
Exemple #12
0
    def show(self, trans, id, **kwd):
        """
        Show the details of a library dataset.

        * GET /api/libraries/datasets/{encoded_dataset_id}

        :param  id:      the encoded id of the library dataset to query
        :type   id:      an encoded id string

        :returns:   detailed library dataset information
        :rtype:     dictionary
        """
        ld = self.ld_manager.get(trans, managers_base.decode_id(self.app, id))
        serialized = self.ld_manager.serialize(trans, ld)
        return serialized
Exemple #13
0
    def show(self, trans, id, **kwd):
        """
        GET /api/libraries/datasets/{encoded_dataset_id}

        Show the details of a library dataset.

        :param  id:      the encoded id of the library dataset to query
        :type   id:      an encoded id string

        :returns:   detailed library dataset information
        :rtype:     dictionary
        """
        ld = self.ld_manager.get(trans, managers_base.decode_id(self.app, id))
        serialized = self.ld_manager.serialize(trans, ld)
        return serialized
Exemple #14
0
    def show_roles(self, trans, encoded_dataset_id, **kwd):
        """
        Display information about current or available roles for a given dataset permission.

        * GET /api/libraries/datasets/{encoded_dataset_id}/permissions

        :param  encoded_dataset_id:      the encoded id of the dataset to query
        :type   encoded_dataset_id:      an encoded id string

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

        :returns:   either dict of current roles for all permission types
                    or dict of available roles to choose from (is the same for any permission type)
        :rtype:     dictionary

        :raises: InsufficientPermissionsException
        """
        current_user_roles = trans.get_current_user_roles()
        library_dataset = self.ld_manager.get(trans, managers_base.decode_id(self.app, encoded_dataset_id))
        dataset = library_dataset.library_dataset_dataset_association.dataset
        # User has to have manage permissions permission in order to see the roles.
        can_manage = trans.app.security_agent.can_manage_dataset(current_user_roles, dataset) or trans.user_is_admin()
        if not can_manage:
            raise exceptions.InsufficientPermissionsException('You do not have proper permission to access permissions.')
        scope = kwd.get('scope', None)
        if scope in ['current', None]:
            return self._get_current_roles(trans, library_dataset)
        elif scope in ['available']:
            page = kwd.get('page', None)
            if page is not None:
                page = int(page)
            else:
                page = 1
            page_limit = kwd.get('page_limit', None)
            if page_limit is not None:
                page_limit = int(page_limit)
            else:
                page_limit = 10
            query = kwd.get('q', None)
            roles, total_roles = trans.app.security_agent.get_valid_roles(trans, dataset, 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 exceptions.RequestParameterInvalidException("The value of 'scope' parameter is invalid. Alllowed values: current, available")
Exemple #15
0
    def contents(self, trans, hdca_id, parent_id, instance_type='history', limit=None, offset=None, **kwds):
        """
        * GET /api/dataset_collection/{hdca_id}/contents/{parent_id}?limit=100&offset=0
        Shows direct child contents of indicated dataset collection parent id

        :type   string:     encoded string id
        :param  id:         HDCA.id
        :type   string:     encoded string id
        :param  parent_id:  parent dataset_collection.id for the dataset contents to be viewed
        :type   integer:    int
        :param  limit:      pagination limit for returned dataset collection elements
        :type   integer:    int
        :param  offset:     pagination offset for returned dataset collection elements
        :rtype:     list
        :returns:   list of dataset collection elements and contents
        """
        svc = self.__service(trans)
        encode_id = trans.app.security.encode_id

        # validate HDCA for current user, will throw error if not permitted
        # TODO: refactor get_dataset_collection_instance
        hdca = svc.get_dataset_collection_instance(trans,
            id=hdca_id, check_ownership=True,
            instance_type=instance_type)

        # check to make sure the dsc is part of the validated hdca
        decoded_parent_id = decode_id(self.app, parent_id)
        if not hdca.contains_collection(decoded_parent_id):
            errmsg = 'Requested dataset collection is not contained within indicated history content'
            raise ObjectNotFound(errmsg)

        # retrieve contents
        contents_qry = svc.get_collection_contents_qry(decoded_parent_id, limit=limit, offset=offset)

        # dictify and tack on a collection_url for drilling down into nested collections
        def process_element(dsc_element):
            result = dictify_element_reference(dsc_element, recursive=False, security=trans.security)
            if result["element_type"] == "dataset_collection":
                result["object"]["contents_url"] = routes.url_for('contents_dataset_collection',
                    hdca_id=encode_id(hdca.id),
                    parent_id=encode_id(result["object"]["id"]))
            trans.security.encode_all_ids(result, recursive=True)
            return result

        results = contents_qry.with_session(trans.sa_session()).all()
        return [process_element(el) for el in results]
Exemple #16
0
    def delete(self, trans, encoded_dataset_id, **kwd):
        """
        DELETE /api/libraries/datasets/{encoded_dataset_id}

        Mark the dataset deleted or undeleted.

        :param  encoded_dataset_id:      the encoded id of the dataset to change
        :type   encoded_dataset_id:      an encoded id string
        :param  undelete:                flag whether to undeleted instead of deleting
        :type   undelete:                bool

        :returns:   dict containing information about the dataset
        :rtype:     dictionary
        """
        undelete = util.string_as_bool(kwd.get('undelete', False))
        library_dataset = self.ld_manager.get(
            trans, managers_base.decode_id(self.app, encoded_dataset_id))
        current_user_roles = trans.get_current_user_roles()
        allowed = trans.app.security_agent.can_modify_library_item(
            current_user_roles, library_dataset)
        if (not allowed) and (not trans.user_is_admin):
            raise exceptions.InsufficientPermissionsException(
                'You do not have proper permissions to delete this dataset.')

        if undelete:
            library_dataset.deleted = False
        else:
            library_dataset.deleted = True

        trans.sa_session.add(library_dataset)
        trans.sa_session.flush()

        rval = trans.security.encode_all_ids(library_dataset.to_dict())
        nice_size = util.nice_size(
            int(library_dataset.library_dataset_dataset_association.get_size())
        )
        rval['file_size'] = nice_size
        rval['update_time'] = library_dataset.update_time.strftime(
            "%Y-%m-%d %I:%M %p")
        rval['deleted'] = library_dataset.deleted
        rval['folder_id'] = 'F' + rval['folder_id']
        return rval
Exemple #17
0
    def delete(self, trans, encoded_dataset_id, **kwd):
        """
        Mark the dataset deleted or undeleted.

        * DELETE /api/libraries/datasets/{encoded_dataset_id}

        :param  encoded_dataset_id:      the encoded id of the dataset to change
        :type   encoded_dataset_id:      an encoded id string
        :param  undelete:                flag whether to undeleted instead of deleting
        :type   undelete:                bool

        :returns:   dict containing information about the dataset
        :rtype:     dictionary
        """
        undelete = util.string_as_bool(kwd.get('undelete', False))
        library_dataset = self.ld_manager.get(trans, managers_base.decode_id(self.app, encoded_dataset_id))
        current_user_roles = trans.get_current_user_roles()
        allowed = trans.app.security_agent.can_modify_library_item(current_user_roles, library_dataset)
        if (not allowed) and (not trans.user_is_admin()):
            raise exceptions.InsufficientPermissionsException('You do not have proper permissions to delete this dataset.')

        if undelete:
            library_dataset.deleted = False
        else:
            library_dataset.deleted = True

        trans.sa_session.add(library_dataset)
        trans.sa_session.flush()

        rval = trans.security.encode_all_ids(library_dataset.to_dict())
        nice_size = util.nice_size(int(library_dataset.library_dataset_dataset_association.get_size()))
        rval['file_size'] = nice_size
        rval['update_time'] = library_dataset.update_time.strftime("%Y-%m-%d %I:%M %p")
        rval['deleted'] = library_dataset.deleted
        rval['folder_id'] = 'F' + rval['folder_id']
        return rval
Exemple #18
0
 def _decode_id(self, id):
     return managers_base.decode_id(self.app, id)
Exemple #19
0
 def to_role_id(encoded_role_id):
     role_id = base.decode_id(self.app, encoded_role_id)
     return role_id
Exemple #20
0
    def update_permissions(self, trans, encoded_dataset_id, payload=None, **kwd):
        """
        POST /api/libraries/datasets/{encoded_dataset_id}/permissions

        Set permissions of the given library dataset to the given role ids.

        :param  encoded_dataset_id:      the encoded id of the dataset to update permissions of
        :type   encoded_dataset_id:      an encoded id string
        :param   payload: dictionary structure containing:

            :param  action:     (required) describes what action should be performed
                                available actions: make_private, remove_restrictions, set_permissions
            :type   action:     string
            :param  access_ids[]:      list of Role.id defining roles that should have access permission on the dataset
            :type   access_ids[]:      string or list
            :param  manage_ids[]:      list of Role.id defining roles that should have manage permission on the dataset
            :type   manage_ids[]:      string or list
            :param  modify_ids[]:      list of Role.id defining roles that should have modify permission on the library dataset item
            :type   modify_ids[]:      string or list

        :type:      dictionary

        :returns:   dict of current roles for all available permission types
        :rtype:     dictionary

        :raises: RequestParameterInvalidException, ObjectNotFound, InsufficientPermissionsException, InternalServerError
                    RequestParameterMissingException
        """
        if payload:
            kwd.update(payload)
        action = kwd.get('action', None)
        if action not in ['remove_restrictions', 'make_private', 'set_permissions']:
            raise exceptions.RequestParameterInvalidException('The mandatory parameter "action" has an invalid value. '
                                                              'Allowed values are: "remove_restrictions", "make_private", "set_permissions"')
        library_dataset = self.ld_manager.get(trans, managers_base.decode_id(self.app, encoded_dataset_id))
        # Some permissions are attached directly to the underlying dataset.
        dataset = library_dataset.library_dataset_dataset_association.dataset
        current_user_roles = trans.get_current_user_roles()
        can_manage = trans.app.security_agent.can_manage_dataset(current_user_roles, dataset) or trans.user_is_admin
        if not can_manage:
            raise exceptions.InsufficientPermissionsException('You do not have proper permissions to manage permissions on this dataset.')
        new_access_roles_ids = util.listify(kwd.get('access_ids[]', None))
        new_manage_roles_ids = util.listify(kwd.get('manage_ids[]', None))
        new_modify_roles_ids = util.listify(kwd.get('modify_ids[]', None))
        if action == 'remove_restrictions':
            trans.app.security_agent.make_dataset_public(dataset)
            if not trans.app.security_agent.dataset_is_public(dataset):
                raise exceptions.InternalServerError('An error occurred while making dataset public.')
        elif action == 'make_private':
            if not trans.app.security_agent.dataset_is_private_to_user(trans, dataset):
                private_role = trans.app.security_agent.get_private_user_role(trans.user)
                dp = trans.app.model.DatasetPermissions(trans.app.security_agent.permitted_actions.DATASET_ACCESS.action, dataset, private_role)
                trans.sa_session.add(dp)
                trans.sa_session.flush()
            if not trans.app.security_agent.dataset_is_private_to_user(trans, dataset):
                # Check again and inform the user if dataset is not private.
                raise exceptions.InternalServerError('An error occurred and the dataset is NOT private.')
        elif action == 'set_permissions':
            # ACCESS DATASET ROLES
            valid_access_roles = []
            invalid_access_roles_ids = []
            valid_roles_for_dataset, total_roles = trans.app.security_agent.get_valid_roles(trans, dataset)
            if new_access_roles_ids is None:
                trans.app.security_agent.make_dataset_public(dataset)
            else:
                for role_id in new_access_roles_ids:
                    role = self.role_manager.get(trans, managers_base.decode_id(self.app, role_id))
                    if role in valid_roles_for_dataset:
                        valid_access_roles.append(role)
                    else:
                        invalid_access_roles_ids.append(role_id)
                if len(invalid_access_roles_ids) > 0:
                    log.warning(f"The following roles could not be added to the dataset access permission: {str(invalid_access_roles_ids)}")

                access_permission = dict(access=valid_access_roles)
                trans.app.security_agent.set_dataset_permission(dataset, access_permission)

            # MANAGE DATASET ROLES
            valid_manage_roles = []
            invalid_manage_roles_ids = []
            new_manage_roles_ids = util.listify(new_manage_roles_ids)
            for role_id in new_manage_roles_ids:
                role = self.role_manager.get(trans, managers_base.decode_id(self.app, role_id))
                if role in valid_roles_for_dataset:
                    valid_manage_roles.append(role)
                else:
                    invalid_manage_roles_ids.append(role_id)
            if len(invalid_manage_roles_ids) > 0:
                log.warning(f"The following roles could not be added to the dataset manage permission: {str(invalid_manage_roles_ids)}")
            manage_permission = {trans.app.security_agent.permitted_actions.DATASET_MANAGE_PERMISSIONS: valid_manage_roles}
            trans.app.security_agent.set_dataset_permission(dataset, manage_permission)

            # MODIFY LIBRARY ITEM ROLES
            valid_modify_roles = []
            invalid_modify_roles_ids = []
            new_modify_roles_ids = util.listify(new_modify_roles_ids)
            for role_id in new_modify_roles_ids:
                role = self.role_manager.get(trans, managers_base.decode_id(self.app, role_id))
                if role in valid_roles_for_dataset:
                    valid_modify_roles.append(role)
                else:
                    invalid_modify_roles_ids.append(role_id)
            if len(invalid_modify_roles_ids) > 0:
                log.warning(f"The following roles could not be added to the dataset modify permission: {str(invalid_modify_roles_ids)}")
            modify_permission = {trans.app.security_agent.permitted_actions.LIBRARY_MODIFY: valid_modify_roles}
            trans.app.security_agent.set_library_item_permission(library_dataset, modify_permission)
        return self._get_current_roles(trans, library_dataset)
 def to_role_id(encoded_role_id):
     role_id = base.decode_id(self.app, encoded_role_id)
     return role_id
Exemple #22
0
 def _decode_id(self, encoded_id: EncodedDatabaseIdField) -> int:
     return decode_id(self._app, encoded_id)
Exemple #23
0
    def update_permissions(self, trans, encoded_dataset_id, payload=None, **kwd):
        """
        Set permissions of the given library dataset to the given role ids.

        *POST /api/libraries/datasets/{encoded_dataset_id}/permissions

        :param  encoded_dataset_id:      the encoded id of the dataset to update permissions of
        :type   encoded_dataset_id:      an encoded id string
        :param   payload: dictionary structure containing:
            :param  action:     (required) describes what action should be performed
                                available actions: make_private, remove_restrictions, set_permissions
            :type   action:     string
            :param  access_ids[]:      list of Role.id defining roles that should have access permission on the dataset
            :type   access_ids[]:      string or list
            :param  manage_ids[]:      list of Role.id defining roles that should have manage permission on the dataset
            :type   manage_ids[]:      string or list
            :param  modify_ids[]:      list of Role.id defining roles that should have modify permission on the library dataset item
            :type   modify_ids[]:      string or list
        :type:      dictionary

        :returns:   dict of current roles for all available permission types
        :rtype:     dictionary

        :raises: RequestParameterInvalidException, ObjectNotFound, InsufficientPermissionsException, InternalServerError
                    RequestParameterMissingException
        """
        if payload:
            kwd.update(payload)
        library_dataset = self.ld_manager.get(trans, managers_base.decode_id(self.app, encoded_dataset_id))
        # Some permissions are attached directly to the underlying dataset.
        dataset = library_dataset.library_dataset_dataset_association.dataset
        current_user_roles = trans.get_current_user_roles()
        can_manage = trans.app.security_agent.can_manage_dataset(current_user_roles, dataset) or trans.user_is_admin()
        if not can_manage:
            raise exceptions.InsufficientPermissionsException('You do not have proper permissions to manage permissions on this dataset.')
        new_access_roles_ids = util.listify(kwd.get('access_ids[]', None))
        new_manage_roles_ids = util.listify(kwd.get('manage_ids[]', None))
        new_modify_roles_ids = util.listify(kwd.get('modify_ids[]', None))
        action = kwd.get('action', None)
        if action is None:
            raise exceptions.RequestParameterMissingException('The mandatory parameter "action" is missing.')
        elif action == 'remove_restrictions':
            trans.app.security_agent.make_dataset_public(dataset)
            if not trans.app.security_agent.dataset_is_public(dataset):
                raise exceptions.InternalServerError('An error occured while making dataset public.')
        elif action == 'make_private':
            if not trans.app.security_agent.dataset_is_private_to_user(trans, library_dataset):
                private_role = trans.app.security_agent.get_private_user_role(trans.user)
                dp = trans.app.model.DatasetPermissions(trans.app.security_agent.permitted_actions.DATASET_ACCESS.action, dataset, private_role)
                trans.sa_session.add(dp)
                trans.sa_session.flush()
            if not trans.app.security_agent.dataset_is_private_to_user(trans, library_dataset):
                # Check again and inform the user if dataset is not private.
                raise exceptions.InternalServerError('An error occured and the dataset is NOT private.')
        elif action == 'set_permissions':
            # ACCESS DATASET ROLES
            valid_access_roles = []
            invalid_access_roles_ids = []
            if new_access_roles_ids is None:
                trans.app.security_agent.make_dataset_public(dataset)
            else:
                for role_id in new_access_roles_ids:
                    role = self.role_manager.get(trans, managers_base.decode_id(self.app, role_id))
                    #  Check whether role is in the set of allowed roles
                    valid_roles, total_roles = trans.app.security_agent.get_valid_roles(trans, dataset)
                    if role in valid_roles:
                        valid_access_roles.append(role)
                    else:
                        invalid_access_roles_ids.append(role_id)
                if len(invalid_access_roles_ids) > 0:
                    log.warning("The following roles could not be added to the dataset access permission: " + str(invalid_access_roles_ids))

                access_permission = dict(access=valid_access_roles)
                trans.app.security_agent.set_dataset_permission(dataset, access_permission)

            # MANAGE DATASET ROLES
            valid_manage_roles = []
            invalid_manage_roles_ids = []
            new_manage_roles_ids = util.listify(new_manage_roles_ids)

            #  Load all access roles to check
            active_access_roles = dataset.get_access_roles(trans)

            for role_id in new_manage_roles_ids:
                role = self.role_manager.get(trans, managers_base.decode_id(self.app, role_id))
                #  Check whether role is in the set of access roles
                if role in active_access_roles:
                    valid_manage_roles.append(role)
                else:
                    invalid_manage_roles_ids.append(role_id)

            if len(invalid_manage_roles_ids) > 0:
                log.warning("The following roles could not be added to the dataset manage permission: " + str(invalid_manage_roles_ids))

            manage_permission = {trans.app.security_agent.permitted_actions.DATASET_MANAGE_PERMISSIONS: valid_manage_roles}
            trans.app.security_agent.set_dataset_permission(dataset, manage_permission)

            # MODIFY LIBRARY ITEM ROLES
            valid_modify_roles = []
            invalid_modify_roles_ids = []
            new_modify_roles_ids = util.listify(new_modify_roles_ids)

            #  Load all access roles to check
            active_access_roles = dataset.get_access_roles(trans)

            for role_id in new_modify_roles_ids:
                role = self.role_manager.get(trans, managers_base.decode_id(self.app, role_id))
                #  Check whether role is in the set of access roles
                if role in active_access_roles:
                    valid_modify_roles.append(role)
                else:
                    invalid_modify_roles_ids.append(role_id)

            if len(invalid_modify_roles_ids) > 0:
                log.warning("The following roles could not be added to the dataset modify permission: " + str(invalid_modify_roles_ids))

            modify_permission = {trans.app.security_agent.permitted_actions.LIBRARY_MODIFY: valid_modify_roles}
            trans.app.security_agent.set_library_item_permission(library_dataset, modify_permission)

        else:
            raise exceptions.RequestParameterInvalidException('The mandatory parameter "action" has an invalid value. '
                                                              'Allowed values are: "remove_restrictions", "make_private", "set_permissions"')

        return self._get_current_roles(trans, library_dataset)