zuora_api 1.7.06 → 1.7.7a

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,105 +9,23 @@ module ZuoraAPI
9
9
  super
10
10
  end
11
11
 
12
- def new_session(auth_type: :basic, debug: false)
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?)
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?)
15
16
 
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
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?
26
22
  end
27
23
  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
- 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)
35
- output_xml = Nokogiri::XML(response_query.body)
36
- Rails.logger.debug('Connect') {"Response Code: #{response_query.code} SOAP XML: #{output_xml.to_xml(:save_with => XML_SAVE_OPTIONS).strip}"} if debug
37
-
38
- if !response_query.success?
39
- self.current_session = nil
40
- if output_xml.namespaces.size > 0 && output_xml.xpath('//soapenv:Fault').size > 0
41
- self.current_error = output_xml.xpath('//fns:FaultMessage', 'fns' =>'http://fault.api.zuora.com/').text
42
- if self.current_error.include?('deactivated')
43
- self.status = 'Deactivated'
44
- self.current_error = 'Deactivated user login, please check with Zuora tenant administrator'
45
- self.errors[:username] = self.current_error
46
- elsif self.current_error.include?('inactive')
47
- self.status = 'Inactive'
48
- self.current_error = 'Inactive user login, please check with Zuora tenant administrator'
49
- self.errors[:username] = self.current_error
50
- elsif self.current_error.include?("invalid username or password") || self.current_error.include?("Invalid login. User name and password do not match.")
51
- self.status = 'Invalid Login'
52
- self.current_error = 'Invalid login, please check username and password or URL endpoint'
53
- self.errors[:username] = self.current_error
54
- self.errors[:password] = self.current_error
55
- elsif self.current_error.include?('unsupported version')
56
- self.status = 'Unsupported API Version'
57
- self.current_error = 'Unsupported API version, please verify URL endpoint'
58
- self.errors[:url] = self.current_error
59
- elsif self.current_error.include?('invalid api version')
60
- self.status = 'Invalid API Version'
61
- self.current_error = 'Invalid API version, please verify URL endpoint'
62
- self.errors[:url] = self.current_error
63
- elsif self.current_error.include?('invalid session')
64
- self.status = 'Invalid Session'
65
- self.current_error = 'Session invalid, please update session and verify URL endpoint'
66
- self.errors[:session] = self.current_error
67
- elsif self.current_error.include?('Your IP address')
68
- self.status = 'Restricted IP'
69
- self.current_error = 'IP restricted, contact Zuora tenant administrator and remove IP restriction'
70
- self.errors[:base] = self.current_error
71
- elsif self.current_error.include?('This account has been locked')
72
- self.status = 'Locked'
73
- self.current_error = 'Locked user login, please wait or navigate to Zuora to unlock user'
74
- self.errors[:username] = self.current_error
75
- elsif self.current_error.include?('Entity not exist:')
76
- self.status = 'Entity Missing'
77
- self.errors[:base] = self.current_error
78
- else
79
- self.status = 'Unknown'
80
- self.current_error = output_xml.xpath('//faultstring').text if self.current_error.blank?
81
- self.errors[:base] = self.current_error
82
- end
83
24
 
84
- else
85
- self.status = 'Unknown'
86
- self.current_error = output_xml.xpath('//faultstring').text if self.current_error.blank?
87
- self.errors[:base] = self.current_error
88
- end
89
- else
90
- #Username & password combo
91
25
  retrieved_session = output_xml.xpath('//ns1:Session', 'ns1' =>'http://api.zuora.com/').text
92
- raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("No session found for api call.", response_query) if retrieved_session.blank?
93
- self.status = 'Active'
26
+ raise ZuoraAPI::Exceptions::ZuoraAPISessionError.new("No session found for api call.", response) if retrieved_session.blank?
94
27
  self.current_session = retrieved_session
