ace-client 0.0.17 → 0.0.18

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.17
1
+ 0.0.18
@@ -1,7 +1,11 @@
1
1
  require 'ace-client/base'
2
2
  require 'ace-client/query2'
3
+ require 'ace-client/base3'
3
4
  require 'ace-client/query3'
5
+ require 'ace-client/xml3'
6
+ require 'ace-client/base4'
4
7
  require 'ace-client/query4'
8
+ require 'ace-client/json4'
5
9
 
6
10
  module AceClient
7
11
  VERSION = File.read(File.dirname(__FILE__) + '/../VERSION').chomp
@@ -0,0 +1,40 @@
1
+ require 'openssl'
2
+ require 'cgi'
3
+ require 'nokogiri'
4
+ require 'time'
5
+
6
+ module AceClient
7
+ class Base3 < Base
8
+ attr_accessor :signature_method # TODO: HMAC-SHA256 or HMAC-SHA1
9
+ attr_accessor :sampler
10
+
11
+ format :xml
12
+
13
+ def initialize(options={})
14
+ super(options)
15
+ @signature_method = options[:signature_method] || 'HmacSHA256'
16
+ @authorization_key = options[:authorization_key] || 'authorization'
17
+ @date_key = options[:date_key] || 'x-date'
18
+ @nonce_key = options[:nonce_key] || 'x-amz-nonce'
19
+ @authorization_prefix = options[:authorization_prefix] || 'AWS3-HTTPS'
20
+ @nonce = options[:nonce]
21
+
22
+ @sampler = options[:sampler]
23
+ @before_signature = options[:before_signature]
24
+ @before_request = options[:before_request]
25
+ end
26
+
27
+ def create_signature
28
+ digest = OpenSSL::Digest::Digest.new(@signature_method.downcase.gsub(/hmac/, ''))
29
+ Base64.encode64(OpenSSL::HMAC.digest(digest, secret_access_key, string_to_sign)).strip
30
+ end
31
+
32
+ def string_to_sign
33
+ @nonce ? date + @nonce : date
34
+ end
35
+
36
+ def date
37
+ @date ||= Time.now.utc.rfc822.gsub(/[\-\+]\d{4}$/, 'GMT')
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,183 @@
1
+ module AceClient
2
+ class Base4 < Base
3
+ attr_accessor :headers
4
+ attr_accessor :region
5
+ attr_accessor :body
6
+ attr_accessor :service
7
+ attr_accessor :datetime
8
+
9
+ def initialize(options)
10
+ super(options)
11
+ @service = options[:service]
12
+ @region = options[:region]
13
+ end
14
+
15
+ def action(action, params={})
16
+ params.update('Action' => action)
17
+ execute(params)
18
+ end
19
+
20
+ def execute(params)
21
+ @datetime = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
22
+ if http_method == :get
23
+ execute_get(params)
24
+ else http_method == :post
25
+ execute_post(params)
26
+ end
27
+ end
28
+
29
+ def execute_get(params)
30
+ @headers = {}
31
+ @headers['host'] = @endpoint
32
+
33
+ @params = params
34
+ @params['Version'] = @version if @version
35
+ @params.update(
36
+ 'X-Amz-Algorithm' => 'AWS4-HMAC-SHA256',
37
+ 'X-Amz-Credential' => access_key_id + '/' + credential_string(datetime),
38
+ 'X-Amz-Date' => datetime,
39
+ 'X-Amz-SignedHeaders' => signed_headers
40
+ )
41
+ options = self.class.default_options.dup
42
+ options[:query] = @params
43
+ request = HTTParty::Request.new(Net::HTTP::Get, endpoint_url + @path, options)
44
+ @query = request.send(:normalize_query, options[:query])
45
+
46
+ @params.update('X-Amz-Signature' => signature(datetime))
47
+
48
+ @body = ''
49
+
50
+ request = HTTParty::Request.new(Net::HTTP::Get, endpoint_url + @path, options)
51
+ request.perform
52
+ end
53
+
54
+ def execute_post(params)
55
+ @params = params
56
+ options = {}
57
+ options = self.class.default_options.dup
58
+ options[:body] = @params
59
+ request = HTTParty::Request.new(Net::HTTP::Post, endpoint_url + @path, options)
60
+ @body = request.send(:normalize_query, options[:body])
61
+
62
+ @headers = {}
63
+ add_authorization!
64
+ options[:headers] = headers
65
+
66
+ request = HTTParty::Request.new(Net::HTTP::Post, endpoint_url + @path, options)
67
+ request.perform
68
+ end
69
+
70
+ def querystring
71
+ if http_method == :post
72
+ ''
73
+ elsif http_method == :get
74
+ @params.sort.collect { |param|
75
+ "#{CGI::escape(param[0])}=#{CGI::escape(param[1])}"
76
+ }.join("&").gsub('+', '%20').gsub('%7E', '~')
77
+ end
78
+ end
79
+
80
+ def add_authorization!
81
+ headers['content-type'] ||= 'application/x-www-form-urlencoded'
82
+ headers['host'] = endpoint
83
+ headers['x-amz-date'] = datetime
84
+ #headers['x-amz-security-token'] = credentials.session_token if credentials.session_token
85
+ headers['x-amz-content-sha256'] ||= hexdigest(body || '')
86
+ headers['authorization'] = authorization(datetime)
87
+ end
88
+
89
+ protected
90
+
91
+ def authorization datetime
92
+ parts = []
93
+ parts << "AWS4-HMAC-SHA256 Credential=#{access_key_id}/#{credential_string(datetime)}"
94
+ parts << "SignedHeaders=#{signed_headers}"
95
+ parts << "Signature=#{signature(datetime)}"
96
+ parts.join(', ')
97
+ end
98
+
99
+ def signature datetime
100
+ k_secret = secret_access_key
101
+ k_date = hmac("AWS4" + k_secret, datetime[0,8])
102
+ k_region = hmac(k_date, region)
103
+ k_service = hmac(k_region, service)
104
+ k_credentials = hmac(k_service, 'aws4_request')
105
+ hexhmac(k_credentials, string_to_sign(datetime))
106
+ end
107
+
108
+ def string_to_sign datetime
109
+ parts = []
110
+ parts << 'AWS4-HMAC-SHA256'
111
+ parts << datetime
112
+ parts << credential_string(datetime)
113
+ parts << hexdigest(canonical_request)
114
+ parts.join("\n")
115
+ end
116
+
117
+ def credential_string datetime
118
+ parts = []
119
+ parts << datetime[0,8]
120
+ parts << region
121
+ parts << service
122
+ parts << 'aws4_request'
123
+ parts.join("/")
124
+ end
125
+
126
+ def canonical_request
127
+ parts = []
128
+ parts << http_method.to_s.upcase
129
+ parts << @path
130
+ parts << querystring
131
+ parts << canonical_headers + "\n"
132
+ parts << signed_headers
133
+ if http_method == :post
134
+ parts << headers['x-amz-content-sha256']
135
+ else
136
+ parts << hexdigest('')
137
+ end
138
+ parts.join("\n")
139
+ end
140
+
141
+ def signed_headers
142
+ to_sign = headers.keys.map{|k| k.to_s.downcase }
143
+ to_sign.delete('authorization')
144
+ to_sign.sort.join(";")
145
+ end
146
+
147
+ def canonical_headers
148
+ headers = []
149
+ self.headers.each_pair do |k,v|
150
+ headers << [k,v] unless k == 'authorization'
151
+ end
152
+ headers = headers.sort_by(&:first)
153
+ headers.map{|k,v| "#{k}:#{canonical_header_values(v)}" }.join("\n")
154
+ end
155
+
156
+ def canonical_header_values values
157
+ values = [values] unless values.is_a?(Array)
158
+ values.map(&:to_s).join(',').gsub(/\s+/, ' ').strip
159
+ end
160
+
161
+ def hexdigest value
162
+ digest = Digest::SHA256.new
163
+ if value.respond_to?(:read)
164
+ chunk = nil
165
+ chunk_size = 1024 * 1024 # 1 megabyte
166
+ digest.update(chunk) while chunk = value.read(chunk_size)
167
+ value.rewind
168
+ else
169
+ digest.update(value)
170
+ end
171
+ digest.hexdigest
172
+ end
173
+
174
+ def hmac key, value
175
+ OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), key, value)
176
+ end
177
+
178
+ def hexhmac key, value
179
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('sha256'), key, value)
180
+ end
181
+ end
182
+ end
183
+
@@ -0,0 +1,28 @@
1
+ module AceClient
2
+ class Json4 < Base4
3
+ format :json
4
+
5
+ def dryrun(action, params={})
6
+ create_request(action, params)
7
+ end
8
+
9
+ def action(action, params={})
10
+ create_request(action, params).perform
11
+ end
12
+
13
+ def create_request(action, params={})
14
+ @datetime = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
15
+ @params = params
16
+ options = self.class.default_options.dup
17
+ @body = options[:body] = @params.to_json
18
+
19
+ @headers = {}
20
+ headers['x-amz-target'] = "Hoge_20141213.#{action}"
21
+ add_authorization!
22
+ options[:headers] = headers
23
+
24
+ HTTParty::Request.new(Net::HTTP::Post, endpoint_url + @path, options)
25
+ end
26
+ end
27
+ end
28
+
@@ -4,27 +4,11 @@ require 'nokogiri'
4
4
  require 'time'
