zuora_api 1.6.25 → 1.6.26

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e550dd86e9507f9652c0523af913d907dfefa22f
4
- data.tar.gz: 66c1f11eda0adab384baf5d2a970ccf72163fe25
3
+ metadata.gz: e86b5da627b9f51c342da05d5e4110e3385a35a4
4
+ data.tar.gz: 9ccf40e8d6dfca789d16207421dc07352ad8c921
5
5
  SHA512:
6
- metadata.gz: adedd68525df111f61712740df8d292578e883320e4b15f508087dea1e684d59eebd8eb09ff45e2fed64d7da277e73f1dad3d3182eb40a9164b465320fdfdbd1
7
- data.tar.gz: 260d9b579be019134023fd270003341ed471f6d2897a02d2cae100fe8dcfc306b2723dc5793a0dec2be4e5d1e9235eeaa5c064764394a16729f8e3fc2c86e87e
6
+ metadata.gz: 35a3fb0d447a8a52d11762133e0fe11cccea7e5970c74aa31bc121153dc62d3aece97adaf08fa1a8cc6562c5eee2b74c9c24144ff981d503083530b10c1e3bb3
7
+ data.tar.gz: ef0b5f9af4d236df06de046d3afd6e8e649a007281036c9770df4cb289d31df99f3f1ae535eae55ff28154b6f098b60e0e46f90724b894d0b1dc27a0743b3795
data/CHANGELOG.md CHANGED
@@ -11,12 +11,6 @@ All notable changes to this project will be documented in this file.
11
11
  ### Removed
12
12
  - Example
13
13
 
14
- ## [1.6.22] - 2019-01-03
15
-
16
- ### Changed
17
- - get_identity method - supports ZSession auth now
18
- - updated rspecs accordingly
19
-
20
14
  ## [1.6.18] - 2018-12-06
21
15
  ### Added
22
16
  - zconnect_provider attribute accessor for identifying ZConnect cookies
@@ -30,4 +24,15 @@ All notable changes to this project will be documented in this file.
30
24
  ### Changed
31
25
  - The way environment and region are set
32
26
 
27
+ ## [1.6.22] - 2019-01-03
33
28
 
29
+ ### Changed
30
+ - get_identity method - supports ZSession auth now
31
+ - updated rspecs accordingly
32
+
33
+ ## [1.6.26] - 2019-03-04
34
+
35
+ ### Changed
36
+ - fixed get_oauth_client for non-staging environments
37
+ - fixed to use correct rest endpoint without version for oauth creation api
38
+ - changed get_oauth_client to no longer accept client id and secret as parameters
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- zuora_api (1.6.25)
4
+ zuora_api (1.6.26)
5
5
  httparty
6
6
  nokogiri
7
7
  railties (>= 4.1.0, < 5.2)
@@ -42,7 +42,7 @@ GEM
42
42
  httparty (0.16.4)
43
43
  mime-types (~> 3.0)
44
44
  multi_xml (>= 0.5.2)
45
- i18n (1.5.3)
45
+ i18n (1.6.0)
46
46
  concurrent-ruby (~> 1.0)
47
47
  json (2.1.0)
48
48
  loofah (2.2.3)
@@ -156,13 +156,11 @@ module ZuoraAPI
156
156
  end
157
157
 
158
158
  # There are two ways to call this method. The first way is best.
159
- # 1. Pass in cookies and optionally custom_authorities, name, and description
160
- # 2. Pass in user_id, entity_ids, client_id, client_secret, and optionally custom_authorities, name, and description
159
+ # 1. Pass in cookies, name, and description
160
+ # 2. Pass in user_id, entity_ids, an existing client_id and client_secret, name, and description
161
161
  # https://intranet.zuora.com/confluence/display/Sunburst/Create+an+OAuth+Client+through+API+Gateway#CreateanOAuthClientthroughAPIGateway-ZSession
