zuora_api 1.6.25 → 1.6.26
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -6
- data/Gemfile.lock +2 -2
- data/lib/zuora_api/login.rb +104 -99
- data/lib/zuora_api/logins/basic.rb +9 -2
- data/lib/zuora_api/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e86b5da627b9f51c342da05d5e4110e3385a35a4
|
4
|
+
data.tar.gz: 9ccf40e8d6dfca789d16207421dc07352ad8c921
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
45
|
+
i18n (1.6.0)
|
46
46
|
concurrent-ruby (~> 1.0)
|
47
47
|
json (2.1.0)
|
48
48
|
loofah (2.2.3)
|
data/lib/zuora_api/login.rb
CHANGED
@@ -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
|
160
|
-
# 2. Pass in user_id, entity_ids, client_id
|
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 (
|
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
|
-
|
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 => {'
|
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
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
if
|
878
|
-
|
879
|
-
|
880
|
-
|
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
|
-
|
883
|
-
|
884
|
-
|
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
|
-
|
888
|
-
|
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
|
-
|
892
|
-
|
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
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
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
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
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
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
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
|
-
|
919
|
-
filename ||= File.basename(full_filename, file_ending)
|
920
|
-
end
|
932
|
+
Rails.logger.info("File: #{filename}#{file_ending} #{encoding} #{type}")
|
921
933
|
|
922
|
-
|
923
|
-
|
924
|
-
|
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
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
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
|
-
|
933
|
-
encoding ||= 'UTF-8'
|
945
|
+
file_handle = File.new(file_path.join("#{file_prefix}#{file_ending}"), "w+")
|
934
946
|
end
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
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
|
-
|
967
|
-
|
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
|
-
|
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
|
data/lib/zuora_api/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2019-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|