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 +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
|