Exemplo n.º 1
0
    def update(self, trans, encoded_folder_id, payload: dict):
        """
        Update the folder defined by an ``encoded_folder_id``
        with the data in the payload.

       .. note:: Currently, only admin users can update library folders. Also the folder must not be `deleted`.

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

        :param  payload: (required) dictionary structure containing::
            'name':         new folder's name, cannot be empty
            'description':  new folder's description
        :type   payload: dict

        :returns:   detailed folder information
        :rtype:     dict

        :raises: RequestParameterMissingException
        """
        decoded_folder_id = self.folder_manager.cut_and_decode(
            trans, encoded_folder_id)
        folder = self.folder_manager.get(trans, decoded_folder_id)
        name = payload.get('name', None)
        if not name:
            raise RequestParameterMissingException(
                "Parameter 'name' of library folder is required. You cannot remove it."
            )
        description = payload.get('description', None)
        updated_folder = self.folder_manager.update(trans, folder, name,
                                                    description)
        folder_dict = self.folder_manager.get_folder_dict(
            trans, updated_folder)
        return folder_dict
Exemplo n.º 2
0
    def create(self, trans, payload, **kwd):
        """
        POST /api/groups
        Return a dictionary of information about the created group.
        The following parameters are included in the payload:

        :param name (required): the name of the group
        :param description (optional): the description of the group

        Example: POST /api/groups/?key=XXXYYYXXXYYY
        Content-Disposition: form-data; name="name" Group_Name
        Content-Disposition: form-data; name="description" Group_Description
        """
        group_dict = dict(message='', status='ok')
        name = payload.get('name', '')
        if name:
            description = payload.get('description', '')
            if not description:
                description = ''
            else:
                # TODO add description field to the model
                group_dict = self.group_manager.create(
                    trans, name=name).to_dict(
                        view='element',
                        value_mapper=self.__get_value_mapper(trans))
        else:
            raise RequestParameterMissingException(
                'Missing required parameter "name".')
        return group_dict
Exemplo n.º 3
0
    def create(self, trans, encoded_parent_folder_id, payload: dict):
        """
        Create a new folder object underneath the one specified in the parameters.

        :param  encoded_parent_folder_id:      (required) the parent folder's id
        :type   encoded_parent_folder_id:      an encoded id string (should be prefixed by 'F')
        :param   payload: dictionary structure containing:

            :param  name:                          (required) the name of the new folder
            :type   name:                          str
            :param  description:                   the description of the new folder
            :type   description:                   str

        :type       dictionary
        :returns:   information about newly created folder, notably including ID
        :rtype:     dictionary
        :raises: RequestParameterMissingException
        """
        name = payload.get('name', None)
        if name is None:
            raise RequestParameterMissingException(
                "Missing required parameter 'name'.")
        description = payload.get('description', '')
        decoded_parent_folder_id = self.folder_manager.cut_and_decode(
            trans, encoded_parent_folder_id)
        parent_folder = self.folder_manager.get(trans,
                                                decoded_parent_folder_id)
        new_folder = self.folder_manager.create(trans, parent_folder.id, name,
                                                description)
        return self.folder_manager.get_folder_dict(trans, new_folder)
Exemplo n.º 4
0
 def _parse_dependency_info(self, kwds):
     extra_kwds = kwds.copy()
     name = extra_kwds.pop("name", None)
     if name is None:
         raise RequestParameterMissingException("Missing 'name' parameter required for resolution.")
     version = extra_kwds.pop("version", None)
     type = extra_kwds.pop("type", "package")
     return name, version, type, extra_kwds
Exemplo n.º 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
 def replace_file_srcs(request_part):
     if isinstance(request_part, dict):
         if request_part.get("src", None) == "files":
             path_def = next(files_iter)
             if path_def is None or path_def["file_data"] is None:
                 raise RequestParameterMissingException("Failed to find uploaded file matching target with src='files'")
             request_part["path"] = path_def["file_data"]["local_filename"]
             if "name" not in request_part:
                 request_part["name"] = path_def["file_data"]["filename"]
             request_part["src"] = "path"
         else:
             for key, value in request_part.items():
                 replace_file_srcs(value)
     elif isinstance(request_part, list):
         for value in request_part:
             replace_file_srcs(value)
