Class: Allorails::Request::ApiRequest

Inherits:
Object
  • Object
show all
Defined in:
lib/allorails/request/request.rb

Constant Summary collapse

MAPPING_FORMAT =

API response format needed to provide response object mapping

'xml'
API_PATH =

API remote base path

'/rest'

Instance Method Summary collapse

Constructor Details

#initialize(parameters, mapping = true, email_account = nil) ⇒ ApiRequest

Constructor

@param parameters (array) Parameters to the API call
@param mapping (boolean) Wether to return a raw response or an object
@param emailAccount (string) Configurated email 


39
40
41
42
43
# File 'lib/allorails/request/request.rb', line 39

def initialize(parameters, mapping = true,  = nil)
  @_mapping = mapping
  @_parameters = _stringify_symbols parameters
   = 
end

Instance Method Details

#_build_parametersObject

Internal method building special required API parameters

@return ApiRequest Class instance for chaining purpose


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/allorails/request/request.rb', line 70

def _build_parameters
  formats = ['json', 'xml']

  @_parameters.update({
    'api_ts' => Time.now.to_i,
    'api_key' => Allorails.config.api_key(),
    'api_hash' => Allorails.config.default_hash
  })

  if @_parameters.has_key?('format')
    if (@_mapping)
      @_parameters['format'] = self::MAPPING_FORMAT
    elsif !formats.include?(@_parameters['format'])
      @_parameters['format'] = Allorails.config.default_format
    end
  else
    @_parameters['format'] = Allorails.config.default_format
  end

  self
end

#_callObject

Internal method calling the Allopass API

@return (tuple) Pair containing response headers and body


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/allorails/request/request.rb', line 127

def _call
  protocol = Allorails.config.network_protocol
  server   = Allorails.config.host
  timeout  = Allorails.config.network_timeout.to_f

  port    = protocol == 'https' ? 443 : 80
  uri     = URI(protocol + '://' + server + ApiRequest::API_PATH + _path)
  method  = _is_http_post ? 'POST' : 'GET'
  headers = {
    "Content-Type" => "application/x-www-form-urlencoded; charset=utf-8",
    "User-Agent" => "Allopass-ApiKit-AlloRails"
  }
  
  # use a proxy?
  use_proxy = false
  http_class = if use_proxy then Net::HTTP::Proxy('127.0.0.1', 9999) else Net::HTTP end

  # prepare and send HTTP request
  http_class.start(uri.host, port, :use_ssl => uri.scheme == 'https') do |http|
    
    if method == 'GET'
      uri.query = _encode_parameters
      req = http_class::Get.new uri.request_uri
    else
      #uri.query = _encode_parameters
      req = http_class::Post.new uri.request_uri
      req.body = _encode_parameters
    end    
    
    # set headers
    headers.each_pair{|k, v| req[k] = v}
    
    # send the request and see if successful
    case res = http.request(req)
      when Net::HTTPSuccess then return [res.to_hash, res.body]
      else raise Allorails::ApiUnavailableResourceError, "Request failed: #{res.body}"
    end
  end
end

#_encode_parametersObject

Internal method encoding request paramters

@return (string) Encoded request parameters


170
171
172
173
174
175
176
177
178
179
180
# File 'lib/allorails/request/request.rb', line 170

def _encode_parameters
  params = @_parameters.dup
  # The Allopass API expects an array of codes encoded
  # in a slightly different matter than urlencode does
  if params.has_key?('code')
    codes = params.delete('code')
    (0..codes.length-1).each{|i| params["code[#{i}]"] = codes[i]}
  end
  
  URI::encode params.collect { |k,v| "#{k}=#{v}" }.join('&') #CGI::escape(v.to_s)
end

#_hash(data) ⇒ Object

Internal method hashing data with defined cipher #TODO en prenant en compte la donnée incrite dans les confs

@parameter data (string) Data to hash

@throws ApiMissingHashFeatureError If defined cipher method isn'h available


113
114
115
# File 'lib/allorails/request/request.rb', line 113

def _hash(data)
  ::Digest::SHA1.hexdigest(data)
end

#_is_http_postObject

Internal method deciding wether to use a POST request

@return (boolean) True to use POST


120
121
122
# File 'lib/allorails/request/request.rb', line 120

def _is_http_post
  false
end

#_new_response(signature, headers, body) ⇒ Object

class of the Response Returns an object mapping the Allopass API response

@param signature (string) Expected response signature
@param headers (list) Response HTTP headers
@param body (string) Raw response data 

@return ApiResponse An object mapping the Allopass API response


30
31
32
# File 'lib/allorails/request/request.rb', line 30

def _new_response(signature, headers, body)
  raise "new_response is not implemented"
end

#_pathObject

Returns the remote path of the Allopass API service

@return (string) A remote path


18
19
20
# File 'lib/allorails/request/request.rb', line 18

def _path
  self.class::PATH
end

#_signObject

Internal methods used to sign the request call

@return ApiRequest Class instance for chaining purpose


95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/allorails/request/request.rb', line 95

def _sign
  params = @_parameters.dup

  if params.has_key?('code')
    params['code'] = params.delete('code').join
  end
  
  sign = params.sort.map{|p| "#{p[0]}#{p[1]}"}.join
  @_parameters['api_sig'] = self._hash(sign + Allorails.config.private_key())
  
  self
end

#_stringify_symbols(x) ⇒ Object

Internal method to turn symbols (keys and values) into strings



60
61
62
63
64
65
# File 'lib/allorails/request/request.rb', line 60

def _stringify_symbols x
  return x.to_s if x.is_a?(Symbol)
  return x.map{|y| _stringify_symbols y} if x.is_a?(Array)
  return x.inject({}) {|h, (k,v)| h[_stringify_symbols k] = _stringify_symbols v; h} if x.is_a?(Hash)
  return x
end

#callObject

Call the Allopass API and returns the response (raw or object)

@return ApiResponse The API response


48
49
50
51
52
53
54
55
56
57
# File 'lib/allorails/request/request.rb', line 48

def call()
  headers, body = self._build_parameters._sign._call
  signature = self._hash(body + Allorails.config.private_key())

  if (@_mapping)
    return self._new_response(signature, headers, body)
  else
    return Allorails::Response::ApiResponse.new(signature, headers, body)
  end
end