amazon-ecs 0.5.4 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ 0.5.5 2009-07-18
2
+ ----------------
3
+ * Sign request
4
+
1
5
  0.5.4 2008-01-02
2
6
  ----------------
3
7
  * Add Response#error_code
data/README CHANGED
@@ -1,8 +1,8 @@
1
1
  == amazon-ecs
2
2
 
3
- Generic Amazon E-commerce REST API using Hpricot with configurable
3
+ Generic Amazon E-commerce REST or Product Advertising API using Hpricot with configurable
4
4
  default options and method call options. Uses Response and
5
- Element wrapper classes for easy access to REST XML output. It supports ECS 4.0.
5
+ Element wrapper classes for easy access to REST XML output.
6
6
 
7
7
  It is generic, so you can easily extend <tt>Amazon::Ecs</tt> to support
8
8
  other not implemented REST operations; and it is also generic because it just wraps around
@@ -12,7 +12,7 @@ If in the future, there is a change in REST XML output structure,
12
12
  no changes will be required on <tt>amazon-ecs</tt> library,
13
13
  instead you just need to change the element path.
14
14
 
15
- Version: 0.5.4
15
+ Version: 0.5.5
16
16
 
17
17
  == INSTALLATION
18
18
 
@@ -23,7 +23,16 @@ Version: 0.5.4
23
23
  require 'amazon/ecs'
24
24
 
25
25
  # set the default options; options will be camelized and converted to REST request parameters.
26
- Amazon::Ecs.options = {:aWS_access_key_id => [your developer token]}
26
+ Amazon::Ecs.options = {:aWS_access_key_id => [your access key]}
27
+
28
+ # to generate signed requests include your secret key:
29
+ Amazon::Ecs.options = {:aWS_access_key_id => [your developer token], :aWS_secret_key => [your secret access key]}
30
+
31
+ # alternatively,
32
+ Amazon::Ecs.configure do |options|
33
+ options[:aWS_access_key_id] = [your access key]
34
+ options[:aWS_secret_key] = [you secret key]
35
+ end
27
36
 
28
37
  # options provided on method call will merge with the default options
29
38
  res = Amazon::Ecs.item_search('ruby', {:response_group => 'Medium', :sort => 'salesrank'})
@@ -87,11 +96,16 @@ http://www.awszone.com/scratchpads/aws/ecs.us/index.aws
87
96
 
88
97
  == LINKS
89
98
 
99
+ * http://github.com/jugend/amazon-ecs
90
100
  * http://amazon-ecs.rubyforge.org
91
101
  * http://www.pluitsolutions.com/amazon-ecs
92
102
 
