syncwise_api 0.0.1

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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +29 -0
  8. data/Rakefile +1 -0
  9. data/lib/syncwise_api/client.rb +47 -0
  10. data/lib/syncwise_api/errors.rb +93 -0
  11. data/lib/syncwise_api/ext/core_ext.rb +176 -0
  12. data/lib/syncwise_api/ext/inflections.rb +66 -0
  13. data/lib/syncwise_api/ext/inflector/inflections.rb +177 -0
  14. data/lib/syncwise_api/ext/inflector_methods.rb +62 -0
  15. data/lib/syncwise_api/ext/string_encoding.rb +12 -0
  16. data/lib/syncwise_api/mixins/mixins.rb +1 -0
  17. data/lib/syncwise_api/mixins/request_builder.rb +23 -0
  18. data/lib/syncwise_api/mixins/request_sender.rb +11 -0
  19. data/lib/syncwise_api/mixins/request_signer.rb +20 -0
  20. data/lib/syncwise_api/requests/V1_0/assign_device_create.rb +19 -0
  21. data/lib/syncwise_api/requests/V1_0/base.rb +115 -0
  22. data/lib/syncwise_api/requests/V1_0/device_details.rb +19 -0
  23. data/lib/syncwise_api/requests/V1_0/device_list.rb +19 -0
  24. data/lib/syncwise_api/requests/V1_0/device_settings_details.rb +19 -0
  25. data/lib/syncwise_api/requests/V1_0/device_settings_edit.rb +19 -0
  26. data/lib/syncwise_api/requests/V1_0/device_subscribe.rb +19 -0
  27. data/lib/syncwise_api/requests/V1_0/device_unsubscribe.rb +19 -0
  28. data/lib/syncwise_api/requests/V1_0/driver_speed_report.rb +19 -0
  29. data/lib/syncwise_api/requests/V1_0/obd_vehicle_details.rb +19 -0
  30. data/lib/syncwise_api/requests/V1_0/trip_event_details.rb +19 -0
  31. data/lib/syncwise_api/requests/V1_0/user_login.rb +26 -0
  32. data/lib/syncwise_api/requests/V1_0/user_subscribe_settings_details.rb +19 -0
  33. data/lib/syncwise_api/requests/V1_0/vehicle_gauge_information.rb +19 -0
  34. data/lib/syncwise_api/requests/V1_0/vehicle_idling_history.rb +19 -0
  35. data/lib/syncwise_api/requests/requests.rb +2 -0
  36. data/lib/syncwise_api/responses/V1_0/base.rb +35 -0
  37. data/lib/syncwise_api/responses/V1_0/standard.rb +9 -0
  38. data/lib/syncwise_api/responses/responses.rb +1 -0
  39. data/lib/syncwise_api/service_utils/crypto/hmac_sha256.rb +15 -0
  40. data/lib/syncwise_api/service_utils/encoders/base64.rb +16 -0
  41. data/lib/syncwise_api/service_utils/encoders/json.rb +21 -0
  42. data/lib/syncwise_api/service_utils/http.rb +34 -0
  43. data/lib/syncwise_api/service_utils/parsers/json.rb +55 -0
  44. data/lib/syncwise_api/service_utils/service_utils.rb +2 -0
  45. data/lib/syncwise_api/service_utils/time_stamper.rb +13 -0
  46. data/lib/syncwise_api/version.rb +3 -0
  47. data/lib/syncwise_api.rb +30 -0
  48. data/syncwise_api.gemspec +27 -0
  49. data/tester.rb +10 -0
  50. metadata +162 -0
