From e6969819baaec529404ab2926757dd4bf26c2276 Mon Sep 17 00:00:00 2001 From: Michael Manganiello Date: Wed, 15 Nov 2023 00:28:05 -0300 Subject: [PATCH] fix: Remove AWS IAM auth leftovers As a follow-up for #1203, any reference to AWS access/secret key, and role ARN is being removed. --- credentials.yml | 4 --- docs/config_file.rst | 5 --- docs/env_variables.rst | 6 ---- docs/examples/authorisation_example.rst | 40 +----------------------- docs/from_code.rst | 6 ---- sp_api/base/client.py | 8 ----- sp_api/base/credential_provider.py | 9 ------ tests/client/test_auth.py | 14 --------- tests/client/test_base.py | 36 +-------------------- tests/client/test_credential_provider.py | 9 ------ 10 files changed, 2 insertions(+), 135 deletions(-) diff --git a/credentials.yml b/credentials.yml index 99f9969cf..cef38341f 100644 --- a/credentials.yml +++ b/credentials.yml @@ -4,7 +4,3 @@ default: refresh_token: '' lwa_app_id: '' lwa_client_secret: '' - aws_secret_key: '' - aws_access_key: '' - role_arn: '' - diff --git a/docs/config_file.rst b/docs/config_file.rst index 3f41f6b45..82e49f4fa 100644 --- a/docs/config_file.rst +++ b/docs/config_file.rst @@ -29,11 +29,6 @@ If you're only using one account, place it under default. You can pass the accou Orders(refresh_token='...') -.. warning:: - If you have assigned the execute-api (STS) permissions to your AWS **user**, omit `role_arn`. - - If you have assigned the permission to a role, the `role_arn` parameter is required. - .. code-block:: yaml version: '1.0' diff --git a/docs/env_variables.rst b/docs/env_variables.rst index 7b67cd371..3996ba304 100644 --- a/docs/env_variables.rst +++ b/docs/env_variables.rst @@ -23,12 +23,6 @@ LWA_CLIENT_SECRET Your login with amazon client secret Orders(refresh_token='...') -.. warning:: - If you have assigned the execute-api (STS) permissions to your AWS **user**, omit `role_arn`. - - If you have assigned the permissions to a role, the `role_arn` parameter is required. - - To set environment variables under linux/mac, use .. code-block:: bash diff --git a/docs/examples/authorisation_example.rst b/docs/examples/authorisation_example.rst index f3643cbac..cd20e5055 100644 --- a/docs/examples/authorisation_example.rst +++ b/docs/examples/authorisation_example.rst @@ -9,35 +9,11 @@ Internal Seller Access To gain initial access to the Api you will need to follow the authorisation process as documented by Amazon https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/developer-guide/SellingPartnerApiDeveloperGuide.md -This involves three main stages: +This involves two main stages: -- Configuring AWS IAM to have User, Role and Permissions for SPAPI - Adding an App to your Seller Central account. - Configuring Python-SPAPI with the correct credentials. -Configuring AWS IAM: -^^^^^^^^^^^^^^^^^^^^ - - 1. Create an IAM User - 2. Create an IAM Policy - 3. Create an IAM Role - 4. Add an AWS Security Token Service (STS) policy to the IAM User - -.. note:: - This guide assumes you have used the ROLE for attaching the permissions policy to as per the SPAPI quick start guide from Amazon - -Make sure you take note of the following items before progressing to the App setup in Seller Central: - -- User ARN -- Role ARN -- AWS Access Key -- AWS Secret Key - -There is the option to download the `new user credentials` - this will give you a CSV file of the `Access Key` and `Secret Key` - -.. warning:: - You will only get one chance to view the Secret key - Configuring the App in Seller Central: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -48,9 +24,6 @@ Overview: - Seller Central -> Partner Network -> Develop Apps. - Add a new client app -- Add in the IAM *ROLE* that you attached the execute permissions to. - - Select the necessary permissions for your app. - - The OAUTH details are not required (for self certification apps) - Click the `LWA Credentials View` link to see your `Login With Amazon` credentials. - Click *Authorise* and copy the `REFRESH_TOKEN` that is provided to you. *This is your only chance to see this token!, you will nee to regenerate it if you lose it.* @@ -65,9 +38,6 @@ The following is an overview of which credentials go with which key. - `refresh_token` -> This is from Seller Central, Authorisation of the app window - `lws_app_id` -> This is from Seller central under LWA client credentials -> Client Identifier and will look like `amzn1.application-oa2-client.7b18cd......` - `lwa_client_secret` -> This is from Seller central under LWA client credentials -> Client Secret and will look like `b5f7f8...` -- `aws_access_key` -> From AWS IAM Setup (Downloaded in the `new_user_credentials.csv`) and is called `Access key ID` -- `aws_secret_key` -> From AWS IAM Setup (Downloaded in the `new_user_credentials.csv`) and is called `Secret access key` -- `role_arn` is from the AWS IAM Setup and is the ARN of the ROLE and will look like `arn:aws:iam::1234567890:role/SellingPartnerAPIRole` .. code-block:: python @@ -75,19 +45,11 @@ The following is an overview of which credentials go with which key. refresh_token='your_refresh_token', # From Seller central under Authorise -> Refresh Token lwa_app_id='your_lwa_app_id', # From Seller Central, named CLIENT IDENTIFIER on website. lwa_client_secret='your_lwa_client_secret', # From Seller Central, named CLIENT SECRET on website. - aws_access_key='your_aws_access_key', # From AWS IAM Setup - aws_secret_key='your_aws_secret_key', # From AWS IAM Setup - role_arn='your_role_arn' #arn:aws:iam::1234567890:role/SellingPartnerAPIRole ) -.. note:: - In this example we used the IAM ROLE to configure the app in Seller Central, so we must also use the ROLE Arn to configure the Python SPAPI. - Should you have chosen an alternate setup, you may need to drop the `role_arn` from your configuration. - - **Example Screenshots** diff --git a/docs/from_code.rst b/docs/from_code.rst index 77eecc0f3..75d01f654 100644 --- a/docs/from_code.rst +++ b/docs/from_code.rst @@ -18,15 +18,9 @@ If you pass a value in credentials, other credentials from env variables or from Orders(refresh_token='...') -.. warning:: - If you have assigned the execute-api (STS) permissions to your AWS **user**, omit `role_arn`. - - If you have assigned the permissions to a role, the `role_arn` parameter is required. - .. code-block:: python - credentials=dict( refresh_token='', lwa_app_id='', diff --git a/sp_api/base/client.py b/sp_api/base/client.py index 04cfb7779..a2c59df37 100644 --- a/sp_api/base/client.py +++ b/sp_api/base/client.py @@ -5,7 +5,6 @@ import os from json import JSONDecodeError -from cachetools import TTLCache from requests import request from sp_api.auth import AccessTokenClient, AccessTokenResponse @@ -17,8 +16,6 @@ log = logging.getLogger(__name__) -role_cache = TTLCache(maxsize=int(os.environ.get('SP_API_AUTH_CACHE_SIZE', 10)), ttl=3200) - class Client(BaseClient): grantless_scope: str = '' @@ -58,11 +55,6 @@ def __init__( self.version = version self.verify = verify - def _get_cache_key(self, token_flavor=''): - return 'role_' + hashlib.md5( - (token_flavor + self._auth.cred.refresh_token).encode('utf-8') - ).hexdigest() - @property def headers(self): return { diff --git a/sp_api/base/credential_provider.py b/sp_api/base/credential_provider.py index 2495cc117..e1c1826d6 100644 --- a/sp_api/base/credential_provider.py +++ b/sp_api/base/credential_provider.py @@ -88,9 +88,6 @@ def load_credentials(self): refresh_token=secret.get('SP_API_REFRESH_TOKEN'), lwa_app_id=secret.get('LWA_APP_ID'), lwa_client_secret=secret.get('LWA_CLIENT_SECRET'), - aws_secret_key=secret.get('SP_API_SECRET_KEY'), - aws_access_key=secret.get('SP_API_ACCESS_KEY'), - role_arn=secret.get('SP_API_ROLE_ARN') ) @abc.abstractmethod @@ -134,9 +131,6 @@ def load_credentials(self): refresh_token=self._get_env('SP_API_REFRESH_TOKEN'), lwa_app_id=self._get_env('LWA_APP_ID'), lwa_client_secret=self._get_env('LWA_CLIENT_SECRET'), - aws_secret_key=self._get_env('SP_API_SECRET_KEY'), - aws_access_key=self._get_env('SP_API_ACCESS_KEY'), - role_arn=self._get_env('SP_API_ROLE_ARN') ) self.credentials = account_data @@ -181,6 +175,3 @@ def __init__(self, **kwargs): self.refresh_token = kwargs.get('refresh_token') self.lwa_app_id = kwargs.get('lwa_app_id') self.lwa_client_secret = kwargs.get('lwa_client_secret') - self.aws_access_key = kwargs.get('aws_access_key') - self.aws_secret_key = kwargs.get('aws_secret_key') - self.role_arn = kwargs.get('role_arn') diff --git a/tests/client/test_auth.py b/tests/client/test_auth.py index 80018a5a3..a3f8b14ce 100644 --- a/tests/client/test_auth.py +++ b/tests/client/test_auth.py @@ -7,9 +7,6 @@ refresh_token = '' lwa_app_id = '' lwa_client_secret = '' -aws_secret_key = '' -aws_access_key = '' -role_arn = '' def test_auth_exception(): @@ -24,8 +21,6 @@ def test_credentials(): assert x.credentials is not None assert x.credentials.lwa_app_id is not None assert x.credentials.lwa_client_secret is not None - assert x.credentials.aws_secret_key is not None - assert x.credentials.aws_access_key is not None def test_credentials_with_custom_provider(): @@ -35,9 +30,6 @@ def load_credentials(self): "refresh_token": refresh_token, "lwa_app_id": lwa_app_id, "lwa_client_secret": lwa_client_secret, - "aws_secret_key": aws_secret_key, - "aws_access_key": aws_access_key, - "role_arn": role_arn, } cp = CredentialProvider(credential_providers=(CustomCredentialProvider,)) @@ -45,9 +37,6 @@ def load_credentials(self): assert cp.credentials.refresh_token == "" assert cp.credentials.lwa_app_id == "" assert cp.credentials.lwa_client_secret == "" - assert cp.credentials.aws_secret_key == "" - assert cp.credentials.aws_access_key == "" - assert cp.credentials.role_arn == "" def test_auth_client(): @@ -55,9 +44,6 @@ def test_auth_client(): refresh_token=refresh_token, lwa_app_id=lwa_app_id, lwa_client_secret=lwa_client_secret, - aws_secret_key=aws_secret_key, - aws_access_key=aws_access_key, - role_arn=role_arn, )).credentials) x = client._auth_code_request_body('foo') assert x.get('grant_type') == 'authorization_code' diff --git a/tests/client/test_base.py b/tests/client/test_base.py index ae4009c89..a378c1747 100644 --- a/tests/client/test_base.py +++ b/tests/client/test_base.py @@ -11,9 +11,6 @@ refresh_token = '' lwa_app_id = '' lwa_client_secret = '' -aws_secret_key = '' -aws_access_key = '' -role_arn = '' class Res: @@ -56,37 +53,18 @@ def test_from_code_credential_provider(): refresh_token=refresh_token, lwa_app_id=lwa_app_id, lwa_client_secret=lwa_client_secret, - aws_secret_key=aws_secret_key, - aws_access_key=aws_access_key, - role_arn=role_arn, )) assert p.credentials is not None assert isinstance(p.credentials, dict) -def test_from_code_credential_provider_no_role(): +def test_from_code_credential_provider_no_refresh_token(): p = FromCodeCredentialProvider(credentials=dict( - refresh_token=refresh_token, lwa_app_id=lwa_app_id, lwa_client_secret=lwa_client_secret, - aws_secret_key=aws_secret_key, - aws_access_key=aws_access_key, )) assert p.credentials is not None assert isinstance(p.credentials, dict) - assert p.credentials.get('role_arn') is None - - -def test_from_code_credential_provider_no_role_no_refresh_token(): - p = FromCodeCredentialProvider(credentials=dict( - lwa_app_id=lwa_app_id, - lwa_client_secret=lwa_client_secret, - aws_secret_key=aws_secret_key, - aws_access_key=aws_access_key, - )) - assert p.credentials is not None - assert isinstance(p.credentials, dict) - assert p.credentials.get('role_arn') is None assert p.credentials.get('refresh_token') is None @@ -95,9 +73,6 @@ def test_env_vars_provider(): os.environ['SP_API_REFRESH_TOKEN'] = 'foo' os.environ['LWA_APP_ID'] = 'foo' os.environ['LWA_CLIENT_SECRET'] = 'foo' - os.environ['SP_API_ACCESS_KEY'] = 'foo' - os.environ['SP_API_SECRET_KEY'] = 'foo' - os.environ['SP_API_ROLE_ARN'] = 'foo' p = FromEnvironmentVariablesCredentialProvider()() assert 'refresh_token' in p @@ -105,9 +80,6 @@ def test_env_vars_provider(): os.environ.pop('SP_API_REFRESH_TOKEN') os.environ.pop('LWA_APP_ID') os.environ.pop('LWA_CLIENT_SECRET') - os.environ.pop('SP_API_ACCESS_KEY') - os.environ.pop('SP_API_SECRET_KEY') - os.environ.pop('SP_API_ROLE_ARN') @pytest.mark.order(-1) @@ -140,15 +112,12 @@ def test_client(): assert client.credentials is not None assert client.endpoint == Marketplaces.UK.endpoint assert client.region == Marketplaces.UK.region - assert client.boto3_client is not None assert client.restricted_data_token is None assert isinstance(client._auth, AccessTokenClient) assert isinstance(client._get_cache_key(), str) assert isinstance(client._get_cache_key('test'), str) - assert client.set_role() is not None - assert client.headers['host'] == client.endpoint[8:] assert len(client.headers.keys()) == 5 @@ -158,9 +127,6 @@ def test_client(): except MissingScopeException as e: assert isinstance(e, MissingScopeException) - assert client.role is not None - assert client._sign_request is not None - try: client._request('', data={}) except SellingApiForbiddenException as e: diff --git a/tests/client/test_credential_provider.py b/tests/client/test_credential_provider.py index c47380e0c..c40f73923 100644 --- a/tests/client/test_credential_provider.py +++ b/tests/client/test_credential_provider.py @@ -7,9 +7,6 @@ REFRESH_TOKEN = '' LWA_APP_ID = '' LWA_CLIENT_SECRET = '' -AWS_SECRET_KEY = '' -AWS_ACCESS_KEY = '' -ROLE_ARN = '' def test_from_cached_secrets_cp_without_secret_id_set(): @@ -34,9 +31,6 @@ def test_from_cached_secrets_cp_with_cache_available(): "SP_API_REFRESH_TOKEN": REFRESH_TOKEN, "LWA_APP_ID": LWA_APP_ID, "LWA_CLIENT_SECRET": LWA_CLIENT_SECRET, - "SP_API_ACCESS_KEY": AWS_ACCESS_KEY, - "SP_API_SECRET_KEY": AWS_SECRET_KEY, - "SP_API_ROLE_ARN": ROLE_ARN, } with mock.patch.dict(os.environ, {"SP_API_AWS_SECRET_ID": "test"}), \ @@ -48,7 +42,4 @@ def test_from_cached_secrets_cp_with_cache_available(): "refresh_token": REFRESH_TOKEN, "lwa_app_id": LWA_APP_ID, "lwa_client_secret": LWA_CLIENT_SECRET, - "aws_access_key": AWS_ACCESS_KEY, - "aws_secret_key": AWS_SECRET_KEY, - "role_arn": ROLE_ARN, }