zuora_api 1.7.81 → 1.8.00

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,22 +10,113 @@ module ZuoraAPI
10
10
  end
11
11
 
12
12
  def new_session(auth_type: :basic, debug: false, zuora_track_id: nil)
13
- super do
14
- raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Basic Login, does not support Authentication of Type: #{auth_type}") if auth_type != :basic
15
- raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Request Basic Login but either 'Username' or 'Password' were not passed.") if (self.password.blank? && self.username.blank?)
13
+ raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Basic Login, does not support Authentication of Type: #{auth_type}") if auth_type != :basic
14
+ raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Request Basic Login but either 'Username' or 'Password' were not passed.") if (self.password.blank? && self.username.blank?)
16
15
 
17
- output_xml, input_xml, response = soap_call(timeout_retry: true, skip_session: true, zuora_track_id: zuora_track_id) do |xml|
18
- xml['api'].login do
19
- xml['api'].username self.username
20
- xml['api'].password self.password
21
- xml['api'].entityId self.entity_id if !self.entity_id.blank?
16
+ tries ||= 2
17
+ request = Nokogiri::XML::Builder.new do |xml|
18
+ xml['SOAP-ENV'].Envelope('xmlns:SOAP-ENV' =>"http://schemas.xmlsoap.org/soap/envelope/", 'xmlns:api' => "http://api.zuora.com/" ) do
19
+ xml['SOAP-ENV'].Header
20
+ xml['SOAP-ENV'].Body do
21
+ xml['api'].login do
22
+ xml['api'].username self.username
23
+ xml['api'].password self.password
24
+ xml['api'].entityId self.entity_id if !self.entity_id.blank?
25
+ end
22
26
  end
23
27
  end
