Beispiel #1
0
    def show( self, trans, id, **kwd ):
        """
        GET /api/repositories/{encoded_repository_id}
        Returns information about a repository in the Tool Shed.

        Example URL: http://localhost:9009/api/repositories/f9cad7b01a472135
        
        :param id: the encoded id of the Repository object
        :type  id: encoded str

        :returns:   detailed repository information
        :rtype:     dict

        :raises:  ObjectNotFound, MalformedId
        """
        try:
            trans.security.decode_id( id )
        except Exception:
            raise MalformedId( 'The given id is invalid.' )

        repository = suc.get_repository_in_tool_shed( trans.app, id )
        if repository is None:
            raise ObjectNotFound( 'Unable to locate repository for the given id.' )
        repository_dict = repository.to_dict( view='element',
                                              value_mapper=self.__get_value_mapper( trans ) )
        # TODO the following property would be better suited in the to_dict method
        repository_dict[ 'category_ids' ] = \
            [ trans.security.encode_id( x.category.id ) for x in repository.categories ]
        return repository_dict
Beispiel #2
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.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 marked deleted.

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

        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 = 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('Deleted a cloudauthz record with id `{}` for the user id `{}` '.format(authz_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.' + str(e))
Beispiel #3
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))
Beispiel #4
0
 def _remap(container, line):
     id_match = re.search(ENCODED_ID_PATTERN, line)
     object_id = None
     if id_match:
         object_id = id_match.group(2)
         try:
             decoded_id = trans.security.decode_id(object_id)
         except Exception:
             raise MalformedId("Invalid encoded ID %s" % object_id)
         line = line.replace(id_match.group(), "%s=%d" % (id_match.group(1), decoded_id))
     return (line, False)
Beispiel #5
0
    def decode_folder_id(self, trans, encoded_folder_id):
        """
        Decode the folder id given that it has already lost the prefixed 'F'.

        :param encoded_folder_id: encoded id of the Folder object
        :type  encoded_folder_id: string

        :returns:  decoded Folder id
        :rtype:    int

        :raises: MalformedId
        """
        try:
            decoded_id = trans.security.decode_id(encoded_folder_id)
        except ValueError:
            raise MalformedId("Malformed folder id ( %s ) specified, unable to decode" % (str(encoded_folder_id)))
        return decoded_id
Beispiel #6
0
    def cut_the_prefix(self, encoded_folder_id):
        """
        Remove the prefix from the encoded folder id.

        :param encoded_folder_id: encoded id of the Folder object with 'F' prepended
        :type  encoded_folder_id: string

        :returns:  encoded Folder id without the 'F' prefix
        :rtype:    string

        :raises: MalformedId
        """
        if ((len(encoded_folder_id) % 16 == 1) and encoded_folder_id.startswith('F')):
            cut_id = encoded_folder_id[1:]
        else:
            raise MalformedId('Malformed folder id ( %s ) specified, unable to decode.' % str(encoded_folder_id))
        return cut_id
Beispiel #7
0
    def deserialize_and_validate_authn_id(self, item, key, val, **context):
        """
        Deserializes an authentication ID (authn_id), and asserts if the
        current user can assume that authentication.

        :type  item:    galaxy.model.CloudAuthz
        :param item:    an instance of cloudauthz

        :type  key:     string
        :param key:     `authn_id` attribute of the cloudauthz object (i.e., the `item` param).

        :type  val:     string
        :param val:     the value of `authn_id` attribute of the cloudauthz object (i.e., the `item` param).

        :type  context: dict
        :param context: a dictionary object containing Galaxy `trans`.

        :rtype:         string
        :return:        decoded authentication ID.
        """

        try:
            decoded_authn_id = self.app.security.decode_id(val)
        except Exception:
            log.debug("cannot decode authz_id `" + str(val) + "`")
            raise MalformedId("Invalid `authz_id` {}!".format(val))

        trans = context.get("trans")
        if trans is None:
            log.debug(
                "Not found expected `trans` when deserializing CloudAuthz.")
            raise InternalServerError

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

        return decoded_authn_id
Beispiel #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))