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 +1 -1
- data/lib/ace-client.rb +4 -0
- data/lib/ace-client/base3.rb +40 -0
- data/lib/ace-client/base4.rb +183 -0
- data/lib/ace-client/json4.rb +28 -0
- data/lib/ace-client/query3.rb +1 -30
- data/lib/ace-client/query4.rb +1 -124
- data/lib/ace-client/xml3.rb +59 -0
- metadata +7 -3
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0.0. | 
| 1 | 
            +
            0.0.18
         | 
    
        data/lib/ace-client.rb
    CHANGED
    
    | @@ -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 | 
            +
             | 
    
        data/lib/ace-client/query3.rb
    CHANGED
    
    | @@ -4,27 +4,11 @@ require 'nokogiri' | |
| 4 4 | 
             
            require 'time'
         | 
| 5 5 |  | 
| 6 6 | 
             
            module AceClient
         | 
| 7 | 
            -
              class Query3 <  | 
| 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
         | 
    
        data/lib/ace-client/query4.rb
    CHANGED
    
    | @@ -1,20 +1,9 @@ | |
| 1 1 | 
             
            module AceClient
         | 
| 2 | 
            -
              class Query4 <  | 
| 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. | 
| 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- | 
| 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: - | 
| 168 | 
            +
                  hash: -2109146560336915270
         | 
| 165 169 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 166 170 | 
             
              none: false
         | 
| 167 171 | 
             
              requirements:
         |