amazon-ecs 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
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