""" Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. SPDX-License-Identifier: Apache-2.0 OR MIT """ import boto3 import configparser import logging import os import pytest import typing logger = logging.getLogger(__name__) logging.getLogger('boto').setLevel(logging.CRITICAL) class AwsCredentials: def __init__(self, profile_name: str): self._profile_name = profile_name self._credentials_path = os.environ.get('AWS_SHARED_CREDENTIALS_FILE') if not self._credentials_path: # Home directory location varies based on the operating system, but is referred to using the environment # variables %UserProfile% in Windows and $HOME or ~ (tilde) in Unix-based systems. self._credentials_path = os.path.join(os.environ.get('UserProfile', os.path.expanduser('~')), '.aws', 'credentials') self._credentials_file_exists = os.path.exists(self._credentials_path) self._credentials = configparser.ConfigParser() self._credentials.read(self._credentials_path) def get_aws_credentials(self) -> typing.Tuple[str, str, str]: """ Get aws credentials stored in the specific named profile. :return AWS credentials. """ access_key_id = self._get_aws_credential_attribute_value('aws_access_key_id') secret_access_key = self._get_aws_credential_attribute_value('aws_secret_access_key') session_token = self._get_aws_credential_attribute_value('aws_session_token') return access_key_id, secret_access_key, session_token def set_aws_credentials_by_session(self, session: boto3.Session) -> None: """ Set AWS credentials stored in the specific named profile using an assumed role session. :param session: assumed role session. """ credentials = session.get_credentials().get_frozen_credentials() self.set_aws_credentials(credentials.access_key, credentials.secret_key, credentials.token) def set_aws_credentials(self, aws_access_key_id: str, aws_secret_access_key: str, aws_session_token: str) -> None: """ Set AWS credentials stored in the specific named profile. :param aws_access_key_id: AWS access key id. :param aws_secret_access_key: AWS secrete access key. :param aws_session_token: AWS assumed role session. """ self._set_aws_credential_attribute_value('aws_access_key_id', aws_access_key_id) self._set_aws_credential_attribute_value('aws_secret_access_key', aws_secret_access_key) self._set_aws_credential_attribute_value('aws_session_token', aws_session_token) if (len(self._credentials.sections()) == 0) and (not self._credentials_file_exists): os.remove(self._credentials_path) return credentials_file_dir = os.path.dirname(self._credentials_path) if not os.path.isdir(credentials_file_dir): os.makedirs(credentials_file_dir) with open(self._credentials_path, 'w+') as credential_file: self._credentials.write(credential_file) def _get_aws_credential_attribute_value(self, attribute_name: str) -> str: """ Get the value of an AWS credential attribute stored in the specific named profile. :param attribute_name: Name of the AWS credential attribute. :return Value of the AWS credential attribute. """ try: value = self._credentials.get(self._profile_name, attribute_name) except configparser.NoSectionError: # Named profile or key doesn't exist value = None except configparser.NoOptionError: # Named profile doesn't have the specified attribute value = None return value def _set_aws_credential_attribute_value(self, attribute_name: str, attribute_value: str) -> None: """ Set the value of an AWS credential attribute stored in the specific named profile. :param attribute_name: Name of the AWS credential attribute. :param attribute_value: Value of the AWS credential attribute. """ if self._profile_name not in self._credentials: self._credentials[self._profile_name] = {} if attribute_value is None: self._credentials.remove_option(self._profile_name, attribute_name) # Remove the named profile if it doesn't have any AWS credential attribute. if len(self._credentials[self._profile_name]) == 0: self._credentials.remove_section(self._profile_name) else: self._credentials[self._profile_name][attribute_name] = attribute_value