95
- end
96
- return self.status
97
- rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
98
- if !(tries -= 1).zero?
99
- Rails.logger.info {"#{ex.class} Timed out will retry after 5 seconds"}
100
- sleep(self.timeout_sleep)
101
- retry
102
- else
103
- self.current_error = "Request timed out. Try again"
104
- self.status = 'Timeout'
105
- return self.status
106
- end
107
- rescue EOFError
108
- if self.url.match?(/.*services\d{1,}.zuora.com*/)
109
- self.current_error = "Services tenant '#{self.url.scan(/.*\/\/(services\d{1,}).zuora.com*/).last.first}' is no longer available."
110
- self.status = 'Not Available'
28
+ self.status = 'Active'
111
29
  return self.status
112
30
  end
113
31
  end
@@ -1,6 +1,6 @@
1
1
  module ZuoraAPI
2
2
  class Oauth < Login
3
- attr_accessor :oauth_client_id, :oauth_secret, :bearer_token, :oauth_session_expires_at
3
+ attr_accessor :oauth_client_id, :oauth_secret, :bearer_token, :oauth_session_expires_at, :scope_entities
4
4
 
5
5
  def initialize(oauth_client_id: nil, oauth_secret: nil, bearer_token: nil, oauth_session_expires_at: nil, **keyword_args)
6
6
  self.oauth_client_id = oauth_client_id
@@ -11,17 +11,19 @@ module ZuoraAPI
11
11
  super
12
12
  end
13
13
 
14
- def new_session(raise_errors: false, auth_type: nil)
15
- if auth_type == :bearer
16
- get_bearer_token()
17
- elsif auth_type == :basic
18
- get_bearer_token() if self.oauth_expired?
19
- get_z_session() if self.status == 'Active'
20
- else
21
- get_bearer_token()
22
- get_z_session() if self.status == 'Active'
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
23
26
  end
24
- return self.status
25
27
  end
26
28
 
27
29
  def get_active_bearer_token
@@ -29,85 +31,45 @@ module ZuoraAPI
29
31
  return self.bearer_token
30
32
  end
31
33
 
32
- def get_z_session(debug: false)
33
- tries ||= 2
34
- headers = self.entity_id.present? ? {"Zuora-Entity-Ids" => self.entity_id } : {}
34
+ def get_z_session(debug: false, zuora_track_id: nil)
35
+ headers = self.entity_id.present? ? {"Zuora-Entity-Ids" => self.entity_id } : {}
36
+ headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
35
37
  output_json, response = self.rest_call(:url => self.rest_endpoint("connections"), :session_type => :bearer, :headers => headers)
36
- self.current_session = response.headers.to_h['set-cookie'][0].split(';')[0].split('=',2)[1].gsub('%3D', '=')
37
- rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
38
- if !(tries -= 1).zero?
39
- Rails.logger.debug {"Session Invalid"}
40
- self.new_session(auth_type: :bearer)
41
- retry
42
- else
43
- if errors.include?(ex.class)
44
- raise ex
45
- else
46
- return [output_json, response]
47
- end
48
- end
49
- rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
50
- if errors.include?(ex.class)
51
- raise ex
52
- else
53
- return [output_json, response]
54
- end
55
- rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
56
- if !(tries -= 1).zero?
57
- Rails.logger.info {"#{ex.class} Timed out will retry after 5 seconds"}
58
- sleep(self.timeout_sleep)
59
- retry
60
- else
61
- self.current_error = "Request timed out. Try again"
62
- self.status = 'Timeout'
63
- return self.status
64
- end
38
+ begin
39
+ self.current_session = response.headers.to_h['set-cookie'][0].split(';')[0].split('=',2)[1].gsub('%3D', '=')
40
+ 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)
49
+ end
65
50
  end
66
51
 
67
- def get_bearer_token
68
- tries ||= 2
52
+ def get_bearer_token(zuora_track_id: nil)
69
53
  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?
70
54
 