162
- def get_oauth_client (custom_authorities = [], info_name: "No Name", info_desc: "This client was created without a description.", user_id: nil, entity_ids: nil, client_id: nil, client_secret: nil, new_client_id: nil, new_client_secret: nil, cookies: nil)
162
+ def get_oauth_client (info_name: "No Name", info_desc: "This client was created without a description.", user_id: nil, entity_ids: nil, client_id: nil, client_secret: nil, cookies: nil)
163
163
  authorization = ""
164
- new_client_id = SecureRandom.uuid if new_client_id.blank?
165
- new_client_secret = SecureRandom.hex(10) if new_client_secret.blank?
166
164
 
167
165
  if !cookies.nil?
168
166
  authorization = cookies["ZSession"]
@@ -178,18 +176,18 @@ module ZuoraAPI
178
176
  raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Zuora User ID not provided", {}, 400)
179
177
  end
180
178
  elsif !client_id.nil? && !client_secret.nil?
181
- bearer_response = HTTParty.post("https://#{self.hostname}/oauth/token", :headers => {'Content-Type' => 'application/x-www-form-urlencoded', 'Accept' => 'application/json'}, :body => {'client_id' => client_id, 'client_secret' => URI::encode(client_secret), 'grant_type' => 'client_credentials'})
179
+ endpoint = self.rest_endpoint("oauth/token").gsub("v1/", "")
180
+ bearer_response = HTTParty.post(endpoint, :headers => {'Content-Type' => 'application/x-www-form-urlencoded', 'Accept' => 'application/json'}, :body => {'client_id' => client_id, 'client_secret' => URI::encode(client_secret), 'grant_type' => 'client_credentials'})
182
181
  bearer_hash = JSON.parse(bearer_response.body)
183
182
  bearer_token = bearer_hash["access_token"]
184
183
  authorization = "Bearer #{bearer_token}"
185
184
  end
186
185
 
187
186
  if !authorization.blank? && !user_id.blank? && !entity_ids.blank?
188
- endpoint = self.rest_endpoint("genesis/clients")
189
- oauth_response = HTTParty.post(endpoint, :headers => {'authorization' => authorization, 'Content-Type' => 'application/json'}, :body => {'clientId' => new_client_id, 'clientSecret' => new_client_secret, 'userId' => user_id, 'entityIds' => entity_ids, 'customAuthorities' => custom_authorities, 'additionalInformation' => {'description' => info_desc, 'name' => info_name}}.to_json)
187
+ endpoint = self.rest_endpoint("genesis/clients").gsub("v1/", "")
188
+ oauth_response = HTTParty.post(endpoint, :headers => {'authorization' => authorization, 'Content-Type' => 'application/json'}, :body => {'userId' => user_id, 'entityIds' => entity_ids, 'additionalInformation' => {'description' => info_desc, 'name' => info_name}}.to_json)
190
189
  output_json = JSON.parse(oauth_response.body)
191
190
  if oauth_response.code == 201
192
- output_json["clientSecret"] = new_client_secret
193
191
  return output_json
194
192
  elsif oauth_response.code == 401 && !oauth_response.message.blank?
195
193
  raise ZuoraAPI::Exceptions::ZuoraAPIError.new(output_json["message"], {}, oauth_response.code)
@@ -529,6 +527,7 @@ module ZuoraAPI
529
527
  end
530
528
 
531
529
  when :JSON
530
+ body = body.dig("results").present? ? body["results"] : body if body.class == Hash
532
531
  if body.class == Hash && (!body["success"] || !body["Success"] || response.code != 200)
533
532
  messages_array = (body["reasons"] || []).map {|error| error['message']}.compact
534
533
  codes_array = (body["reasons"] || []).map {|error| error['code']}.compact
@@ -599,7 +598,7 @@ module ZuoraAPI
599
598
  end
600
599
  end
601
600
 
602
- #Zuora REST Actions error (Create, Update, Delete)
601
+ #Zuora REST Actions error (Create, Update, Delete, Amend)
603
602
  if body.class == Array
604
603
  all_errors = body.select {|obj| !obj['Success'] || !obj['success'] }.map {|obj| obj['Errors'] || obj['errors'] }.compact
