diff --git a/lib/galaxy/authnz/managers.py b/lib/galaxy/authnz/managers.py index fe030be0b34..93fc3c010ac 100644 --- a/lib/galaxy/authnz/managers.py +++ b/lib/galaxy/authnz/managers.py @@ -1,13 +1,5 @@ import builtins -import copy -import json import logging -import os -import random -import string - -from cloudauthz import CloudAuthz -from cloudauthz.exceptions import CloudAuthzBaseException from galaxy import ( exceptions, @@ -18,7 +10,6 @@ from galaxy.util import ( etree, listify, parse_xml, - requests, string_as_bool, unicodify, ) @@ -32,10 +23,7 @@ from .custos_authnz import ( ) from .psa_authnz import ( BACKENDS_NAME, - on_the_fly_config, PSAAuthnz, - Storage, - Strategy, ) OIDC_BACKEND_SCHEMA = resource_path(__package__, "xsd/oidc_backends_config.xsd") @@ -263,35 +251,6 @@ class AuthnzManager: else: return None - def _extend_cloudauthz_config(self, cloudauthz, request, sa_session, user_id): - config = copy.deepcopy(cloudauthz.config) - if cloudauthz.provider == "aws": - success, message, backend = self._get_authnz_backend(cloudauthz.authn.provider) - strategy = Strategy(request, None, Storage, backend.config) - on_the_fly_config(sa_session) - try: - config["id_token"] = cloudauthz.authn.get_id_token(strategy) - except requests.exceptions.HTTPError as e: - msg = ( - f"Sign-out from Galaxy and remove its access from `{self._unify_provider_name(cloudauthz.authn.provider)}`, " - "then log back in using `{cloudauthz.authn.uid}` account." - ) - log.debug( - "Failed to get/refresh ID token for user with ID `%s` for assuming authz_id `%s`. " - "User may not have a refresh token. If the problem persists, set the `prompt` key to " - "`consent` in `oidc_backends_config.xml`, then restart Galaxy and ask user to: %s" - "Error Message: `%s`", - user_id, - cloudauthz.id, - msg, - e.response.text, - ) - raise exceptions.AuthenticationFailed( - err_msg=f"An error occurred getting your ID token. {msg}. If the problem persists, please " - "contact Galaxy admin." - ) - return config - @staticmethod def can_user_assume_authn(trans, authn_id): qres = trans.sa_session.query(model.UserAuthnzToken).get(authn_id) @@ -307,36 +266,6 @@ class AuthnzManager: log.warning(msg) raise exceptions.ItemAccessibilityException(msg) - @staticmethod - def try_get_authz_config(sa_session, user_id, authz_id): - """ - It returns a cloudauthz config (see model.CloudAuthz) with the - given ID; and raise an exception if either a config with given - ID does not exist, or the configuration is defined for a another - user than trans.user. - - :type trans: galaxy.webapps.base.webapp.GalaxyWebTransaction - :param trans: Galaxy web transaction - - :type authz_id: int - :param authz_id: The ID of a CloudAuthz configuration to be used for - getting temporary credentials. - - :rtype : model.CloudAuthz - :return: a cloudauthz configuration. - """ - qres = sa_session.query(model.CloudAuthz).get(authz_id) - if qres is None: - raise exceptions.ObjectNotFound("An authorization configuration with given ID not found.") - if user_id != qres.user_id: - msg = ( - f"The request authorization configuration (with ID:`{qres.id}`) is not accessible for user with " - f"ID:`{user_id}`." - ) - log.warning(msg) - raise exceptions.ItemAccessibilityException(msg) - return qres - def refresh_expiring_oidc_tokens_for_provider(self, trans, auth): try: success, message, backend = self._get_authnz_backend(auth.provider) @@ -509,98 +438,3 @@ class AuthnzManager: msg = f"An error occurred when disconnecting authentication with `{provider}` identity provider for user `{trans.user.username}`" log.exception(msg) return False, msg, None - - def get_cloud_access_credentials(self, cloudauthz, sa_session, user_id, request=None): - """ - This method leverages CloudAuthz (https://github.com/galaxyproject/cloudauthz) - to request a cloud-based resource provider (e.g., Amazon AWS, Microsoft Azure) - for temporary access credentials to a given resource. - - It first checks if a cloudauthz config with the given ID (`authz_id`) is - available and can be assumed by the user, and raises an exception if either - is false. Otherwise, it then extends the cloudauthz configuration as required - by the CloudAuthz library for the provider specified in the configuration. - For instance, it adds on-the-fly values such as a valid OpenID Connect - identity token, as required by CloudAuthz for AWS. Then requests temporary - credentials from the CloudAuthz library using the updated configuration. - - :type cloudauthz: CloudAuthz - :param cloudauthz: an instance of CloudAuthz to be used for getting temporary - credentials. - - :type sa_session: sqlalchemy.orm.scoping.scoped_session - :param sa_session: SQLAlchemy database handle. - - :type user_id: int - :param user_id: Decoded Galaxy user ID. - - :type request: galaxy.web.framework.base.Request - :param request: Encapsulated HTTP(S) request. - - :rtype: dict - :return: a dictionary containing credentials to access a cloud-based - resource provider. See CloudAuthz (https://github.com/galaxyproject/cloudauthz) - for details on the content of this dictionary. - """ - config = self._extend_cloudauthz_config(cloudauthz, request, sa_session, user_id) - try: - ca = CloudAuthz() - log.info( - "Requesting credentials using CloudAuthz with config id `%s` on be half of user `%s`.", - cloudauthz.id, - user_id, - ) - credentials = ca.authorize(cloudauthz.provider, config) - return credentials - except CloudAuthzBaseException as e: - log.info(e) - raise exceptions.AuthenticationFailed(e) - except NotImplementedError as e: - log.info(e) - raise exceptions.RequestParameterInvalidException(e) - - def get_cloud_access_credentials_in_file(self, new_file_path, cloudauthz, sa_session, user_id, request=None): - """ - This method leverages CloudAuthz (https://github.com/galaxyproject/cloudauthz) - to request a cloud-based resource provider (e.g., Amazon AWS, Microsoft Azure) - for temporary access credentials to a given resource. - - This method uses the `get_cloud_access_credentials` method to obtain temporary - credentials, and persists them to a (temporary) file, and returns the file path. - - :type new_file_path: str - :param new_file_path: Where dataset files are saved on temporary storage. - See `app.config.new_file_path`. - - :type cloudauthz: CloudAuthz - :param cloudauthz: an instance of CloudAuthz to be used for getting temporary - credentials. - - :type sa_session: sqlalchemy.orm.scoping.scoped_session - :param sa_session: SQLAlchemy database handle. - - :type user_id: int - :param user_id: Decoded Galaxy user ID. - - :type request: galaxy.web.framework.base.Request - :param request: [Optional] Encapsulated HTTP(S) request. - - :rtype: str - :return: The filename to which credentials are written. - """ - filename = os.path.abspath( - os.path.join( - new_file_path, - "cd_" - + "".join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(11)), - ) - ) - credentials = self.get_cloud_access_credentials(cloudauthz, sa_session, user_id, request) - log.info( - "Writing credentials generated using CloudAuthz with config id `%s` to the following file: `%s`", - cloudauthz.id, - filename, - ) - with open(filename, "w") as f: - f.write(json.dumps(credentials)) - return filename