5
5
 
6
6
  module AceClient
7
- class Query3 < Base
7
+ class Query3 < Base3
8
8
  attr_accessor :http_method
9
- attr_accessor :signature_method # TODO: HMAC-SHA256 or HMAC-SHA1
10
- attr_accessor :sampler
11
9
 
12
10
  format :xml
13
11
 
14
- def initialize(options={})
15
- super(options)
16
- @signature_method = options[:signature_method] || 'HmacSHA256'
17
- @authorization_key = options[:authorization_key] || 'authorization'
18
- @date_key = options[:date_key] || 'x-date'
19
- @nonce_key = options[:nonce_key] || 'x-amz-nonce'
20
- @authorization_prefix = options[:authorization_prefix] || 'AWS3-HTTPS'
21
- @nonce = options[:nonce]
22
-
23
- @sampler = options[:sampler]
24
- @before_signature = options[:before_signature]
25
- @before_request = options[:before_request]
26
- end
27
-
28
12
  def action(action, params={})
29
13
  params.update('Action' => action)
30
14
  execute(params)
@@ -68,18 +52,5 @@ module AceClient
68
52
  record_response { request.perform }
69
53
  end
70
54
  end
71
-
72
- def create_signature
73
- digest = OpenSSL::Digest::Digest.new(@signature_method.downcase.gsub(/hmac/, ''))
74
- Base64.encode64(OpenSSL::HMAC.digest(digest, secret_access_key, string_to_sign)).strip
75
- end
76
-
77
- def string_to_sign
78
- @nonce ? date + @nonce : date
79
- end
80
-
81
- def date
82
- @date ||= Time.now.utc.rfc822.gsub(/[\-\+]\d{4}$/, 'GMT')
83
- end
84
55
  end
