Ejemplo n.º 1
0
    def get(self, trans, decoded_group_id=None, name=None):
        """
        Get the group from the DB based on its ID or name.

        :param  decoded_group_id:       decoded group id
        :type   decoded_group_id:       int

        :returns:   the requested group
        :rtype:     Group
        """
        if decoded_group_id is None and name is None:
            raise RequestParameterInvalidException(
                'You must supply either ID or a name of the group.')

        name_query = trans.sa_session.query(trans.app.model.Group).filter(
            trans.app.model.Group.table.c.name == name)
        id_query = trans.sa_session.query(trans.app.model.Group).filter(
            trans.app.model.Group.table.c.id == decoded_group_id)

        try:
            group = id_query.one() if decoded_group_id else name_query.one()
        except MultipleResultsFound:
            raise InconsistentDatabase(
                'Multiple groups found with the same identifier.')
        except NoResultFound:
            raise ObjectNotFound(
                'No group found with the identifier provided.')
        except Exception:
            raise InternalServerError('Error loading from the database.')
        return group
Ejemplo n.º 2
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

        :raises: InconsistentDatabase, RequestParameterInvalidException, InternalServerError
        """
        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 InconsistentDatabase('Multiple folders found with the same id.')
        except NoResultFound:
            raise RequestParameterInvalidException('No folder found with the id provided.')
        except Exception as e:
            raise InternalServerError('Error loading from the database.' + unicodify(e))
        folder = self.secure(trans, folder, check_manageable, check_accessible)
        return folder
Ejemplo n.º 3
0
    def delete(self, trans, encoded_authz_id, **kwargs):
        """
        * DELETE /api/cloud/authz/{encoded_authz_id}
            Deletes the CloudAuthz record with the given ``encoded_authz_id`` from database.

        :type  trans: galaxy.webapps.base.webapp.GalaxyWebTransaction
        :param trans: Galaxy web transaction

        :type  encoded_authz_id:    string
        :param encoded_authz_id:    The encoded ID of the CloudAuthz record to be marked deleted.

        :rtype  JSON
        :return The cloudauthz record marked as deleted, serialized as a JSON object.
        """

        msg_template = f"Rejected user `{str(trans.user.id)}`'s request to delete cloudauthz config because of {{}}."
        try:
            authz_id = self.decode_id(encoded_authz_id)
        except MalformedId as e:
            log.debug(msg_template.format(f"cannot decode authz_id `{encoded_authz_id}`"))
            raise e

        try:
            cloudauthz = trans.app.authnz_manager.try_get_authz_config(trans.sa_session, trans.user.id, authz_id)
            trans.sa_session.delete(cloudauthz)
            trans.sa_session.flush()
            log.debug(f'Deleted a cloudauthz record with id `{authz_id}` for the user id `{str(trans.user.id)}` ')
            view = self.cloudauthz_serializer.serialize_to_view(cloudauthz, trans=trans, **self._parse_serialization_params(kwargs, 'summary'))
            trans.response.status = '200'
            return view
        except Exception as e:
            log.exception(msg_template.format("exception while deleting the cloudauthz record with "
                                              "ID: `{}`.".format(encoded_authz_id)))
            raise InternalServerError('An unexpected error has occurred while responding to the DELETE request of the '
                                      'cloudauthz API.' + unicodify(e))
Ejemplo n.º 4
0
    def update(self, trans, encoded_authz_id, payload, **kwargs):
        """
        * PUT /api/cloud/authz/{encoded_authz_id}
            Updates the values for the cloudauthz configuration with the given ``encoded_authz_id``.

            With this API only the following attributes of a cloudauthz configuration
            can be updated: `authn_id`, `provider`, `config`, `deleted`.

        :type  trans:               galaxy.web.framework.webapp.GalaxyWebTransaction
        :param trans:               Galaxy web transaction

        :type  encoded_authz_id:    string
        :param encoded_authz_id:    The encoded ID of the CloudAuthz record to be updated.

        :type payload:              dict
        :param payload:             A dictionary structure containing the attributes to modified with their new values.
                                    It can contain any number of the following attributes:
                                        *   provider:   the cloud-based resource provider
                                                        to which this configuration belongs to.

                                        *   authn_id:   the (encoded) ID of a third-party authentication of a user.
                                                        To have this ID, user must have logged-in to this Galaxy server
                                                        using third-party identity (e.g., Google), or has associated
                                                        their Galaxy account with a third-party OIDC-based identity.
                                                        See this page: https://galaxyproject.org/admin/authentication/

                                                        Note: A user can associate a cloudauthz record with their own
                                                        authentications only. If the given authentication with authn_id
                                                        belongs to a different user, Galaxy will throw the
                                                        ItemAccessibilityException exception.

                                        *   config:     a dictionary containing all the configuration required to
                                                        request temporary credentials from the provider.
                                                        See the following page for details:
                                                        https://galaxyproject.org/cloud/authnz/

                                        *   deleted:    a boolean type marking the specified cloudauthz as (un)deleted.

        """

        msg_template = "Rejected user `" + str(trans.user.id) + "`'s request to delete cloudauthz config because of {}."
        try:
            authz_id = self.decode_id(encoded_authz_id)
        except Exception:
            log.debug(msg_template.format("cannot decode authz_id `" + str(encoded_authz_id) + "`"))
            raise MalformedId('Invalid `authz_id`!')

        try:
            cloudauthz_to_update = trans.app.authnz_manager.try_get_authz_config(trans.sa_session, trans.user.id, authz_id)
            self.cloudauthz_deserializer.deserialize(cloudauthz_to_update, payload, trans=trans)
            self.cloudauthz_serializer.serialize_to_view(cloudauthz_to_update, view='summary')
            return self.cloudauthz_serializer.serialize_to_view(cloudauthz_to_update, view='summary')
        except MalformedId as e:
            raise e
        except Exception as e:
            log.exception(msg_template.format("exception while updating the cloudauthz record with "
                                              "ID: `{}`.".format(encoded_authz_id)))
            raise InternalServerError('An unexpected error has occurred while responding to the PUT request of the '
                                      'cloudauthz API.' + str(e))
Ejemplo n.º 5
0
    def index(self, trans, **kwds):
        """
        GET /api/tools: returns a list of tools defined by parameters::

            parameters:

                in_panel  - if true, tools are returned in panel structure,
                            including sections and labels
                trackster - if true, only tools that are compatible with
                            Trackster are returned
                q         - if present search on the given query will be performed
                tool_id   - if present the given tool_id will be searched for
                            all installed versions
        """

        # Read params.
        in_panel = util.string_as_bool(kwds.get('in_panel', 'True'))
        trackster = util.string_as_bool(kwds.get('trackster', 'False'))
        q = kwds.get('q', '')
        tool_id = kwds.get('tool_id', '')

        # Find whether to search.
        if q:
            hits = self._search(q)
            results = []
            if hits:
                for hit in hits:
                    tool = self._get_tool(hit)
                    if tool:
                        results.append(tool.id)
            return results

        # Find whether to detect.
        if tool_id:
            detected_versions = self._detect(trans, tool_id)
            return detected_versions

        # Return everything.
        try:
            return self.app.toolbox.to_dict(trans,
                                            in_panel=in_panel,
                                            trackster=trackster)
        except Exception:
            raise InternalServerError(
                "Error: Could not convert toolbox to dictionary")
Ejemplo n.º 6
0
    def get(self, trans, decoded_library_dataset_id, check_accessible=True):
        """
        Get the library dataset from the DB.

        :param  decoded_library_dataset_id: decoded library dataset id
        :type   decoded_library_dataset_id: int
        :param  check_accessible:           flag whether to check that user can access item
        :type   check_accessible:           bool

        :returns:   the requested library dataset
        :rtype:     galaxy.model.LibraryDataset
        """
        try:
            ld = trans.sa_session.query(trans.app.model.LibraryDataset).filter(trans.app.model.LibraryDataset.table.c.id == decoded_library_dataset_id).one()
        except Exception as e:
            raise InternalServerError('Error loading from the database.' + util.unicodify(e))
        ld = self.secure(trans, ld, check_accessible)
        return ld
Ejemplo n.º 7
0
    def get(self, trans, decoded_repo_id):
        """
        Get the repo from the DB.

        :param  decoded_repo_id:       decoded repo id
        :type   decoded_repo_id:       int

        :returns:   the requested repo
        :rtype:     Repository
        """
        try:
            repo = trans.sa_session.query(trans.app.model.Repository).filter(trans.app.model.Repository.table.c.id == decoded_repo_id).one()
        except MultipleResultsFound:
            raise InconsistentDatabase('Multiple repositories found with the same id.')
        except NoResultFound:
            raise RequestParameterInvalidException('No repository found with the id provided.')
        except Exception:
            raise InternalServerError('Error loading from the database.')
        return repo
Ejemplo n.º 8
0
    def create(self, trans, payload, **kwargs):
        """
        * POST /api/cloud/authz
            Request to store the payload as a cloudauthz (cloud authorization) configuration for a user.

        :type  trans: galaxy.webapps.base.webapp.GalaxyWebTransaction
        :param trans: Galaxy web transaction

        :type payload: dict
        :param payload: A dictionary structure containing the following keys:
            *   provider:       the cloud-based resource provider to which this configuration belongs to.

            *   config:         a dictionary containing all the configuration required to request temporary credentials
                                from the provider. See the following page for details:
                                https://galaxyproject.org/cloud/authnz/

            *   authn_id:       the (encoded) ID of a third-party authentication of a user. To have this ID, user must
                                have logged-in to this Galaxy server using third-party identity (e.g., Google), or has
                                associated his/her Galaxy account with a third-party OIDC-based identity. See this page:
                                https://galaxyproject.org/admin/authentication/

            *   description:    [Optional] a brief description for this configuration.

        :param kwargs: empty dict

        :rtype: dict
        :return: a dictionary with the following kvp:
            *   status:     HTTP response code
            *   message:    A message complementary to the response code.
        """
        msg_template = "Rejected user `" + str(
            trans.user.id
        ) + "`'s request to create cloudauthz config because of {}."
        if not isinstance(payload, dict):
            raise ActionInputError(
                'Invalid payload data type. The payload is expected to be a dictionary, but '
                'received data of type `{}`.'.format(str(type(payload))))

        missing_arguments = []
        provider = payload.get('provider', None)
        if provider is None:
            missing_arguments.append('provider')

        config = payload.get('config', None)
        if config is None:
            missing_arguments.append('config')

        authn_id = payload.get('authn_id', None)
        if authn_id is None and provider.lower() not in ["azure", "gcp"]:
            missing_arguments.append('authn_id')

        if len(missing_arguments) > 0:
            log.debug(
                msg_template.format(
                    "missing required config {}".format(missing_arguments)))
            raise RequestParameterMissingException(
                'The following required arguments are missing in the payload: '
                '{}'.format(missing_arguments))

        description = payload.get("description", "")

        if not isinstance(config, dict):
            log.debug(
                msg_template.format(
                    "invalid config type `{}`, expect `dict`".format(
                        type(config))))
            raise RequestParameterInvalidException(
                'Invalid type for the required `config` variable; expect `dict` '
                'but received `{}`.'.format(type(config)))
        if authn_id:
            try:
                authn_id = self.decode_id(authn_id)
            except Exception:
                log.debug(
                    msg_template.format("cannot decode authn_id `" +
                                        str(authn_id) + "`"))
                raise MalformedId('Invalid `authn_id`!')

            try:
                trans.app.authnz_manager.can_user_assume_authn(trans, authn_id)
            except Exception as e:
                raise e

        # No two authorization configuration with
        # exact same key/value should exist.
        for ca in trans.user.cloudauthzs:
            if ca.equals(trans.user.id, provider, authn_id, config):
                log.debug(
                    "Rejected user `{}`'s request to create cloud authorization because a similar config "
                    "already exists.".format(trans.user.id))
                raise ActionInputError(
                    "A similar cloud authorization configuration is already defined."
                )

        try:
            new_cloudauthz = self.cloudauthz_manager.create(
                user_id=trans.user.id,
                provider=provider,
                config=config,
                authn_id=authn_id,
                description=description)
            view = self.cloudauthz_serializer.serialize_to_view(
                new_cloudauthz,
                trans=trans,
                **self._parse_serialization_params(kwargs, 'summary'))
            log.debug(
                'Created a new cloudauthz record for the user id `{}` '.format(
                    str(trans.user.id)))
            return view
        except Exception as e:
            log.exception(
                msg_template.format(
                    "exception while creating the new cloudauthz record"))
            raise InternalServerError(
                'An unexpected error has occurred while responding to the create request of the '
                'cloudauthz API.' + unicodify(e))