Exemplo n.º 7
0
def validation_error_to_message_exception(e):
    invalid_found = False
    missing_found = False
    for error in e.errors():
        if error["type"] == "value_error.missing" or error[
                "type"] == "type_error.none.not_allowed":
            missing_found = True
        elif error["type"].startswith("type_error"):
            invalid_found = True
    if missing_found and not invalid_found:
        return RequestParameterMissingException(str(e),
                                                validation_errors=loads(
                                                    e.json()))
    else:
        return RequestParameterInvalidException(str(e),
                                                validation_errors=loads(
                                                    e.json()))
Exemplo n.º 8
0
    def configure_provider(provider, credentials):
        """
        Given a provider name and required credentials, it configures and returns a cloudbridge
        connection to the provider.

        :type  provider: string
        :param provider: the name of cloud-based resource provided. A list of supported providers is given in
                         `SUPPORTED_PROVIDERS` variable.

        :type  credentials: dict
        :param credentials: a dictionary containing all the credentials required to authenticated to the
                            specified provider.

        :rtype: provider specific, e.g., `cloudbridge.cloud.providers.aws.provider.AWSCloudProvider` for AWS.
        :return: a cloudbridge connection to the specified provider.
        """
        missing_credentials = []
        if provider == 'aws':
            access = credentials.get('access_key', None)
            if access is None:
                access = credentials.get("AccessKeyId", None)
                if access is None:
                    missing_credentials.append('access_key')
            secret = credentials.get('secret_key', None)
            if secret is None:
                secret = credentials.get("SecretAccessKey", None)
                if secret is None:
                    missing_credentials.append('secret_key')
            if len(missing_credentials) > 0:
                raise RequestParameterMissingException(
                    "The following required key(s) are missing from the provided "
                    "credentials object: {}".format(missing_credentials))
            session_token = credentials.get("SessionToken")
            config = {
                'aws_access_key': access,
                'aws_secret_key': secret,
                "aws_session_token": session_token
            }
            connection = CloudProviderFactory().create_provider(
                ProviderList.AWS, config)
        elif provider == "azure":
            subscription = credentials.get('subscription_id', None)
            if subscription is None:
                missing_credentials.append('subscription_id')
            client = credentials.get('client_id', None)
            if client is None:
                missing_credentials.append('client_id')
            secret = credentials.get('secret', None)
            if secret is None:
                missing_credentials.append('secret')
            tenant = credentials.get('tenant', None)
            if tenant is None:
                missing_credentials.append('tenant')
            if len(missing_credentials) > 0:
                raise RequestParameterMissingException(
                    "The following required key(s) are missing from the provided "
                    "credentials object: {}".format(missing_credentials))

            config = {
                'azure_subscription_id': subscription,
                'azure_client_id': client,
                'azure_secret': secret,
                'azure_tenant': tenant
            }
            storage_account = credentials.get("storage_account")
            if storage_account:
                config["azure_storage_account"] = storage_account
            resource_group = credentials.get("resource_group")
            if resource_group:
                config["azure_resource_group"] = resource_group
            connection = CloudProviderFactory().create_provider(
                ProviderList.AZURE, config)
        elif provider == "openstack":
            username = credentials.get('username', None)
            if username is None:
                missing_credentials.append('username')
            password = credentials.get('password', None)
            if password is None:
                missing_credentials.append('password')
            auth_url = credentials.get('auth_url', None)
            if auth_url is None:
                missing_credentials.append('auth_url')
            prj_name = credentials.get('project_name', None)
            if prj_name is None:
                missing_credentials.append('project_name')
            prj_domain_name = credentials.get('project_domain_name', None)
            if prj_domain_name is None:
                missing_credentials.append('project_domain_name')
            user_domain_name = credentials.get('user_domain_name', None)
            if user_domain_name is None:
                missing_credentials.append('user_domain_name')
            if len(missing_credentials) > 0:
                raise RequestParameterMissingException(
                    "The following required key(s) are missing from the provided "
                    "credentials object: {}".format(missing_credentials))
            config = {
                'os_username': username,
                'os_password': password,
                'os_auth_url': auth_url,
                'os_project_name': prj_name,
                'os_project_domain_name': prj_domain_name,
                'os_user_domain_name': user_domain_name
            }
            connection = CloudProviderFactory().create_provider(
                ProviderList.OPENSTACK, config)
        elif provider == "gcp":
            config = {"gcp_service_creds_dict": credentials}
            connection = CloudProviderFactory().create_provider(
                ProviderList.GCP, config)
        else:
            raise RequestParameterInvalidException(
                "Unrecognized provider '{}'; the following are the supported "
                "providers: {}.".format(provider, SUPPORTED_PROVIDERS.keys()))

        # The authorization-assertion mechanism of Cloudbridge assumes a user has an elevated privileges,
        # such as Admin-level access to all resources (see https://github.com/CloudVE/cloudbridge/issues/135).
        # As a result, a user who wants to authorize Galaxy to read/write an Amazon S3 bucket, need to
        # also authorize Galaxy with full permission to Amazon EC2 (because Cloudbridge leverages EC2-specific
        # operation to assert credentials). While the EC2 authorization is not required by Galaxy to
        # read/write a S3 bucket, it can cause this exception.
        #
        # Until Cloudbridge implements an authorization-specific credentials assertion, we are not asserting
        # the authorization/validity of the credentials, in order to avoid asking users to grant Galaxy with an
        # elevated, yet unnecessary, privileges.
        #
        # Note, if user's credentials are invalid/expired to perform the authorized action, that can cause
        # exceptions which we capture separately in related read/write attempts.
        return connection