605
604
  all_success = body.select {|obj| obj['Success'] || obj['success']}.compact
@@ -863,110 +862,116 @@ module ZuoraAPI
863
862
  end
864
863
 
865
864
  response_save = nil
866
- http.request_get(uri.request_uri, headers) do |response|
867
- response_save = response
868
- status_code = response.code if response
869
-
870
- case response
871
- when Net::HTTPNotFound
872
- Rails.logger.fatal("404 - Not Found")
873
- raise
874
-
875
- when Net::HTTPUnauthorized
876
- if count <= 0
877
- if z_session
878
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
879
- else
880
- raise
865
+ begin
866
+ http.request_get(uri.request_uri, headers) do |response|
867
+ response_save = response
868
+ status_code = response.code if response
869
+
870
+ case response
871
+ when Net::HTTPNotFound
872
+ Rails.logger.fatal("404 - Not Found")
873
+ raise
874
+
875
+ when Net::HTTPUnauthorized
876
+ if count <= 0
877
+ if z_session
878
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new(self.current_error)
879
+ else
880
+ raise
881
+ end
881
882
  end
882
- end
883
- Rails.logger.fatal("Unauthorized: Retry")
884
- self.new_session if z_session
885
- return get_file(:url => url, :headers => headers, :count => count - 1, :z_session => z_session, :tempfile => tempfile, :file_path => file_path, :timeout_retries => timeout_retries, :timeout => timeout)
883
+ Rails.logger.fatal("Unauthorized: Retry")
884
+ self.new_session if z_session
885
+ return get_file(:url => url, :headers => headers, :count => count - 1, :z_session => z_session, :tempfile => tempfile, :file_path => file_path, :timeout_retries => timeout_retries, :timeout => timeout)
886
886
 
887
- when *(CONNECTION_EXCEPTIONS).concat(CONNECTION_READ_EXCEPTIONS)
888
- Rails.logger.fatal("#{response.class} timeout - retry")
889
- return get_file(:url => url, :headers => headers, :count => count, :z_session => z_session, :tempfile => tempfile, :file_path => file_path, :timeout_retries => timeout_retries - 1, :timeout => timeout)
887
+ when Net::HTTPClientError
888
+ raise
890
889
 
891
- when Net::HTTPClientError
892
- raise
890
+ when Net::HTTPOK
891
+ headers = {}
892
+ response.each_header do |k,v|
893
+ headers[k] = v
894
+ end
895
+ Rails.logger.debug("Headers: #{headers.to_s}")
893
896
 
894
- when Net::HTTPOK
895
- headers = {}
896
- response.each_header do |k,v|
897
- headers[k] = v
898
- end
899
- Rails.logger.debug("Headers: #{headers.to_s}")
897
+ if output_file_name.present?
898
+ file_ending ||= output_file_name.end_with?(".csv.zip") ? ".csv.zip" : File.extname(output_file_name)
899
+ filename ||= File.basename(output_file_name, file_ending)
900
+ end
900
901
 
901
- if output_file_name.present?
902
- file_ending ||= output_file_name.end_with?(".csv.zip") ? ".csv.zip" : File.extname(output_file_name)
903
- filename ||= File.basename(output_file_name, file_ending)
904
- end
902
+ size, export_progress = [0, 0]
903
+ encoding, type, full_filename = [nil, nil, nil]
904
+ if response.header["Content-Disposition"].present?
905
+ case response.header["Content-Disposition"]
906
+ when /.*; filename\*=.*/
907
+ full_filename ||= /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[2].strip
908
+ encoding = /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[1].strip
909
+ when /.*; filename=/
910
+ full_filename ||= /.*; filename=(.*)/.match(response.header["Content-Disposition"])[1].strip
911
+ else
912
+ raise "Can't parse Content-Disposition header: #{response.header["Content-Disposition"]}"
913
+ end
914
+ file_ending ||= full_filename.end_with?(".csv.zip") ? ".csv.zip" : File.extname(full_filename)
915
+ filename ||= File.basename(full_filename, file_ending)
916
+ end
905
917
 