55
+ headers = { "content-type" => "application/x-www-form-urlencoded" }
56
+ headers['Zuora-Track-Id'] = zuora_track_id if zuora_track_id.present?
57
+
71
58
  output_json, response = self.rest_call(:method => :post,
72
- :url => self.rest_endpoint.chomp('v1/').concat("oauth/token"),
73
- :z_session => false,
74
- :session_type => :bearer,
75
- :headers => {"content-type" => "application/x-www-form-urlencoded"},
76
- :body => {"client_id"=> self.oauth_client_id, "client_secret"=>self.oauth_secret, "grant_type" =>"client_credentials"}
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"}
77
64
  )
78
65
 
79
66
  self.bearer_token = output_json["access_token"]
67
+ self.scope_entities = output_json.fetch('scope', '').split(" ").map { |scope| scope.split('.').last.gsub('-', '') if scope.include?('entity.') }.compact.uniq
80
68
  self.oauth_session_expires_at = Time.now.to_i + output_json["expires_in"].to_i
81
69
  self.current_error = nil
82
70
  self.status = 'Active'
83
71
 
84
72
  return self.status
85
- rescue ZuoraAPI::Exceptions::ZuoraAPISessionError => ex
86
- self.bearer_token = nil
87
- self.oauth_session_expires_at = nil
88
- self.current_error = ex.message
89
- case ex.message
90
- when "Forbidden"
91
- self.current_error = "The user associated to OAuth credential, '#{self.oauth_client_id}', set has been deactivated."
92
- self.status = 'Deactivated'
93
- else
94
- self.current_error = "Invalid login, please check client ID and Client Secret or URL endpoint"
95
- self.status = 'Invalid Login'
96
- end
97
-
98
- return self.status
99
- rescue ZuoraAPI::Exceptions::ZuoraAPIError, ZuoraAPI::Exceptions::ZuoraAPIRequestLimit, ZuoraAPI::Exceptions::ZuoraAPILockCompetition => ex
100
- raise ex
101
- rescue *(CONNECTION_EXCEPTIONS + CONNECTION_READ_EXCEPTIONS) => ex
102
- if !(tries -= 1).zero?
103
- Rails.logger.info {"#{ex.class} Timed out will retry after 5 seconds"}
104
- sleep(self.timeout_sleep)
105
- retry
106
- else
107
- self.current_error = "Invalid login, please check client ID and Client Secret or URL endpoint"
108
- self.status = 'Timeout'
109
- return self.status
110
- end
111
73
  end
112
74
 
113
75
  def oauth_expired?
@@ -1,3 +1,3 @@
1
1
  module ZuoraAPI
2
- VERSION = "1.7.06"
2
+ VERSION = "1.7.7a"
3
3
  end
@@ -18,11 +18,12 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.12"
21
+ spec.add_development_dependency "bundler"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency "rspec", "~> 3.0"
24
24
  spec.add_development_dependency("webmock")
25
- spec.add_development_dependency("simplecov")
25
+ spec.add_development_dependency("simplecov", "~> 0.18.5")
26
+ spec.add_dependency("ougai")
26
27
  spec.add_dependency("nokogiri")
27
28
  spec.add_dependency("httparty")
28
29
  spec.add_dependency("rubyzip")
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.06
4
+ version: 1.7.7a
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-08-25 00:00:00.000000000 Z
11
+ date: 2020-08-26 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: '1.12'
19
+ version: '0'
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: '1.12'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -68,12 +68,26 @@ 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
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
74
88
  - !ruby/object:Gem::Version
75
89
  version: '0'
76
- type: :development
90
+ type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
@@ -182,11 +196,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
182
196
  version: '0'
183
197
  required_rubygems_version: !ruby/object:Gem::Requirement
184
198
  requirements:
185
- - - ">="
199
+ - - ">"
186
200
  - !ruby/object:Gem::Version
187
- version: '0'
201
+ version: 1.3.1
188
202
  requirements: []
189
- rubygems_version: 3.0.3
203
+ rubygems_version: 3.1.2
190
204
  signing_key:
191
205
  specification_version: 4
192
206
  summary: Gem that provides easy integration to Zuora