Exemplo n.º 9
0
    def create( self, trans, **kwd ):
        """
        create( self, trans, payload, **kwd )
        * POST /api/repositories:
            Creates a new repository.
            Only ``name`` and ``synopsis`` parameters are required.

        :param payload: dictionary structure containing::
            'name':                  new repo's name (required)
            'synopsis':              new repo's synopsis (required)
            'description':           new repo's description (optional)
            'remote_repository_url': new repo's remote repo (optional)
            'homepage_url':          new repo's homepage url (optional)
            'category_ids[]':        list of existing encoded TS category ids
                                     the new repo should be associated with (optional)
            'type':                  new repo's type, defaults to ``unrestricted`` (optional)

        :type payload: dict

        :returns:   detailed repository information
        :rtype:     dict

        :raises: RequestParameterMissingException, RequestParameterInvalidException
        """
        payload = kwd.get( 'payload', None )
        if not payload:
            raise RequestParameterMissingException( "You did not specify any payload." )
        name = payload.get( 'name', None )
        if not name:
            raise RequestParameterMissingException( "Missing required parameter 'name'." )
        synopsis = payload.get( 'synopsis', None )
        if not synopsis:
            raise RequestParameterMissingException( "Missing required parameter 'synopsis'." )

        description = payload.get( 'description', '' )
        remote_repository_url = payload.get( 'remote_repository_url', '' )
        homepage_url = payload.get( 'homepage_url', '' )
        category_ids = util.listify( payload.get( 'category_ids[]', '' ) )
        selected_categories = [ trans.security.decode_id( id ) for id in category_ids ]

        repo_type = payload.get( 'type', rt_util.UNRESTRICTED )
        if repo_type not in rt_util.types:
            raise RequestParameterInvalidException( 'This repository type is not valid' )

        invalid_message = repository_util.validate_repository_name( trans.app, name, trans.user )
        if invalid_message:
            raise RequestParameterInvalidException( invalid_message )

        repo, message = repository_util.create_repository( app=trans.app,
                                                  name=name,
                                                  type=repo_type,
                                                  description=synopsis,
                                                  long_description=description,
                                                  user_id = trans.user.id,
                                                  category_ids=category_ids,
                                                  remote_repository_url=remote_repository_url,
                                                  homepage_url=homepage_url )

        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