906
- size, export_progress = [0, 0]
907
- encoding, type, full_filename = [nil, nil, nil]
908
- if response.header["Content-Disposition"].present?
909
- case response.header["Content-Disposition"]
910
- when /.*; filename\*=.*/
911
- full_filename ||= /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[2].strip
912
- encoding = /.*; filename\*=(.*)''(.*)/.match(response.header["Content-Disposition"])[1].strip
913
- when /.*; filename=/
914
- full_filename ||= /.*; filename=(.*)/.match(response.header["Content-Disposition"])[1].strip
915
- else
916
- raise "Can't parse Content-Disposition header: #{response.header["Content-Disposition"]}"
918
+ #If user supplied a filename use it, else default to content header filename, else default to uri pattern
919
+ file_ending ||= uri.path.end_with?(".csv.zip") ? ".csv.zip" : File.extname(uri.path)
920
+ filename ||= File.basename(uri.path, file_ending)
921
+
922
+ if response.header["Content-Type"].present?
923
+ case response.header["Content-Type"]
924
+ when /.*;charset=.*/
925
+ type = /(.*);charset=(.*)/.match(response.header["Content-Type"])[1]
926
+ encoding = /(.*);charset=(.*)/.match(response.header["Content-Type"])[2]
927
+ else
928
+ type = response.header["Content-Type"]
929
+ encoding ||= 'UTF-8'
930
+ end
917
931
  end
918
- file_ending ||= full_filename.end_with?(".csv.zip") ? ".csv.zip" : File.extname(full_filename)
919
- filename ||= File.basename(full_filename, file_ending)
920
- end
932
+ Rails.logger.info("File: #{filename}#{file_ending} #{encoding} #{type}")
921
933
 
922
- #If user supplied a filename use it, else default to content header filename, else default to uri pattern
923
- file_ending ||= uri.path.end_with?(".csv.zip") ? ".csv.zip" : File.extname(uri.path)
924
- filename ||= File.basename(uri.path, file_ending)
934
+ if response.header["Content-Length"].present?
935
+ export_size = response.header["Content-Length"].to_i
936
+ elsif response.header["ContentLength"].present?
937
+ export_size = response.header["ContentLength"].to_i
938
+ end
925
939
 
926
- if response.header["Content-Type"].present?
927
- case response.header["Content-Type"]
928
- when /.*;charset=.*/
929
- type = /(.*);charset=(.*)/.match(response.header["Content-Type"])[1]
930
- encoding = /(.*);charset=(.*)/.match(response.header["Content-Type"])[2]
940
+ file_prefix = add_timestamp ? "#{filename}_#{Time.now.to_i}" : filename
941
+ if tempfile
942
+ require 'tempfile'
943
+ file_handle = ::Tempfile.new([file_prefix, "#{file_ending}"], file_path)
931
944
  else
932
- type = response.header["Content-Type"]
933
- encoding ||= 'UTF-8'
945
+ file_handle = File.new(file_path.join("#{file_prefix}#{file_ending}"), "w+")
934
946
  end
935
- end
936
- Rails.logger.info("File: #{filename}#{file_ending} #{encoding} #{type}")
937
-
938
- if response.header["Content-Length"].present?
939
- export_size = response.header["Content-Length"].to_i
940
- elsif response.header["ContentLength"].present?
941
- export_size = response.header["ContentLength"].to_i
942
- end
943
-
944
- file_prefix = add_timestamp ? "#{filename}_#{Time.now.to_i}" : filename
945
- if tempfile
946
- require 'tempfile'
947
- file_handle = ::Tempfile.new([file_prefix, "#{file_ending}"], file_path)
948
- else
949
- file_handle = File.new(file_path.join("#{file_prefix}#{file_ending}"), "w+")
950
- end
951
- file_handle.binmode
952
-
953
- response.read_body do |chunk|
954
- file_handle << chunk.force_encoding(encoding)
955
-
956
- if defined?(export_size) && export_size != 0 && export_size.class == Integer
957
- size += chunk.size
958
- new_progress = (size * 100) / export_size
959
- unless new_progress == export_progress
960
- Rails.logger.debug("Login: Export Downloading %s (%3d%%)" % [filename, new_progress])
947
+ file_handle.binmode
948
+
949
+ response.read_body do |chunk|
950
+ file_handle << chunk.force_encoding(encoding)
951
+
952
+ if defined?(export_size) && export_size != 0 && export_size.class == Integer
953
+ size += chunk.size
954
+ new_progress = (size * 100) / export_size
955
+ unless new_progress == export_progress
956
+ Rails.logger.debug("Login: Export Downloading %s (%3d%%)" % [filename, new_progress])
957
+ end
958
+ export_progress = new_progress
961
959
  end