103
+ == CREDITS
104
+
105
+ Thanks to Dan Milne (http://da.nmilne.com/) for the signed request patch.
106
+
93
107
  == LICENSE
94
108
 
95
109
  (The MIT License)
96
110
 
97
- Copyright (c) 2006 Herryanto Siatono, Pluit Solutions
111
+ Copyright (c) 2009 Herryanto Siatono, Pluit Solutions
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006 Herryanto Siatono, Pluit Solutions
2
+ # Copyright (c) 2009 Herryanto Siatono, Pluit Solutions
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -24,20 +24,26 @@
24
24
  require 'net/http'
25
25
  require 'hpricot'
26
26
  require 'cgi'
27
+ require 'hmac-sha2'
28
+ require 'base64'
27
29
 
28
30
  module Amazon
29
31
  class RequestError < StandardError; end
30
32
 
31
33
  class Ecs
32
- SERVICE_URLS = {:us => 'http://webservices.amazon.com/onca/xml?Service=AWSECommerceService',
33
- :uk => 'http://webservices.amazon.co.uk/onca/xml?Service=AWSECommerceService',
34
- :ca => 'http://webservices.amazon.ca/onca/xml?Service=AWSECommerceService',
35
- :de => 'http://webservices.amazon.de/onca/xml?Service=AWSECommerceService',
36
- :jp => 'http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService',
37
- :fr => 'http://webservices.amazon.fr/onca/xml?Service=AWSECommerceService'
34
+ SERVICE_URLS = {:us => 'http://webservices.amazon.com/onca/xml?',
35
+ :uk => 'http://webservices.amazon.co.uk/onca/xml?',
36
+ :ca => 'http://webservices.amazon.ca/onca/xml?',
37
+ :de => 'http://webservices.amazon.de/onca/xml?',
38
+ :jp => 'http://webservices.amazon.co.jp/onca/xml?',
39
+ :fr => 'http://webservices.amazon.fr/onca/xml?'
40
+ }
41
+
42
+ @@options = {
43
+ :version => "2009-01-06",
44
+ :service => "AWSECommerceService"
38
45
  }
39
46
 
40
- @@options = {}
41
47
  @@debug = false
42
48
 
43
49
  # Default search options
@@ -92,6 +98,10 @@ module Amazon
92
98
  # Generic send request to ECS REST service. You have to specify the :operation parameter.
93
99
  def self.send_request(opts)
94
100
  opts = self.options.merge(opts) if self.options
101
+
102
+ # Include other required options
103
+ opts[:timestamp] = Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
104
+
95
105
  request_url = prepare_url(opts)
96
106
  log "Request URL: #{request_url}"
97
107
 
@@ -190,19 +200,39 @@ module Amazon
190
200
  country = (country.nil?) ? 'us' : country
191
201
  request_url = SERVICE_URLS[country.to_sym]
192
202
  raise Amazon::RequestError, "Invalid country '#{country}'" unless request_url
203
+
204
+ secret_key = opts.delete(:aWS_secret_key)
205
+ request_host = URI.parse(request_url).host
193
206
 
194
207
  qs = ''
195
- opts.each {|k,v|
196
- next unless v
197
- v = v.join(',') if v.is_a? Array
198
- qs << "&#{camelize(k.to_s)}=#{URI.encode(v.to_s)}"
208
+ opts.collect {|a,b| [camelize(a.to_s), b.to_s] }.sort {|c,d| c[0].to_s <=> d[0].to_s}.each {|e|
209
+ log "Adding #{e[0]}=#{e[1]}"
210
+ next unless e[1]
211
+ e[1] = e[1].join(',') if e[1].is_a? Array
212
+ v=URI.encode(e[1].to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
213
+ qs << "&" unless qs.length == 0
214
+ qs << "#{e[0]}=#{v}"
199
215
  }
200
- "#{request_url}#{qs}"
216
+
217
+ signature = ''
218
+ unless secret_key.nil?
219
+ request_to_sign="GET\n#{request_host}\n/onca/xml\n#{qs}"
220
+ signature = "&Signature=#{sign_request(request_to_sign, secret_key)}"
221
+ end
222
+
223
+ "#{request_url}#{qs}#{signature}"
201
224
  end
202
225
 
203
226
  def self.camelize(s)
204
227
  s.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
205
228
  end
229
+
230
+ def self.sign_request(url, key)
231
+ return nil if key.nil?
232
+ signature = URI.escape( Base64.encode64( HMAC::SHA256.digest(key, url) ).strip, Regexp.new("[+=]") )
233
+ return signature
234
+ end
235
+
206
236
  end
207
237
 
208
238
  # Internal wrapper class to provide convenient method to access Hpricot element value.
@@ -2,21 +2,29 @@ require File.dirname(__FILE__) + '/../test_helper'
2
2
 
3
3
  class Amazon::EcsTest < Test::Unit::TestCase
4
4
 
5
- AWS_ACCESS_KEY_ID = '1ZD53WRGR730ZCVWBSG2'
5
+ AWS_ACCESS_KEY_ID = ''
6
+ AWS_SECRET_KEY = ''
7
+
6
8
  raise "Please specify set your AWS_ACCESS_KEY_ID" if AWS_ACCESS_KEY_ID.empty?
9
+ raise "Please specify set your AWS_SECRET_KEY" if AWS_SECRET_KEY.empty?
7
10
 
8
11
  Amazon::Ecs.configure do |options|
9
12
  options[:response_group] = 'Large'
10
13
  options[:aWS_access_key_id] = AWS_ACCESS_KEY_ID
14
+ options[:aWS_secret_key] = AWS_SECRET_KEY
11
15
  end
12
16
 
13
17
  ## Test item_search
14
18
 
15
19
  def test_item_search
16
20
  resp = Amazon::Ecs.item_search('ruby')
21
+
17
22
  assert(resp.is_valid_request?)
18
23
  assert(resp.total_results >= 3600)
19
24
  assert(resp.total_pages >= 360)
25
+
26
+ signature_elements = (resp.doc/"arguments/argument").select {|ele| ele.attributes['name'] == 'Signature' }.length
27
+ assert(signature_elements == 1)
20
28
  end
21
29
 
22
30
  def test_item_search_with_paging
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amazon-ecs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.5.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Herryanto Siatono
@@ -9,7 +9,7 @@ autorequire: name
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-24 00:00:00 +08:00
12
+ date: 2009-07-18 00:00:00 +08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,6 +22,16 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: "0.4"
24
24
  version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: ruby-hmac
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.2
34
+ version:
25
35
  description:
26
36
  email: herryanto@pluitsolutions.com
27
37
  executables: []
@@ -32,12 +42,13 @@ extra_rdoc_files:
32
42
  - README
33
43
  - CHANGELOG
34
44
  files:
35
- - lib/amazon
36
45
  - lib/amazon/ecs.rb
37
46
  - README
38
47
  - CHANGELOG
39
48
  has_rdoc: true
40
49
  homepage: http://amazon-ecs.rubyforge.net/
50
+ licenses: []
51
+
41
52
  post_install_message:
42
53
  rdoc_options: []
43
54
 
@@ -58,9 +69,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
69
  requirements: []
59
70
 
60
71
  rubyforge_project:
61
- rubygems_version: 1.3.0
72
+ rubygems_version: 1.3.4
62
73
  signing_key:
63
- specification_version: 2
74
+ specification_version: 3
64
75
  summary: Generic Amazon E-commerce Service (ECS) REST API. Supports ECS 4.0.
65
76
  test_files:
66
77
  - test/amazon/ecs_test.rb