85
56
  end
@@ -1,20 +1,9 @@
1
1
  module AceClient
2
- class Query4 < Base
3
- attr_accessor :headers
4
- attr_accessor :region
5
- attr_accessor :body
6
- attr_accessor :service
7
- attr_accessor :datetime
2
+ class Query4 < Base4
8
3
  attr_accessor :query
9
4
 
10
5
  format :xml
11
6
 
12
- def initialize(options)
13
- super(options)
14
- @service = options[:service]
15
- @region = options[:region]
16
- end
17
-
18
7
  def action(action, params={})
19
8
  params.update('Action' => action)
20
9
  execute(params)
@@ -69,118 +58,6 @@ module AceClient
69
58
  request = HTTParty::Request.new(Net::HTTP::Post, endpoint_url + @path, options)
70
59
  request.perform
71
60
  end
72
-
73
- def querystring
74
- if http_method == :post
75
- ''
76
- elsif http_method == :get
77
- @params.sort.collect { |param|
78
- "#{CGI::escape(param[0])}=#{CGI::escape(param[1])}"
79
- }.join("&").gsub('+', '%20').gsub('%7E', '~')
80
- end
81
- end
82
-
83
- def add_authorization!
84
- headers['content-type'] ||= 'application/x-www-form-urlencoded'
85
- headers['host'] = endpoint
86
- headers['x-amz-date'] = datetime
87
- #headers['x-amz-security-token'] = credentials.session_token if credentials.session_token
88
- headers['x-amz-content-sha256'] ||= hexdigest(body || '')
89
- headers['authorization'] = authorization(datetime)
90
- end
91
-
92
- protected
93
-
94
- def authorization datetime
95
- parts = []
96
- parts << "AWS4-HMAC-SHA256 Credential=#{access_key_id}/#{credential_string(datetime)}"
97
- parts << "SignedHeaders=#{signed_headers}"
98
- parts << "Signature=#{signature(datetime)}"
99
- parts.join(', ')
100
- end
101
-
102
- def signature datetime
103
- k_secret = secret_access_key
104
- k_date = hmac("AWS4" + k_secret, datetime[0,8])
105
- k_region = hmac(k_date, region)
106
- k_service = hmac(k_region, service)
107
- k_credentials = hmac(k_service, 'aws4_request')
108
- hexhmac(k_credentials, string_to_sign(datetime))
109
- end
110
-
111
- def string_to_sign datetime
112
- parts = []
113
- parts << 'AWS4-HMAC-SHA256'
114
- parts << datetime
115
- parts << credential_string(datetime)
116
- parts << hexdigest(canonical_request)
117
- parts.join("\n")
118
- end
119
-
120
- def credential_string datetime
121
- parts = []
122
- parts << datetime[0,8]
123
- parts << region
124
- parts << service
125
- parts << 'aws4_request'
126
- parts.join("/")
127
- end
128
-
129
- def canonical_request
130
- parts = []
131
- parts << http_method.to_s.upcase
132
- parts << @path
133
- parts << querystring
134
- parts << canonical_headers + "\n"
135
- parts << signed_headers
136
- if http_method == :post
137
- parts << headers['x-amz-content-sha256']
138
- else
139
- parts << hexdigest('')
140
- end
141
- parts.join("\n")
142
- end
143
-
144
- def signed_headers
145
- to_sign = headers.keys.map{|k| k.to_s.downcase }
146
- to_sign.delete('authorization')
147
- to_sign.sort.join(";")
148
- end
149
-
150
- def canonical_headers
151
- headers = []
152
- self.headers.each_pair do |k,v|
153
- headers << [k,v] unless k == 'authorization'
154
- end
155
- headers = headers.sort_by(&:first)
156
- headers.map{|k,v| "#{k}:#{canonical_header_values(v)}" }.join("\n")
157
- end
158
-
159
- def canonical_header_values values
160
- values = [values] unless values.is_a?(Array)
161
- values.map(&:to_s).join(',').gsub(/\s+/, ' ').strip
162
- end
163
-
164
- def hexdigest value
165
- digest = Digest::SHA256.new
166
- if value.respond_to?(:read)
167
- chunk = nil
168
- chunk_size = 1024 * 1024 # 1 megabyte
169
- digest.update(chunk) while chunk = value.read(chunk_size)
170
- value.rewind
171
- else
172
- digest.update(value)
173
- end
174
- digest.hexdigest
175
- end
176
-
177
- def hmac key, value
178
- OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha256'), key, value)
179
- end
180
-
181
- def hexhmac key, value
182
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('sha256'), key, value)
183
- end
184
61
  end