@@ -0,0 +1,62 @@
1
+ require_relative 'inflections'
2
+
3
+ # holds 'inflector methods' (to use a Rails term) to change 'words' from one form to another
4
+ module SyncwiseApi
5
+ module Inflector
6
+
7
+ # downcase words, and replace ' ' with '_'. Example 'Big Bob'.dehumanize => 'big_bob'
8
+ def dehumanize(word)
9
+ # should be OK to remove the respond_to? as long as we ensure we call this only on Strings or things that can be
10
+ # cast to Strings
11
+ #if word.respond_to?(:to_s)
12
+ dh_word = word.to_s.dup
13
+ dh_word.gsub!(/ /, '_')
14
+ dh_word.downcase!
15
+ dh_word
16
+ #end
17
+ end
18
+
19
+ def underscore(camel_cased_word)
20
+ # should be OK to remove the respond_to? as long as we ensure we call this only on Strings or things that can be
21
+ # cast to Strings
22
+ #if camel_cased_word.respond_to?(:to_s)
23
+ word = camel_cased_word.to_s.dup
24
+ word.gsub!(/::/, '/')
25
+ word.gsub!(/(?:([A-Za-z\d])|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
26
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
27
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
28
+ word.tr!("-", "_")
29
+ word.downcase!
30
+ word
31
+ #end
32
+ end
33
+
34
+ # By default, +camelize+ converts strings to UpperCamelCase. If the argument to +camelize+
35
+ # is set to <tt>:lower</tt> then +camelize+ produces lowerCamelCase.
36
+ #
37
+ # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
38
+ #
39
+ # Examples:
40
+ # "active_model".camelize # => "ActiveModel"
41
+ # "active_model".camelize(:lower) # => "activeModel"
42
+ # "active_model/errors".camelize # => "ActiveModel::Errors"
43
+ # "active_model/errors".camelize(:lower) # => "activeModel::Errors"
44
+ #
45
+ # As a rule of thumb you can think of +camelize+ as the inverse of +underscore+,
46
+ # though there are cases where that does not hold:
47
+ #
48
+ # "SSLError".underscore.camelize # => "SslError"
49
+ def camelize(term, uppercase_first_letter = true)
50
+ string = term.to_s
51
+ if uppercase_first_letter
52
+ string = string.sub(/^[a-z\d]*/) { inflections.acronyms[$&] || $&.capitalize }
53
+ else
54
+ string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
55
+ end
56
+ string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }.gsub('/', '::')
57
+ end
58
+
59
+ module_function :dehumanize, :underscore, :camelize
60
+
61
+ end
62
+ end
@@ -0,0 +1,12 @@
1
+ # ripped from rails
2
+ class String
3
+ if defined?(Encoding) && "".respond_to?(:encode)
4
+ def encoding_aware?
5
+ true
6
+ end
7
+ else
8
+ def encoding_aware?
9
+ false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1 @@
1
+ Dir["#{File.dirname(__FILE__)}/**/*.rb"].each { |f| require f }
@@ -0,0 +1,23 @@
1
+ # Currently not used
2
+ #module SyncwiseApi
3
+ # module Mixins
4
+ # module RequestBuilder
5
+ #
6
+ # def extract_header_params
7
+ # # first, we have to make sure that this is mixed into a class that has a @param instance variable
8
+ # # and that has a superclass with a required_header_params method
9
+ # if !self.instance_variable_defined?(:@params)
10
+ # fail SyncwiseApi::Errors::MissingInstanceVariable.new(:@params, SyncwiseApi::Mixins::RequestBuilder, self)
11
+ # elsif !self.superclass.respond_to?(:required_header_params)
12
+ # fail SyncwiseApi::Errors::MissingMethod.new(:required_header_params, SyncwiseApi::Mixins::RequestBuilder, self)
13
+ # else
14
+ # # as crazy as this looks, all it does is pull out the required header params from the @params hash, which holds
15
+ # # any dynamically supplied params, and add them to the @header hash, which holds the header params
16
+ # @header = {}
17
+ # self.superclass.required_header_params.each { |key| @header[key] = @params.delete(key) }
18
+ # end
19
+ # end
20
+ #
21
+ # end
22
+ # end
23
+ #end
@@ -0,0 +1,11 @@
1
+ # using Net::Http to make requests to avoid external gem dependencies
2
+ module SyncwiseApi
3
+ module Mixins
4
+ module RequestSender
5
+
6
+ def send
7
+ #TODO: make request to syncwise
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ module SyncwiseApi
2
+ module Mixins
3
+ module RequestSigner
4
+
5
+ def sign
6
+ if !self.instance_variable_defined?(:@params)
7
+ fail SyncwiseApi::Errors::MissingInstanceVariable.new(:@request, SyncwiseApi::Mixins::RequestSigner, self)
8
+ elsif !self.instance_variable_defined?(:@header)
9
+ fail SyncwiseApi::Errors::MissingInstanceVariable.new(:@header, SyncwiseApi::Mixins::RequestSigner, self)
10
+ else
11
+
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class AssignDeviceCreate < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:deviceList]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,115 @@
1
+ require 'openssl'
2
+
3
+ module SyncwiseApi
4
+ module Requests
5
+ module V1_0
6
+ class Base
7
+ #include SyncwiseApi::Mixins::RequestBuilder
8
+ #include SyncwiseApi::Mixins::RequestSigner
9
+ #include SyncwiseApi::Mixins::RequestSender
10
+
11
+ # @required_header_params represents the keys required by all required for all Syncwise API calls, and CHANGE on a per call basis
12
+ # thus, they must be present (have values) in the paramss passed to #initialize when creating a new object that
13
+ # inherits from this class (Base)
14
+ #TODO: Make this a class constant?
15
+ @required_header_params = [:'API Key', :'Action Code']
16
+ @required_header_params.freeze
17
+
18
+ # @default_header_params holds key/values that are universally required for all Syncwise API calls, and DO NOT CHANGE
19
+ #TODO: Make this a class constant?
20
+ @default_header_params = {:'API Version' => 1.0, :'Signature Version' => 1, :'Signature Method' => 'HmacSHA256', :'Response Format' => 'JSON'}
21
+ @default_header_params.freeze
22
+
23
+ # @required_params represents all the params (both header and payload) that must be passed to #initialize when
24
+ # creating a new object that inherits from this class (Base)
25
+ #TODO: Make this a class constant?
26
+ @required_params = [:secretKey, :accountId]
27
+ @required_params.concat(@required_header_params)
28
+ @required_params.freeze
29
+
30
+ HOST_HEADER = 'api-int.syncwise.com'
31
+ BASE_URL = "https://#{HOST_HEADER}/rest/action"
32
+
33
+ class << self
34
+ attr_reader :required_header_params, :default_header_params, :required_params, :host_header
35
+ end
36
+
37
+ def initialize(params = {})
38
+ # Add the action code to params based on the child class's name
39
+ params[:'Action Code'] = self.unqualified_class
40
+
41
+ # Verify we have all required params by comparing child class's required_params to the passed in params
42
+ param_keys = params.keys.sort
43
+
44
+ fail SyncwiseApi::Errors::InvalidParameters.new(self.class, param_keys, self.class.required_params) unless param_keys & self.class.required_params == self.class.required_params
45
+ # remove the signing key from params and store it for use when building the HMAC signature
46
+ @secret_key = params.delete(:secretKey)
47
+
48
+ # @params now holds the params we need to build the header_hash
49
+ @params = params
50
+
51
+ build_header_hash
52
+
53
+ # after build_header_hash returns, we have @header which holds all values needed to build the request and signature
54
+ # and @params which now only contains the values that will be added to the JSON payload
55
+ end
56
+
57
+ def send_request
58
+ request_string = build_api_call
59
+ body = build_body
60
+ # TODO: send POST with Net::Http to request_string with JSON payload body
61
+ SyncwiseApi::ServiceUtils::HTTP.post(request_string, body) do |http_response|
62
+ SyncwiseApi::Responses::V1_0::Standard.new(http_response)
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def build_header_hash
69
+ # pull out the required header params from the @params hash, which holds
70
+ # any dynamically supplied params, and add them to the @header hash, which holds the header params
71
+ @header = {}.merge(SyncwiseApi::Requests::V1_0::Base.default_header_params)
72
+ SyncwiseApi::Requests::V1_0::Base.required_header_params.each { |key| @header[key] = @params.delete(key) }
73
+ @header[:Timestamp] = SyncwiseApi::ServiceUtils::Timestamper.stamp
74
+ end
75
+
76
+ def build_api_call
77
+ "#{SyncwiseApi::Requests::V1_0::Base::BASE_URL}/#{@header[:'Action Code']}/#{@header[:'API Key']}/#{@header[:'API Version']}/#{@header[:'Signature Version']}/#{@header[:'Signature Method']}/#{create_signature}/#{@header[:Timestamp]}/#{@header[:'Response Format']}"
78
+ end
79
+
80
+ def build_body
81
+ SyncwiseApi::ServiceUtils::Encoders::JSON.encode(@params)
82
+ end
83
+
84
+ def create_signature
85
+ bin_hmac = SyncwiseApi::ServiceUtils::Crypto::HmacSha256.crypt(@secret_key, string_to_sign)
86
+ base64_hmac = SyncwiseApi::ServiceUtils::Encoders::Base64.encode(bin_hmac)
87
+ replace_bad_chars(base64_hmac)
88
+ end
89
+
90
+ def string_to_sign
91
+ "#{self.class.verb}\n#{SyncwiseApi::Requests::V1_0::Base::HOST_HEADER}\n#{canonicalized_query_string}"
92
+ end
93
+
94
+ def canonicalized_query_string
95
+ sorted_header_array = @header.to_a.sort
96
+ query_string = ''
97
+ sorted_header_array.each do |key_value_array|
98
+ query_string = query_string + "&#{key_value_array[0]}=#{key_value_array[1]}"
99
+ end
100
+
101
+ query_string
102
+ end
103
+
104
+ def replace_bad_chars(encoded_string)
105
+ encoded_string.gsub!('/', 'A')
106
+ encoded_string.gsub!('+', 'B')
107
+ encoded_string.gsub!('=', 'C')
108
+ encoded_string.gsub!('&', 'D')
109
+ encoded_string
110
+ end
111
+
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class DeviceDetails < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:deviceId]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class DeviceList < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = []
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class DeviceSettingsDetails < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:deviceId, :settingsStatus]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class DeviceSettingsEdit < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:deviceId, :appTypeVer, :deviceSettings]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class DeviceSubscribe < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:deviceList]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class DeviceUnsubscribe < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:deviceList]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class DriverSpeedReport < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:deviceId, :endDate, :startDate]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class OBDVehicleDetails < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:deviceId]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class TripEventDetails < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:deviceId, :tripId]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class UserLogin < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:password]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ # overrides create_signature in Base, because for this request only, no signature is possible since we
17
+ # don't have a secret key yet. the service still requires a dummy value here, though, so just quickly return a
18
+ # valid, but dummy, signature string
19
+ def create_signature
20
+ 'k8NipGDhzthk0EJRmHCBy2NcwSsC'
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class UserSubscribeSettingsDetails < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = []
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class VehicleGaugeInformation < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:deviceId, :gaugeMap, :endDate, :startDate]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module SyncwiseApi
2
+ module Requests
3
+ module V1_0
4
+ class VehicleIdlingHistory < Base
5
+
6
+ #TODO: this is janky. Fix it. Class constants? Something in Base? Not sure...
7
+ my_required_params = [:deviceId, :endDate, :startDate]
8
+ @required_params = my_required_params.concat(self.superclass.required_params)
9
+ @required_params.sort!.freeze
10
+ @verb = 'POST'
11
+
12
+ class << self
13
+ attr_reader :required_params, :verb
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,2 @@
1
+ require_relative 'V1_0/base'
2
+ Dir["#{File.dirname(__FILE__)}/**/*.rb"].each { |f| require f }
@@ -0,0 +1,35 @@
1
+ module SyncwiseApi
2
+ module Responses
3
+ module V1_0
4
+ class Base
5
+
6
+ def initialize(http_response_object)
7
+ @http_response_object = http_response_object
8
+ @body = @http_response_object.body
9
+ @header_hash = @http_response_object.header.to_hash.symbolize_keys
10
+ @body_hash = parse
11
+ end
12
+
13
+ attr_reader :body_hash
14
+
15
+ def valid?
16
+ @body_hash[:sts] == '1'
17
+ end
18
+
19
+ private
20
+
21
+ def parse
22
+ # if the response has a body, and the body is json, parse and store it in @body_hash; otherwise throw an error
23
+ if @body.blank?
24
+ fail SyncwiseApi::Errors::EmptyResponseBody.new(@http_response_object, @http_response_object.uri, @header_hash)
25
+ elsif !@header_hash[:content_type].include?('application/json')
26
+ fail SyncwiseApi::Errors::InvalidContentType.new(@http_response_object, @http_response_object.uri, @header_hash)
27
+ else
28
+ SyncwiseApi::ServiceUtils::Parsers::JSON.parse(@body).symbolize_keys
29
+ end
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ module SyncwiseApi
2
+ module Responses
3
+ module V1_0
4
+ class Standard < Base
5
+
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1 @@
1
+ Dir["#{File.dirname(__FILE__)}/**/*.rb"].each { |f| require f }
@@ -0,0 +1,15 @@
1
+ module SyncwiseApi
2
+ module ServiceUtils
3
+ module Crypto
4
+ module HmacSha256
5
+
6
+ def crypt(secret_key, string_to_sign)
7
+ digest = OpenSSL::Digest::Digest.new('sha256')
8
+ OpenSSL::HMAC.digest(digest, secret_key, string_to_sign)
9
+ end
10
+
11
+ module_function :crypt
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require 'base64'
2
+
3
+ module SyncwiseApi
4
+ module ServiceUtils
5
+ module Encoders
6
+ module Base64
7
+
8
+ def encode(body)
9
+ ::Base64.strict_encode64(body)
10
+ end
11
+
12
+ module_function :encode
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ require 'yajl'
2
+
3
+ module SyncwiseApi
4
+ module ServiceUtils
5
+ module Encoders
6
+ module JSON
7
+
8
+ def encode(object)
9
+ if object.is_a?(Hash) || object.is_a?(Array)
10
+ Yajl::Encoder.encode(object)
11
+ else
12
+ fail SyncwiseApi::Errors::JSONEncodeError.new(object)
13
+ end
14
+ end
15
+
16
+ module_function :encode
17
+
18
+ end
19
+ end
20
+ end
21
+ end