28
+ end
29
+
30
+ input_xml = Nokogiri::XML(request.to_xml(:save_with => XML_SAVE_OPTIONS).strip)
31
+ input_xml.xpath('//ns1:session', 'ns1' =>'http://api.zuora.com/').children.remove
32
+ Rails.logger.debug('Connect') {"SOAP XML: #{input_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
33
+
34
+ headers = { 'Content-Type' => "text/xml; charset=utf-8" }
35
+ headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
24
36
 
37
+ response_query = HTTParty.post(self.url,:body => request.to_xml(:save_with => XML_SAVE_OPTIONS).strip, :headers => headers, :timeout => 10)
38
+ output_xml = Nokogiri::XML(response_query.body)
39
+ Rails.logger.debug('Connect') {"Response Code: #{response_query.code} SOAP XML: #{output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
40
+
41
+ if !response_query.success?
42
+ self.current_session = nil
43
+ if output_xml.namespaces.size > 0 && output_xml.xpath('//soapenv:Fault').size > 0
44
+ self.current_error = output_xml.xpath('//fns:FaultMessage', 'fns' =>'http://fault.api.zuora.com/').text
45
+ if self.current_error.include?('deactivated')
46
+ self.status = 'Deactivated'
47
+ self.current_error = 'Deactivated user login, please check with Zuora tenant administrator'
48
+ self.errors[:username] = self.current_error
49
+ elsif self.current_error.include?('inactive')
50
+ self.status = 'Inactive'
51
+ self.current_error = 'Inactive user login, please check with Zuora tenant administrator'
52
+ self.errors[:username] = self.current_error
53
+ elsif self.current_error.include?("invalid username or password") || self.current_error.include?("Invalid login. User name and password do not match.")
54
+ self.status = 'Invalid Login'
55
+ self.current_error = 'Invalid login, please check username and password or URL endpoint'
56
+ self.errors[:username] = self.current_error
57
+ self.errors[:password] = self.current_error
58
+ elsif self.current_error.include?('unsupported version')
59
+ self.status = 'Unsupported API Version'
60
+ self.current_error = 'Unsupported API version, please verify URL endpoint'
61
+ self.errors[:url] = self.current_error
62
+ elsif self.current_error.include?('invalid api version')
63
+ self.status = 'Invalid API Version'
64
+ self.current_error = 'Invalid API version, please verify URL endpoint'
65
+ self.errors[:url] = self.current_error
66
+ elsif self.current_error.include?('invalid session')
67
+ self.status = 'Invalid Session'
68
+ self.current_error = 'Session invalid, please update session and verify URL endpoint'
69
+ self.errors[:session] = self.current_error
70
+ elsif self.current_error.include?('Your IP address')
71
+ self.status = 'Restricted IP'
72
+ self.current_error = 'IP restricted, contact Zuora tenant administrator and remove IP restriction'
73
+ self.errors[:base] = self.current_error
74
+ elsif self.current_error.include?('This account has been locked')
75
+ self.status = 'Locked'
76
+ self.current_error = 'Locked user login, please wait or navigate to Zuora to unlock user'
77
+ self.errors[:username] = self.current_error
78
+ elsif self.current_error.include?('Entity not exist:')
79
+ self.status = 'Entity Missing'
80
+ self.errors[:base] = self.current_error
81
+ else
82
+ self.status = 'Unknown'
83
+ self.current_error = output_xml.xpath('//faultstring').text if self.current_error.blank?
84
+ self.errors[:base] = self.current_error
85
+ end
86
+
87
+ else
88
+ self.status = 'Unknown'
89
+ self.current_error = output_xml.xpath('//faultstring').text if self.current_error.blank?
90
+ self.errors[:base] = self.current_error
91
+ end
92
+ else
93
+ #Username & password combo
25
94
  retrieved_session = output_xml.xpath('//ns1:Session', 'ns1' =>'http://api.zuora.com/').text
26
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("No session found for api call.", response) if retrieved_session.blank?
27
- self.current_session = retrieved_session
95
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("No session found for api call.", response_query) if retrieved_session.blank?
28
96
  self.status = 'Active'
97
+ self.current_session = retrieved_session
98
+ end
99
+ return self.status
100
+ rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
101
+ if !tries.zero?
102
+ tries -= 1
103
+ sleep(self.timeout_sleep)
104
+ retry
105
+ else
106
+ if Rails.logger.class.to_s == "Ougai::Logger"
107
+ Rails.logger.error("BasicLogin - Timed out", ex)
108
+ else
109
+ Rails.logger.error("BasicLogin - #{ex.class} Timed out")
110
+ end
111
+
112
+ self.current_error = "Request timed out. Try again"
113
+ self.status = 'Timeout'
114
+ return self.status
115
+ end
116
+ rescue EOFError
117
+ if self.url.match?(/.*services\d{1,}.zuora.com*/)
118
+ self.current_error = "Services tenant '#{self.url.scan(/.*\/\/(services\d{1,}).zuora.com*/).last.first}' is no longer available."
119
+ self.status = 'Not Available'
29
120
  return self.status
30
121
  end
31
122
  end
@@ -12,18 +12,16 @@ module ZuoraAPI
12
12
  end
13
13
 
14
14
  def new_session(auth_type: nil, zuora_track_id: nil)
15
- super do
16
- if auth_type == :bearer
17
- get_bearer_token(zuora_track_id: zuora_track_id)
18
- elsif auth_type == :basic
19
- get_bearer_token(zuora_track_id: zuora_track_id) if self.oauth_expired?
20
- get_z_session(zuora_track_id: zuora_track_id)
21
- else
22
- get_bearer_token(zuora_track_id: zuora_track_id) if self.oauth_expired?
23
- get_z_session(zuora_track_id: zuora_track_id)
24
- end
25
- return self.status
15
+ if auth_type == :bearer
16
+ get_bearer_token(zuora_track_id: zuora_track_id)
17
+ elsif auth_type == :basic
18
+ get_bearer_token(zuora_track_id: zuora_track_id) if self.oauth_expired?
19
+ get_z_session(zuora_track_id: zuora_track_id) if self.status == 'Active'
20
+ else
21
+ get_bearer_token(zuora_track_id: zuora_track_id)
22
+ get_z_session(zuora_track_id: zuora_track_id) if self.status == 'Active'
26
23
  end
24
+ return self.status
27
25
  end
28
26
 
29
27
  def get_active_bearer_token
@@ -32,35 +30,59 @@ module ZuoraAPI
32
30
  end
33
31
 
34
32
  def get_z_session(debug: false, zuora_track_id: nil)
33
+ tries ||= 2
35
34
  headers = self.entity_id.present? ? {"Zuora-Entity-Ids" => self.entity_id } : {}
36
35
  headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
37
36
  output_json, response = self.rest_call(:url => self.rest_endpoint("connections"), :session_type => :bearer, :headers => headers)
38
37
  begin
39
38
  self.current_session = response.headers.to_h['set-cookie'][0].split(';')[0].split('=',2)[1].gsub('%3D', '=')
40
39
  rescue NoMethodError => ex
41
- Rails.logger.fatal("Failure Parsing Cookie Headers", {
42
- response: {
43
- status: response.code,
44
- params: response.body.to_s,
45
- headers: response.headers.to_s,
46
- }
47
- })
48
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("Failure Parsing Cookie Headers", response)
40
+ Rails.logger.fatal("Failure Parsing Cookie Headers", response.headers.to_s)
41
+ raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Failure Parsing Cookie Headers")
49
42
  end
43
+ rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
44
+ if !tries.zero?
45
+ tries -= 1
46
+ Rails.logger.debug {"Session Invalid"}
47
+ self.new_session(auth_type: :bearer)
48
+ retry
49
+ end
50
+ raise ex if errors.include?(ex.class)
51
+ return [output_json, response]
52
+
53
+ rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
54
+ raise ex if errors.include?(ex.class)
55
+ return [output_json, response]
56
+
57
+ rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
58
+ if !tries.zero?
59
+ tries -= 1
60
+ sleep(self.timeout_sleep)
61
+ retry
62
+ end
63
+ if Rails.logger.class.to_s == "Ougai::Logger"
64
+ Rails.logger.error("OAuthLogin - Timed out", ex)
65
+ else
66
+ Rails.logger.error("OAuthLogin - #{ex.class} Timed out")
67
+ end
68
+ self.current_error = "Request timed out. Try again"
69
+ self.status = 'Timeout'
70
+ return self.status
50
71
  end
51
72
 
52
73
  def get_bearer_token(zuora_track_id: nil)
74
+ tries ||= 2
53
75
  raise ZuoraAPI::Exceptions::ZuoraAPIAuthenticationTypeError.new("Request Oauth Login but either 'Oauth Client Id' or 'Oauth Secret' were not passed") if self.oauth_client_id.blank? || self.oauth_secret.blank?
54
76
 
55
77
  headers = { "content-type" => "application/x-www-form-urlencoded" }
56
78
  headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
57
79
 
58
80
  output_json, response = self.rest_call(:method => :post,
59
- url: self.rest_endpoint.chomp('v1/').concat("oauth/token"),
60
- z_session: false,
61
- timeout_retry: true,
62
- headers: headers,
63
- body: {"client_id"=> self.oauth_client_id, "client_secret"=>self.oauth_secret, "grant_type" =>"client_credentials"}
81
+ :url => self.rest_endpoint.chomp('v1/').concat("oauth/token"),
82
+ :z_session => false,
83
+ :session_type => :bearer,
84
+ :headers => headers,
85
+ :body => {"client_id"=> self.oauth_client_id, "client_secret"=>self.oauth_secret, "grant_type" =>"client_credentials"}
64
86
  )
65
87
 
66
88
  self.bearer_token = output_json["access_token"]
@@ -70,6 +92,44 @@ module ZuoraAPI
70
92
  self.status = 'Active'
71
93
 
72
94
  return self.status
95
+
96
+ rescue ZuoraAPI::Exceptions::ZuoraAPIInternalServerError => ex
97
+ raise ex if tries.zero?
98
+
99
+ tries -= 1
100
+ sleep(self.timeout_sleep)
101
+ retry
102
+ rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
103
+ self.bearer_token = nil
104
+ self.oauth_session_expires_at = nil
105
+ self.current_error = ex.message
106
+ case ex.message
107
+ when "Forbidden"
108
+ self.current_error = "The user associated to OAuth credential set has been deactivated."
109
+ self.status = 'Deactivated'
110
+ else
111
+ self.current_error = "Invalid login, please check client ID and Client Secret or URL endpoint"
112
+ self.status = 'Invalid Login'
113
+ end
114
+
115
+ return self.status
116
+ rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
117
+ raise ex
118
+ rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
119
+ if !tries.zero?
120
+ tries -= 1
121
+ sleep(self.timeout_sleep)
122
+ retry
123
+ else
124
+ if Rails.logger.class.to_s == "Ougai::Logger"
125
+ Rails.logger.error("OAuthLogin - Timed out will retry after #{self.timeout_sleep} seconds", ex)
126
+ else
127
+ Rails.logger.error("OAuthLogin - #{ex.class} Timed out will retry after #{self.timeout_sleep} seconds")
128
+ end
129
+ self.current_error = "Invalid login, please check client ID and Client Secret or URL endpoint"
130
+ self.status = 'Timeout'
131
+ return self.status
132
+ end
73
133
  end
74
134
 
75
135
  def oauth_expired?
@@ -1,3 +1,3 @@
1
1
  module ZuoraAPI
2
- VERSION = "1.7.81"
2
+ VERSION = "1.8.00"
3
3
  end
data/zuora_api.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'zuora_api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "zuora_api"
8
+ spec.version = ZuoraAPI::VERSION
9
+ spec.authors = ["Zuora Strategic Solutions Group"]
10
+ spec.email = ["connect@zuora.com"]
11
+
12
+ spec.summary = %q{Gem that provides easy integration to Zuora}
13
+ spec.description = %q{Gem that provides easy integration to Zuora}
14
+ spec.homepage = "https://connect.zuora.com"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.12"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
24
+ spec.add_development_dependency("webmock")
25
+ spec.add_development_dependency("simplecov")
26
+ spec.add_dependency("nokogiri")
27
+ spec.add_dependency("httparty")
28
+ spec.add_dependency("rubyzip")
29
+ spec.add_dependency("railties", ">= 4.1.0", "< 6")
30
+ end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zuora_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.81
4
+ version: 1.8.00
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: 2021-03-12 00:00:00.000000000 Z
11
+ date: 2020-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.12'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.12'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -68,26 +68,12 @@ dependencies:
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: simplecov
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 0.18.5
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 0.18.5
83
- - !ruby/object:Gem::Dependency
84
- name: ougai
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - ">="
88
74
  - !ruby/object:Gem::Version
89
75
  version: '0'
90
- type: :runtime
76
+ type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
@@ -145,7 +131,7 @@ dependencies:
145
131
  version: 4.1.0
146
132
  - - "<"
147
133
  - !ruby/object:Gem::Version
148
- version: '6.1'
134
+ version: '6'
149
135
  type: :runtime
150
136
  prerelease: false
151
137
  version_requirements: !ruby/object:Gem::Requirement
@@ -155,7 +141,7 @@ dependencies:
155
141
  version: 4.1.0
156
142
  - - "<"
157
143
  - !ruby/object:Gem::Version
158
- version: '6.1'
144
+ version: '6'
159
145
  description: Gem that provides easy integration to Zuora
160
146
  email:
161
147
  - connect@zuora.com
@@ -163,9 +149,17 @@ executables: []
163
149
  extensions: []
164
150
  extra_rdoc_files: []
165
151
  files:
166
- - MIT-LICENSE
152
+ - ".gitignore"
153
+ - ".gitlab-ci.yml"
154
+ - ".rspec"
155
+ - ".travis.yml"
156
+ - CHANGELOG.md
157
+ - Gemfile
158
+ - Gemfile.lock
167
159
  - README.md
168
160
  - Rakefile
161
+ - bin/console
162
+ - bin/setup
169
163
  - lib/insights_api/login.rb
170
164
  - lib/zuora_api.rb
171
165
  - lib/zuora_api/exceptions.rb
@@ -173,6 +167,7 @@ files:
173
167
  - lib/zuora_api/logins/basic.rb
174
168
  - lib/zuora_api/logins/oauth.rb
175
169
  - lib/zuora_api/version.rb
170
+ - zuora_api.gemspec
176
171
  homepage: https://connect.zuora.com
177
172
  licenses: []
178
173
  metadata: {}
@@ -191,7 +186,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
191
186
  - !ruby/object:Gem::Version
192
187
  version: '0'
193
188
  requirements: []
194
- rubygems_version: 3.1.4
189
+ rubygems_version: 3.0.3
195
190
  signing_key:
196
191
  specification_version: 4
197
192
  summary: Gem that provides easy integration to Zuora
data/MIT-LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright 2021 Zuora, Inc.
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.