185
62
  end
186
63
 
@@ -0,0 +1,59 @@
1
+ require 'openssl'
2
+ require 'cgi'
3
+ require 'nokogiri'
4
+ require 'time'
5
+ require 'builder'
6
+
7
+ module AceClient
8
+ class Xml3 < Base3
9
+ format :xml
10
+
11
+ def action(method, path, params={})
12
+ record_response do
13
+ create_request(method, path, params).perform
14
+ end
15
+ end
16
+
17
+ def dryrun(method, path, params={})
18
+ create_request(method, path, params)
19
+ end
20
+
21
+ def create_request(method, path, params={})
22
+ @params = params
23
+ @params['Version'] = @version if @version
24
+
25
+ @before_signature.call(@params) if @before_signature
26
+
27
+ signature = create_signature
28
+
29
+ options = self.class.default_options.dup
30
+ options[:headers] = {}
31
+ options[:headers]['Date'] = date
32
+ options[:headers][@authorization_key] = "#{@authorization_prefix} #{@access_key_id_key}=#{access_key_id},Algorithm=#{signature_method},Signature=#{signature}"
33
+ options[:headers]['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
34
+ options[:headers]['User-Agent'] = @user_agent if @user_agent
35
+ options[:headers][@nonce_key] = @nonce if @nonce
36
+
37
+ http_method_class = case method
38
+ when :get; Net::HTTP::Get
39
+ when :post; Net::HTTP::Post
40
+ when :delete; Net::HTTP::Delete
41
+ end
42
+
43
+ if !params.empty?
44
+ builder = Builder::XmlMarkup.new
45
+ options[:body] = builder.tag!(params.keys.first) do |b|
46
+ params[params.keys.first].each do |k, v|
47
+ b.tag!(k, v)
48
+ end
49
+ end
50
+ end
51
+
52
+ @path = File.join('/', @version, path)
53
+
54
+ @before_request.call(@params) if @before_request
55
+
56
+ HTTParty::Request.new(http_method_class, endpoint_url + @path, options)
57
+ end
58
+ end
59
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ace-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.17
4
+ version: 0.0.18
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-12-04 00:00:00.000000000 Z
12
+ date: 2014-12-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -141,9 +141,13 @@ files:
141
141
  - bin/ace-q2
142
142
  - lib/ace-client.rb
143
143
  - lib/ace-client/base.rb
144
+ - lib/ace-client/base3.rb
145
+ - lib/ace-client/base4.rb
146
+ - lib/ace-client/json4.rb
144
147
  - lib/ace-client/query2.rb
145
148
  - lib/ace-client/query3.rb
146
149
  - lib/ace-client/query4.rb
150
+ - lib/ace-client/xml3.rb
147
151
  - spec/ace-client_spec.rb
148
152
  - spec/spec_helper.rb
149
153
  homepage: http://github.com/tily/ace-client
@@ -161,7 +165,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
161
165
  version: '0'
162
166
  segments:
163
167
  - 0
164
- hash: -293639598898322907
168
+ hash: -2109146560336915270
165
169
  required_rubygems_version: !ruby/object:Gem::Requirement
166
170
  none: false
167
171
  requirements: