Skip to content

Commit

Permalink
Merge pull request #55 from ericcj/restricted_operations
Browse files Browse the repository at this point in the history
support for restricted operations
  • Loading branch information
ericcj authored Oct 19, 2023
2 parents 18a2613 + fa386df commit 0c2c49e
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 18 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,41 @@ require 'fulfillment-outbound-api-model'
end
```

## Restricted operations

Configure as per above but also create a new client for each restrictedResources you need, e.g.:

```
require 'orders-api-model'
client = AmzSpApi::RestrictedSpApiClient.new({
'restrictedResources' => [
{
'method' => 'GET',
'path' => "/orders/v0/orders",
'dataElements' => ['buyerInfo', 'shippingAddress']
}
]
})
api_orders = AmzSpApi::OrdersApiModel::OrdersV0Api.new(client)
api_orders.get_orders(marketplace_ids, created_after: 1.day.ago.iso8601)
client = AmzSpApi::RestrictedSpApiClient.new({
'restrictedResources' => [
{
'method' => 'GET',
'path' => "/orders/v0/orders/#{my_order_id}",
'dataElements' => ['buyerInfo', 'shippingAddress']
}
]
})
api_orders = AmzSpApi::OrdersApiModel::OrdersV0Api.new(client)
api_orders.get_order(my_order_id)
# or you can use models AmzSpApi::RestrictedSpApiClient.new(AmzSpApi::TokensApiModel::CreateRestrictedDataTokenRequest.new(restricted_resources: [
AmzSpApi::TokensApiModel::RestrictedResource.new(...
```

## Feeds and reports

This gem also offers encrypt/decrypt helper methods for feeds and reports, but actually using that API as per https://developer-docs.amazon.com/sp-api/docs/ requires the following calls, e.g. for feeds but reports is the same pattern:
Expand Down
3 changes: 2 additions & 1 deletion lib/amz_sp_api.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
require 'amz_sp_api_version'
require 'api_error'
require 'sp_api_client'
require 'sp_configuration'
require 'sp_api_client'
require 'restricted_sp_api_client'

module AmzSpApi
class << self
Expand Down
2 changes: 1 addition & 1 deletion lib/amz_sp_api_version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module AmzSpApi
VERSION = '1.0.0'
VERSION = '1.0.1'
end
56 changes: 56 additions & 0 deletions lib/restricted_sp_api_client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
require 'api_error'
require 'api_client'
require 'configuration'
require 'sp_api_client'

require 'tokens-api-model'

module AmzSpApi
class RestrictedSpApiClient < ApiClient

def initialize(create_restricted_data_token_request, config = SpConfiguration.default)
super(config)
raise "pass create_restricted_data_token_request to RestrictedSpApiClient.new" if create_restricted_data_token_request.kind_of?(Configuration)
@wrapped_client = SpApiClient.new(config)
@create_restricted_data_token_request = create_restricted_data_token_request
@cache_key = config.access_token_key + "-RDT-" + Digest::MD5.hexdigest(create_restricted_data_token_request.to_s)
end

alias_method :super_call_api, :call_api
def call_api(http_method, path, opts = {})
unsigned_request = build_request(http_method, path, opts)
aws_headers = auth_headers(http_method, unsigned_request.url, unsigned_request.encoded_body)
signed_opts = opts.merge(:header_params => aws_headers.merge(opts[:header_params] || {}))
super(http_method, path, signed_opts)
end

private

def retrieve_rdt_access_token
return request_rdt_access_token[:access_token] unless config.get_access_token
stored_token = config.get_access_token.call(@cache_key)
if stored_token.nil?
new_token = request_rdt_access_token
config.save_access_token.call(@cache_key, new_token) if config.save_access_token
return new_token[:access_token]
else
return stored_token
end
end

def request_rdt_access_token
api_tokens = AmzSpApi::TokensApiModel::TokensApi.new(@wrapped_client)
response = api_tokens.create_restricted_data_token(@create_restricted_data_token_request)

{access_token: response.restricted_data_token,
expires_in: response.expires_in}
end

def auth_headers(http_method, url, body)
SpApiClient.signed_request_headers(config, http_method, url, body).merge({
'x-amz-access-token' => retrieve_rdt_access_token
})
end

end
end
32 changes: 16 additions & 16 deletions lib/sp_api_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ def call_api(http_method, path, opts = {})
super(http_method, path, signed_opts)
end

def self.signed_request_headers(config, http_method, url, body)
request_config = {
service: 'execute-api',
region: config.aws_region
}
if config.credentials_provider
request_config[:credentials_provider] = config.credentials_provider
else
request_config[:access_key_id] = config.aws_access_key_id
request_config[:secret_access_key] = config.aws_secret_access_key
end
signer = Aws::Sigv4::Signer.new(request_config)
signer.sign_request(http_method: http_method.to_s, url: url, body: body).headers
end

private

def retrieve_lwa_access_token
Expand Down Expand Up @@ -58,23 +73,8 @@ def request_lwa_access_token
data
end

def signed_request_headers(http_method, url, body)
request_config = {
service: 'execute-api',
region: config.aws_region
}
if config.credentials_provider
request_config[:credentials_provider] = config.credentials_provider
else
request_config[:access_key_id] = config.aws_access_key_id
request_config[:secret_access_key] = config.aws_secret_access_key
end
signer = Aws::Sigv4::Signer.new(request_config)
signer.sign_request(http_method: http_method.to_s, url: url, body: body).headers
end

def auth_headers(http_method, url, body)
signed_request_headers(http_method, url, body).merge({
self.class.signed_request_headers(config, http_method, url, body).merge({
'x-amz-access-token' => retrieve_lwa_access_token
})
end
Expand Down

0 comments on commit 0c2c49e

Please sign in to comment.