962
- export_progress = new_progress
963
960
  end
964
- end
965
961
 
966
- file_handle.close
967
- Rails.logger.debug("Filepath: #{file_handle.path} Size: #{File.size(file_handle.path).to_f/1000000} mb")
962
+ file_handle.close
963
+ Rails.logger.debug("Filepath: #{file_handle.path} Size: #{File.size(file_handle.path).to_f/1000000} mb")
968
964
 
969
- return file_handle
965
+ return file_handle
966
+ end
967
+ end
968
+ rescue *(CONNECTION_EXCEPTIONS).concat(CONNECTION_READ_EXCEPTIONS) => e
969
+ sleep(5)
970
+ if (timeout_retries -= 1) >= 0
971
+ Rails.logger.warn("Download Failed: #{e.class} : #{e.message}")
972
+ retry
973
+ else
974
+ raise
970
975
  end
971
976
  end
972
977
  rescue Exception => e
@@ -27,11 +27,11 @@ module ZuoraAPI
27
27
 
28
28
  input_xml = Nokogiri::XML(request.to_xml(:save_with => XML_SAVE_OPTIONS).strip)
29
29
  input_xml.xpath('//ns1:session', 'ns1' =>'http://api.zuora.com/').children.remove
30
- Rails.logger.debug('Connect') {"Request SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
30
+ Rails.logger.debug('Connect') {"Request Code: #{@response_query.code} SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
31
31
 
32
32
  @response_query = HTTParty.post(self.url,:body => request.to_xml(:save_with => XML_SAVE_OPTIONS).strip, :headers => {'Content-Type' => "text/xml; charset=utf-8"}, :timeout => 10)
33
33
  @output_xml = Nokogiri::XML(@response_query.body)
34
- Rails.logger.debug('Connect') {"Response SOAP XML: #{@output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
34
+ Rails.logger.debug('Connect') {"Response Code: #{@response_query.code} SOAP XML: #{@output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
35
35
 
36
36
  if !@response_query.success?
37
37
  self.current_session = nil
@@ -88,6 +88,7 @@ module ZuoraAPI
88
88
  #Username & password combo
89
89
  retrieved_session = @output_xml.xpath('//ns1:Session', 'ns1' =>'http://api.zuora.com/').text
90
90
  raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("No session found for api call.") if retrieved_session.blank?
91
+ self.status = 'Active'
91
92
  self.current_session = retrieved_session
92
93
  end
93
94
  return self.status
@@ -101,6 +102,12 @@ module ZuoraAPI
101
102
  self.status = 'Timeout'
102
103
  return self.status
103
104
  end
105
+ rescue EOFError
106
+ if self.url.match?(/.*services\d{1,}.zuora.com*/)
107
+ self.current_error = "Services tenant '#{self.url.scan(/.*\/\/(services\d{1,}).zuora.com*/).last.first}' is no longer available."
108
+ self.status = 'Not Available'
109
+ return self.status
110
+ end
104
111
  end
105
112
  end
106
113
  end
@@ -1,3 +1,3 @@
1
1
  module ZuoraAPI
2
- VERSION = "1.6.25"
2
+ VERSION = "1.6.26"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zuora_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.25
4
+ version: 1.6.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zuora Strategic Solutions Group
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-07 00:00:00.000000000 Z
11
+ date: 2019-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler