woocommerce_api 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -41,22 +41,23 @@ woocommerce = WooCommerce::API.new(
41
41
 
42
42
  #### Args options
43
43
 
44
- | Option | Type | Required | Description |
45
- | ------------ | -------- | -------- | --------------------------------------------------------------------------------------------------- |
46
- | `version` | `String` | no | API version, default is `v3` |
47
- | `verify_ssl` | `Bool` | no | Verify SSL when connect, use this option as `false` when need to test with self-signed certificates |
44
+ | Option | Type | Required | Description |
45
+ | ------------------ | -------- | -------- | ------------------------------------------------------------------------------------------------------------ |
46
+ | `version` | `String` | no | API version, default is `v3` |
47
+ | `verify_ssl` | `Bool` | no | Verify SSL when connect, use this option as `false` when need to test with self-signed certificates |
48
+ | `signature_method` | `String` | no | Signature method used for oAuth requests, works with `HMAC-SHA1` and `HMAC-SHA256`, default is `HMAC-SHA256` |
48
49
 
49
50
  ## Methods
50
51
 
51
- | Params | Type | Description |
52
- | ---------- | ---------- | ------------------------------------------------------------ |
53
- | `endpoint` | `String` | WooCommerce API endpoint, example: `customers` or `order/12` |
54
- | `data` | `Object` | JS object, will be converted to JSON |
55
- | `callback` | `Function` | Callback function. Returns `err`, `data` and `res` |
52
+ | Params | Type | Description |
53
+ | ---------- | -------- | ------------------------------------------------------------ |
54
+ | `endpoint` | `String` | WooCommerce API endpoint, example: `customers` or `order/12` |
55
+ | `data` | `Hash` | Only for POST and PUT, data that will be converted to JSON |
56
+ | `query` | `Hash` | Only for GET and DELETE, request query string |
56
57
 
57
58
  ### GET
58
59
 
59
- - `.get(endpoint)`
60
+ - `.get(endpoint, query)`
60
61
 
61
62
  ### POST
62
63
 
@@ -68,7 +69,7 @@ woocommerce = WooCommerce::API.new(
68
69
 
69
70
  ### DELETE
70
71
 
71
- - `.delete(endpoint)`
72
+ - `.delete(endpoint, query)`
72
73
 
73
74
  #### Response
74
75
 
@@ -92,6 +93,7 @@ puts response.headers["x-wc-totalpages"] # Total of pages
92
93
 
93
94
  ## Release History
94
95
 
96
+ - 2015-08-27 - 1.1.0 - Added `query` argument for GET and DELETE methods, reduced chance of nonce collisions and added support for urls including ports
95
97
  - 2015-08-27 - 1.0.3 - Encode all % characters in query string for OAuth 1.0a.
96
98
  - 2015-08-12 - 1.0.2 - Fixed the release date.
97
99
  - 2015-08-12 - 1.0.1 - Escaped oauth_signature in url query string.
@@ -14,11 +14,16 @@ module WooCommerce
14
14
  @consumer_secret = consumer_secret
15
15
 
16
16
  # Optional args
17
- defaults = {version: "v3", verify_ssl: true}
17
+ defaults = {
18
+ version: "v3",
19
+ verify_ssl: true,
20
+ signature_method: "HMAC-SHA256"
21
+ }
18
22
  args = defaults.merge(args)
19
23
 
20
24
  @version = args[:version]
21
25
  @verify_ssl = args[:verify_ssl] == true
26
+ @signature_method = args[:signature_method]
22
27
 
23
28
  # Internal args
24
29
  @is_ssl = @url.start_with? "https"
@@ -27,10 +32,11 @@ module WooCommerce
27
32
  # Public: GET requests.
28
33
  #
29
34
  # endpoint - A String naming the request endpoint.
35
+ # query - A Hash with query params.
30
36
  #
31
37
  # Returns the request Hash.
32
- def get endpoint
33
- do_request :get, endpoint
38
+ def get endpoint, query = nil
39
+ do_request :get, add_query_params(endpoint, query)
34
40
  end
35
41
 
36
42
  # Public: POST requests.
@@ -56,38 +62,52 @@ module WooCommerce
56
62
  # Public: DELETE requests.
57
63
  #
58
64
  # endpoint - A String naming the request endpoint.
65
+ # query - A Hash with query params.
59
66
  #
60
67
  # Returns the request Hash.
61
- def delete endpoint
62
- do_request :delete, endpoint
68
+ def delete endpoint, query = nil
69
+ do_request :delete, add_query_params(endpoint, query)
63
70
  end
64
71
 
65
72
  protected
66
73
 
74
+ # Internal: Appends data as query params onto an endpoint
75
+ #
76
+ # endpoint - A String naming the request endpoint.
77
+ # data - A hash of data to flatten and append
78
+ #
79
+ # Returns an endpoint string with the data appended
80
+ def add_query_params endpoint, data
81
+ return endpoint if data.nil? || data.empty?
82
+
83
+ endpoint += '?' unless endpoint.include? '?'
84
+ endpoint += '&' unless endpoint.end_with? '?'
85
+ endpoint + URI.encode(flatten_hash(data).join('&'))
86
+ end
87
+
67
88
  # Internal: Get URL for requests
68
89
  #
69
90
  # endpoint - A String naming the request endpoint.
91
+ # method - The method used in the url (for oauth querys)
70
92
  #
71
93
  # Returns the endpoint String.
72
- def get_url endpoint
94
+ def get_url endpoint, method
73
95
  url = @url
74
- if !url.end_with? "/"
75
- url = "#{url}/"
76
- end
96
+ url = "#{url}/" unless url.end_with? "/"
97
+ url = "#{url}wc-api/#{@version}/#{endpoint}"
77
98
 
78
- "#{url}wc-api/#{@version}/#{endpoint}"
99
+ @is_ssl ? url : oauth_url(url, method)
79
100
  end
80
101
 
81
102
  # Internal: Requests default options.
82
103
  #
83
- # method - A String maning the request method
104
+ # method - A String naming the request method
84
105
  # endpoint - A String naming the request endpoint.
85
106
  # data - The Hash data for the request.
86
107
  #
87
108
  # Returns the response in JSON String.
88
- def do_request method, endpoint, data = nil
89
- url = get_url endpoint
90
-
109
+ def do_request method, endpoint, data = {}
110
+ url = get_url(endpoint, method)
91
111
  options = {
92
112
  format: :json,
93
113
  verify: @verify_ssl,
@@ -97,27 +117,52 @@ module WooCommerce
97
117
  "Accept" => "application/json"
98
118
  }
99
119
  }
100
-
101
120
  if @is_ssl
102
- options.merge!({
103
- basic_auth: {
104
- username: @consumer_key,
105
- password: @consumer_secret
106
- }
107
- })
108
- else
109
- oauth = WooCommerce::OAuth.new url, method, @version, @consumer_key, @consumer_secret
110
- url = oauth.get_oauth_url
111
- end
112
-
113
- if data
114
- options.merge!({
115
- body: data.to_json
121
+ options.merge!(basic_auth: {
122
+ username: @consumer_key,
123
+ password: @consumer_secret
116
124
  })
117
125
  end
126
+ options.merge!(body: data.to_json) if data
127
+ HTTParty.send(method, url, options)
128
+ end
118
129
 
119
- HTTParty.send method, url, options
130
+ # Internal: Generates an oauth url given current settings
131
+ #
132
+ # url - A String naming the current request url
133
+ # method - The HTTP verb of the request
134
+ #
135
+ # Returns a url to be used for the query.
136
+ def oauth_url url, method
137
+ oauth = WooCommerce::OAuth.new(
138
+ url,
139
+ method,
140
+ @version,
141
+ @consumer_key,
142
+ @consumer_secret,
143
+ @signature_method
144
+ )
145
+ oauth.get_oauth_url
120
146
  end
121
147
 
148
+ # Internal: Flattens a hash into an array of query relations
149
+ #
150
+ # hash - A hash to flatten
151
+ #
152
+ # Returns an array full of key value paired strings
153
+ def flatten_hash hash
154
+ hash.flat_map do |key, value|
155
+ case value
156
+ when Hash
157
+ value.map do |inner_key, inner_value|
158
+ "#{key}[#{inner_key}]=#{inner_value}"
159
+ end
160
+ when Array
161
+ value.map { |inner_value| "#{key}[]=#{inner_value}" }
162
+ else
163
+ "#{key}=#{value}"
164
+ end
165
+ end
166
+ end
122
167
  end
123
168
  end
@@ -6,13 +6,15 @@ require "openssl"
6
6
 
7
7
  module WooCommerce
8
8
  class OAuth
9
+ class InvalidSignatureMethodError < StandardError; end
9
10
 
10
- def initialize url, method, version, consumer_key, consumer_secret
11
+ def initialize url, method, version, consumer_key, consumer_secret, signature_method = "HMAC-SHA256"
11
12
  @url = url
12
13
  @method = method.upcase
13
14
  @version = version
14
15
  @consumer_key = consumer_key
15
16
  @consumer_secret = consumer_secret
17
+ @signature_method = signature_method
16
18
  end
17
19
 
18
20
  # Public: Get OAuth url
@@ -27,13 +29,16 @@ module WooCommerce
27
29
  CGI::parse(parsed_url.query).each do |key, value|
28
30
  params[key] = value[0]
29
31
  end
32
+ params = Hash[params.sort]
30
33
 
31
- url = "#{parsed_url.scheme}://#{parsed_url.host}#{parsed_url.path}"
34
+ url = parsed_url.to_s.gsub(/\?.*/, "")
32
35
  end
33
36
 
37
+ nonce_lifetime = 15 * 60 # Woocommerce keeps nonces for 15 minutes
38
+
34
39
  params["oauth_consumer_key"] = @consumer_key
35
- params["oauth_nonce"] = Digest::SHA1.hexdigest("#{Time.new.to_i + rand(99999)}")
36
- params["oauth_signature_method"] = "HMAC-SHA256"
40
+ params["oauth_nonce"] = Digest::SHA1.hexdigest((Time.new.to_f % nonce_lifetime + (Process.pid * nonce_lifetime)).to_s)
41
+ params["oauth_signature_method"] = @signature_method
37
42
  params["oauth_timestamp"] = Time.new.to_i
38
43
  params["oauth_signature"] = CGI::escape(generate_oauth_signature(params, url))
39
44
 
@@ -68,7 +73,19 @@ module WooCommerce
68
73
  consumer_secret = @consumer_secret
69
74
  end
70
75
 
71
- return Base64.strict_encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), consumer_secret, string_to_sign))
76
+ return Base64.strict_encode64(OpenSSL::HMAC.digest(digest, consumer_secret, string_to_sign))
77
+ end
78
+
79
+ # Internal: Digest object based on signature method
80
+ #
81
+ # Returns a digest object.
82
+ def digest
83
+ case @signature_method
84
+ when "HMAC-SHA256" then OpenSSL::Digest.new("sha256")
85
+ when "HMAC-SHA1" then OpenSSL::Digest.new("sha1")
86
+ else
87
+ fail InvalidSignatureMethodError
88
+ end
72
89
  end
73
90
 
74
91
  # Internal: Encode param
@@ -76,8 +93,8 @@ module WooCommerce
76
93
  # text - A String to be encoded
77
94
  #
78
95
  # Returns the encoded String.
79
- def encode_param(text)
80
- CGI::escape(text).gsub('%', '%25')
96
+ def encode_param text
97
+ CGI::escape(text).gsub("%", "%25")
81
98
  end
82
99
  end
83
100
  end
@@ -1,3 +1,3 @@
1
1
  module WooCommerce
2
- VERSION = '1.0.3'
2
+ VERSION = '1.1.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: woocommerce_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
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: 2015-08-27 00:00:00.000000000 Z
12
+ date: 2015-10-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: httparty