Exemplo n.º 10
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))
Exemplo n.º 11
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)
Exemplo n.º 12
0
    def _configure_provider(provider, credentials):
        """
        Given a provider name and required credentials, it configures and returns a cloudbridge
        connection to the provider.

        :type  provider: string
        :param provider: the name of cloud-based resource provided. A list of supported providers is given in
        `SUPPORTED_PROVIDERS` variable.

        :type  credentials: dict
        :param credentials: a dictionary containing all the credentials required to authenticated to the
        specified provider.

        :rtype: provider specific, e.g., `cloudbridge.cloud.providers.aws.provider.AWSCloudProvider` for AWS.
        :return: a cloudbridge connection to the specified provider.
        """
        missing_credentials = []
        if provider == 'aws':
            access = credentials.get('access_key', None)
            if access is None:
                missing_credentials.append('access_key')
            secret = credentials.get('secret_key', None)
            if secret is None:
                missing_credentials.append('secret_key')
            if len(missing_credentials) > 0:
                raise RequestParameterMissingException(
                    "The following required key(s) are missing from the provided "
                    "credentials object: {}".format(missing_credentials))

            config = {'aws_access_key': access, 'aws_secret_key': secret}
            connection = CloudProviderFactory().create_provider(
                ProviderList.AWS, config)
        elif provider == "azure":
            subscription = credentials.get('subscription_id', None)
            if subscription is None:
                missing_credentials.append('subscription_id')
            client = credentials.get('client_id', None)
            if client is None:
                missing_credentials.append('client_id')
            secret = credentials.get('secret', None)
            if secret is None:
                missing_credentials.append('secret')
            tenant = credentials.get('tenant', None)
            if tenant is None:
                missing_credentials.append('tenant')
            if len(missing_credentials) > 0:
                raise RequestParameterMissingException(
                    "The following required key(s) are missing from the provided "
                    "credentials object: {}".format(missing_credentials))

            config = {
                'azure_subscription_id': subscription,
                'azure_client_id': client,
                'azure_secret': secret,
                'azure_tenant': tenant
            }
            connection = CloudProviderFactory().create_provider(
                ProviderList.AZURE, config)
        elif provider == "openstack":
            username = credentials.get('username', None)
            if username is None:
                missing_credentials.append('username')
            password = credentials.get('password', None)
            if password is None:
                missing_credentials.append('password')
            auth_url = credentials.get('auth_url', None)
            if auth_url is None:
                missing_credentials.append('auth_url')
            prj_name = credentials.get('project_name', None)
            if prj_name is None:
                missing_credentials.append('project_name')
            prj_domain_name = credentials.get('project_domain_name', None)
            if prj_domain_name is None:
                missing_credentials.append('project_domain_name')
            user_domain_name = credentials.get('user_domain_name', None)
            if user_domain_name is None:
                missing_credentials.append('user_domain_name')
            if len(missing_credentials) > 0:
                raise RequestParameterMissingException(
                    "The following required key(s) are missing from the provided "
                    "credentials object: {}".format(missing_credentials))
            config = {
                'os_username': username,
                'os_password': password,
                'os_auth_url': auth_url,
                'os_project_name': prj_name,
                'os_project_domain_name': prj_domain_name,
                'os_user_domain_name': user_domain_name
            }
            connection = CloudProviderFactory().create_provider(
                ProviderList.OPENSTACK, config)
        else:
            raise RequestParameterInvalidException(
                "Unrecognized provider '{}'; the following are the supported "
                "providers: {}.".format(provider, SUPPORTED_PROVIDERS))

        try:
            if connection.authenticate():
                return connection
        except ProviderConnectionException as e:
            raise AuthenticationFailed(
                "Could not authenticate to the '{}' provider. {}".format(
                    provider, e))