Skip to content

Commit

Permalink
v0.2.1 with feed encryption helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
ericcj committed Apr 20, 2021
1 parent fda9e12 commit 31d6a1e
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,27 @@ require 'fulfillment-outbound-api-model'

This is a handy way to see all the API model class names and corresponding files you need to require for them, e.g. require 'finances-api-model' to use https://www.rubydoc.info/gems/amz_sp_api/AmzSpApi/FinancesApiModel/DefaultApi

## Feeds

This gem also offers encrypt/decrypt helper methods for feeds, but actually using that API as per https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/use-case-guides/feeds-api-use-case-guide requires the following calls:

```ruby
feeds = AmzSpApi::FeedsApiModel::FeedsApi.new(AmzSpApi::SpApiClient.new)
response = feeds.create_feed_document({"contentType" => content_type})
feed_document_id = response&.payload&.dig(:feedDocumentId)
url = response.payload[:url]
encrypted = AmzSpApi.encrypt_feed(feed_content, response.payload)
# PUT to url with lowercase "content-type" header, it's already pre-signed
response = feeds.create_feed({"feedType" => feed_type, "marketplaceIds" => marketplace_ids, "inputFeedDocumentId" => feed_document_id})
feed_id = response&.payload&.dig(:feedId)
response = feeds.get_feed(feed_id)
result_feed_document_id = response&.payload&.dig(:resultFeedDocumentId) # present once it is successful
response = feeds.get_feed_document(result_feed_document_id)
url = response&.payload&.dig(:url)
# GET response&.payload&.dig(:url) into ciphertext, again it's pre-signed so no authorization needed
AmzSpApi.decrypt_and_inflate_feed(ciphertext, response.payload)
```

## Thanks

to https://github.com/patterninc/muffin_man as the basis for [sp_api_client.rb](lib/sp_api_client.rb)
33 changes: 33 additions & 0 deletions lib/amz_sp_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,38 @@ def configure
SpConfiguration.default
end
end

def encrypt_feed(feed_content, feed_document_response_payload)
cipher = feed_cipher(feed_document_response_payload, encrypt: true)
cipher.update(feed_content) + cipher.final
end

def decrypt_and_inflate_feed(ciphertext, feed_document_response_payload)
cipher = feed_cipher(feed_document_response_payload, encrypt: false)

compression = feed_document_response_payload[:compressionAlgorithm]
raise "unknown compressionAlgorithm #{compression}" if compression && compression != "GZIP"

result = cipher.update(ciphertext) + cipher.final
result = Zlib::Inflate.inflate(result) if compression
result
end

# from https://github.com/amzn/selling-partner-api-models/blob/main/clients/sellingpartner-api-documents-helper-java/src/main/java/com/amazon/spapi/documents/impl/AESCryptoStreamFactory.java
def feed_cipher(response, encrypt:)
key = Base64.decode64(response.dig(:encryptionDetails, :key))

cipher = case response.dig(:encryptionDetails, :standard)
when "AES"
OpenSSL::Cipher.new("AES-#{key.size * 8}-CBC")
else
raise "unknown encryption standard #{response.inspect}"
end

encrypt ? cipher.encrypt : cipher.decrypt
cipher.key = key
cipher.iv = Base64.decode64(response.dig(:encryptionDetails, :initializationVector))
cipher
end
end
end
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 = '0.2.0'
VERSION = '0.2.1'
end

0 comments on commit 31d6a1e

Please sign in to comment.