zuora_connect 2.0.57 → 2.0.58

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae04188bc84b9fd594f1a2453128a9f7f8d489e9edd9ffd053ef51c09c32b02d
4
- data.tar.gz: 3f19d9ed178c02807f44dbed319f5d2c5b47301de9bdc6666ce5df320cc8c40c
3
+ metadata.gz: 1b0443ea374a1f1f82e212960a7df80fb9aa953fb4bf0fcb123949e73dfc622d
4
+ data.tar.gz: a356f5120206bf8febbdca0db439c5792dca19156776356f09f5a39da50cf7b1
5
5
  SHA512:
6
- metadata.gz: 9a1249ce65d708fe4bd792c890b49946ce1dea1c1ffba97a98ef397d98e69014e5f24021b700f0b2c980c2ce2292b601fbbb9550110f7e66b4099908ee0467ac
7
- data.tar.gz: d40bdadd5ccbe7e2416f3ab354830f05aadec4c1c5faea71dccf8a87f1df0e012bfe4a49f1ed7f0a6e29c97ac4e3c04d8548ba48094f81d01f30c55c4484753b
6
+ metadata.gz: 34e40410cfcd4752b174d584d2cf883084630b56e7e4d897733da177fa66ece76c9ec3b2556e0ea3778b05eed949c6dba9e4c37f635d178fb9d77f776ec5221f
7
+ data.tar.gz: '08dde90f26d809089f79928c0cfa6d7c43d551b61448b7ce040b0ba05aa64552599ff3e3c49f46feb54340d846565faa75f891730501e2ad1ffe6a8c554856e5'
@@ -4,12 +4,31 @@ window.define = previousDefine;
4
4
  if (isHallway()) {
5
5
  $( document ).ajaxError(function( event, jqxhr, settings, thrownError ) {
6
6
  if ( jqxhr.status === 401) {
7
- window.location.href = '/apps/newlogin.do?retURL=' + window.location.pathname;
7
+ fetch("https://" + window.location.host + "/apps/v1/navigation").then(response => {
8
+ if (response.status === 401) {
9
+ deleteAllCookies();
10
+ window.location.href = '/apps/newlogin.do?retURL=' + window.location.pathname;
11
+ }
12
+ });
8
13
  }
9
14
  });
10
15
  }
11
16
 
12
17
  function isHallway() {
13
- var regex = new RegExp("^/services/");
14
- return window.location.pathname.match(regex);
18
+ var regex = new RegExp("(?<=\\/)services\\/.*");
19
+ if (regex.test(window.location.pathname)) {
20
+ return window.location.pathname.match(regex)[0]
21
+ }
22
+ return null;
23
+ }
24
+
25
+ function deleteAllCookies() {
26
+ var cookies = document.cookie.split(";");
27
+
28
+ for (var i = 0; i < cookies.length; i++) {
29
+ var cookie = cookies[i];
30
+ var eqPos = cookie.indexOf("=");
31
+ var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
32
+ document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
33
+ }
15
34
  }
@@ -20,7 +20,7 @@ module ZuoraConnect
20
20
  BLANK_OBJECT_ID_LOOKUP = 'BlankValueSupplied'
21
21
  HOLDING_PATTERN_SLEEP = 5.seconds
22
22
  CONNECT_APPLICATION_ID = 0
23
- CONNECT_COMMUNICATION_SLEEP= 5.seconds
23
+ CONNECT_COMMUNICATION_SLEEP = Rails.env.test? ? 0.seconds : 5.seconds
24
24
  IGNORED_LOCALS = ['fr', 'ja', 'es', 'zh', 'de']
25
25
  INTERNAL_HOSTS = []
26
26
  LOGIN_TENANT_DESTINATION = 'target_login'
@@ -98,7 +98,9 @@ module ZuoraConnect
98
98
  Redis.current.zrem("InstanceRefreshing", self.id)
99
99
  end
100
100
  if defined?(Resque.redis)
101
- Resque.redis.zrem("PauseQueue", self.id)
101
+ Resque.redis.zrange("PauseQueue", 0, -1).each do |key|
102
+ Resque.redis.zrem("PauseQueue", key) if key.split("__").first.to_i == self.id
103
+ end
102
104
  end
103
105
  return true
104
106
  end
@@ -161,6 +163,7 @@ module ZuoraConnect
161
163
  end
162
164
 
163
165
  self.build_task(task_data: mock_task_data, session: session)
166
+ self.last_refresh = Time.now.to_i
164
167
  else
165
168
  time_expire = (session["#{self.id}::last_refresh"] || Time.now).to_i - INSTANCE_REFRESH_WINDOW.ago.to_i
166
169
 
@@ -202,14 +205,14 @@ module ZuoraConnect
202
205
  else
203
206
  self.new_session_message = "REBUILDING - Expires in #{time_expire} seconds"
204
207
  end
205
- ZuoraConnect.logger.debug(self.new_session_message)
208
+ ZuoraConnect.logger.debug(self.new_session_message, self.default_ougai_items)
206
209
  self.build_task(task_data: session["#{self.id}::task_data"], session: session)
207
210
  end
208
211
  end
209
212
  return self
210
213
  rescue ZuoraConnect::Exceptions::HoldingPattern => ex
211
214
  while self.marked_for_refresh?
212
- ZuoraConnect.logger.info("Holding - Expires in #{self.reset_mark_expires_at}. '#{self.new_session_message}'")
215
+ ZuoraConnect.logger.info("Holding - Expires in #{self.reset_mark_expires_at}. '#{self.new_session_message}'", self.default_ougai_items)
213
216
  sleep(HOLDING_PATTERN_SLEEP)
214
217
  end
215
218
  self.reload_attributes([:refresh_token, :oauth_expires_at, :access_token])
@@ -218,17 +221,17 @@ module ZuoraConnect
218
221
  rescue ZuoraConnect::Exceptions::MissMatch => ex
219
222
  self.delete_app_instance
220
223
  session = {}
221
- ZuoraConnect.logger.error(ex, app_instance_id_new: self.task_data['id'])
224
+ ZuoraConnect.logger.error(ex, self.default_ougai_items.merge({app_instance_id_new: self.task_data['id']}))
222
225
  retry
223
226
  rescue ZuoraConnect::Exceptions::InvalidCredentialSet => ex
224
227
  raise
225
228
  rescue => ex
226
229
  if recoverable_session
227
- ZuoraConnect.logger.warn("REBUILDING - Using backup expired cache", ex)
230
+ ZuoraConnect.logger.warn("REBUILDING - Using backup expired cache", ex, self.default_ougai_items)
228
231
  self.build_task(task_data: session["#{self.id}::task_data"], session: session)
229
232
  return self
230
233
  else
231
- ZuoraConnect.logger.error("Failed new session", ex)
234
+ ZuoraConnect.logger.error("Failed new session", ex, self.default_ougai_items)
232
235
  raise
233
236
  end
234
237
  ensure
@@ -276,11 +279,8 @@ module ZuoraConnect
276
279
  #Check how app was deployed
277
280
  if self.id < 25000000 && !skip_connect
278
281
  self.check_oauth_state
279
- start = Time.now
280
282
  response = HTTParty.get(ZuoraConnect.configuration.url + "/api/#{self.api_version}/tools/tasks/#{self.id}.json",:body => {:access_token => self.access_token})
281
- response_time = Time.now - start
282
283
 
283
- ZuoraConnect.logger.debug("REFRESH TASK - Connect Task Info Request Time #{response_time.round(2).to_s}")
284
284
  if response.code == 200
285
285
  begin
286
286
  parsed_json = JSON.parse(response.body)
@@ -312,7 +312,7 @@ module ZuoraConnect
312
312
  refresh_count += 1
313
313
  if refresh_count < 3
314
314
  sleep(10)
315
- ZuoraConnect.logger.debug("REFRESH TASK - Connection Failure Retrying(#{refresh_count})", ex)
315
+ ZuoraConnect.logger.debug("REFRESH TASK - Connection Failure Retrying(#{refresh_count})", ex, self.default_ougai_items)
316
316
  retry
317
317
  else
318
318
  ZuoraConnect.logger.fatal("REFRESH TASK - Connection Failed", ex)
@@ -321,17 +321,17 @@ module ZuoraConnect
321
321
  rescue ZuoraConnect::Exceptions::ConnectCommunicationError => ex
322
322
  refresh_count += 1
323
323
  if refresh_count < 3
324
- ZuoraConnect.logger.debug("REFRESH TASK - Communication Failure Retrying(#{refresh_count})", ex)
324
+ ZuoraConnect.logger.debug("REFRESH TASK - Communication Failure Retrying(#{refresh_count})", ex, self.default_ougai_items)
325
325
  self.refresh_oauth if ex.code == 401
326
326
  retry
327
327
  else
328
- ZuoraConnect.logger.fatal("REFRESH TASK - Communication Failed #{ex.code}", ex)
328
+ ZuoraConnect.logger.fatal("REFRESH TASK - Communication Failed #{ex.code}", ex, self.default_ougai_items)
329
329
  raise
330
330
  end
331
331
  end
332
332
  rescue => ex
333
333
  if self['zuora_logins'].present?
334
- ZuoraConnect.logger.warn("REFRESH TASK - Fallback to local encrypted store", ex)
334
+ ZuoraConnect.logger.warn("REFRESH TASK - Fallback to local encrypted store", ex, self.default_ougai_items)
335
335
  skip_connect = true
336
336
  retry
337
337
  end
@@ -653,16 +653,12 @@ module ZuoraConnect
653
653
  end
654
654
 
655
655
  def refresh_oauth
656
- refresh_oauth_count ||= 0
657
- start = Time.now
658
- params = {
659
- :grant_type => "refresh_token",
660
- :redirect_uri => ZuoraConnect.configuration.oauth_client_redirect_uri,
661
- :refresh_token => self.refresh_token
662
- }
663
- response = HTTParty.post("#{ZuoraConnect.configuration.url}/oauth/token",:body => params)
664
- response_time = Time.now - start
665
- ZuoraConnect.logger.debug("REFRESH OAUTH - In #{response_time.round(2).to_s}")
656
+ refresh_oauth_count ||= 0
657
+ response = HTTParty.post("#{ZuoraConnect.configuration.url}/oauth/token", body: {
658
+ :grant_type => "refresh_token",
659
+ :redirect_uri => ZuoraConnect.configuration.oauth_client_redirect_uri,
660
+ :refresh_token => self.refresh_token
661
+ })
666
662
 
667
663
  if response.code == 200
668
664
  response_body = JSON.parse(response.body)
@@ -676,11 +672,11 @@ module ZuoraConnect
676
672
  end
677
673
  rescue *(ZuoraAPI::Login::CONNECTION_EXCEPTIONS + ZuoraAPI::Login::CONNECTION_READ_EXCEPTIONS) => ex
678
674
  if (refresh_oauth_count += 1) < 3
679
- sleep(5)
680
- ZuoraConnect.logger.debug("REFRESH OAUTH - Connection Failure Retrying(#{refresh_oauth_count})", ex)
675
+ sleep(CONNECT_COMMUNICATION_SLEEP)
676
+ ZuoraConnect.logger.debug("REFRESH OAUTH - Connection Failure Retrying(#{refresh_oauth_count})", ex, self.default_ougai_items)
681
677
  retry
682
678
  else
683
- ZuoraConnect.logger.fatal("REFRESH OAUTH - Connection Failed", ex)
679
+ Rails.logger.fatal("REFRESH OAUTH - Connection Failed", ex, self.default_ougai_items)
684
680
  raise
685
681
  end
686
682
  rescue ZuoraConnect::Exceptions::ConnectCommunicationError => ex
@@ -691,10 +687,10 @@ module ZuoraConnect
691
687
  return if !self.oauth_expired?
692
688
 
693
689
  if (refresh_oauth_count += 1) < 3
694
- ZuoraConnect.logger.debug("REFRESH OAUTH - Communication Failure Retrying(#{refresh_oauth_count})", ex)
690
+ ZuoraConnect.logger.debug("REFRESH OAUTH - Communication Failure Retrying(#{refresh_oauth_count})", ex, self.default_ougai_items)
695
691
  retry
696
692
  else
697
- ZuoraConnect.logger.fatal("REFRESH OAUTH - Communication Failed #{ex.code}", ex)
693
+ ZuoraConnect.logger.fatal("REFRESH OAUTH - Communication Failed #{ex.code}", ex, self.default_ougai_items)
698
694
  raise
699
695
  end
700
696
  end
@@ -744,10 +740,10 @@ module ZuoraConnect
744
740
  end
745
741
  end
746
742
  if cached_instance.blank?
747
- ZuoraConnect.logger.debug("Cached AppInstance Missing")
743
+ ZuoraConnect.logger.debug("Cached AppInstance Missing", self.default_ougai_items)
748
744
  return session
749
745
  else
750
- ZuoraConnect.logger.debug("Cached AppInstance Found")
746
+ ZuoraConnect.logger.debug("Cached AppInstance Found", self.default_ougai_items)
751
747
  return decrypt_data(data: cached_instance, rescue_return: session).merge(session)
752
748
  end
753
749
  else
@@ -763,7 +759,7 @@ module ZuoraConnect
763
759
  if defined?(Redis.current)
764
760
  #Task data must be present and the last refresh cannot be old. We dont want to overwite new cache data with old
765
761
  if self.task_data.present? && (self.last_refresh.to_i > INSTANCE_REFRESH_WINDOW.ago.to_i)
766
- ZuoraConnect.logger.debug("Caching AppInstance")
762
+ ZuoraConnect.logger.debug("Caching AppInstance", self.default_ougai_items)
767
763
  Redis.current.setex("AppInstance:#{self.id}", INSTANCE_REDIS_CACHE_PERIOD.to_i, self.encrypt_data(data: self.save_data))
768
764
  end
769
765
  end
@@ -827,10 +823,10 @@ module ZuoraConnect
827
823
  begin
828
824
  return JSON.parse(encryptor.decrypt_and_verify(CGI::unescape(data)))
829
825
  rescue ActiveSupport::MessageVerifier::InvalidSignature => ex
830
- ZuoraConnect.logger.error("Error Decrypting", ex) if log_fatal
826
+ ZuoraConnect.logger.error("Error Decrypting", ex, self.default_ougai_items) if log_fatal
831
827
  return rescue_return
832
828
  rescue JSON::ParserError => ex
833
- ZuoraConnect.logger.error("JSON Parse Error", ex) if log_fatal
829
+ ZuoraConnect.logger.error("JSON Parse Error", ex, self.default_ougai_items) if log_fatal
834
830
  return encryptor.decrypt_and_verify(CGI::unescape(data))
835
831
  end
836
832
  end
@@ -1127,6 +1123,15 @@ module ZuoraConnect
1127
1123
  # Data from each schema will be loaded into table(aggregate_name) into the public schema
1128
1124
  def self.refresh_aggregate_table(aggregate_name: 'all_tasks_processing', table_name: 'tasks', where_clause: "where status in ('Processing', 'Queued')", index_table: true, ignore_indexes: [])
1129
1125
  self.update_functions
1126
+
1127
+ sql_result = ActiveRecord::Base.connection.execute <<-eos
1128
+ SELECT pid, relname, mode
1129
+ FROM pg_locks l
1130
+ JOIN pg_class t ON l.relation = t.oid AND t.relkind = 'r'
1131
+ WHERE t.relname = '#{aggregate_name}' AND l.mode ='AccessExclusiveLock';
1132
+ eos
1133
+ raise ZuoraConnect::Exceptions::Error.new("An existing lock detected while dropping table '#{aggregate_name}'") if sql_result.count > 0
1134
+
1130
1135
  if index_table
1131
1136
  ActiveRecord::Base.connection.execute('SELECT "shared_extensions".refresh_aggregate_table(\'%s\', \'%s\', %s, \'Index\', \'{%s}\');' % [aggregate_name, table_name, ActiveRecord::Base.connection.quote(where_clause), ignore_indexes.map { |index| "\"#{index}\"" }.join(',')])
1132
1137
  else
@@ -1214,6 +1219,16 @@ module ZuoraConnect
1214
1219
  end
1215
1220
  end
1216
1221
 
1222
+ def self.without_sticking
1223
+ if self.connection.respond_to?(:without_sticking)
1224
+ self.connection.without_sticking do
1225
+ yield
1226
+ end
1227
+ else
1228
+ yield
1229
+ end
1230
+ end
1231
+
1217
1232
  method_hook :updateOption, :update_logins, :before => :check_oauth_state
1218
1233
  method_hook :new_session, :refresh, :build_task, :after => :apartment_switch
1219
1234
  end
@@ -3,12 +3,7 @@
3
3
  <title>Select Task ID</title>
4
4
  <meta name="viewport" content="width=device-width,initial-scale=1">
5
5
  <style>
6
- body {
7
- background-color: #EFEFEF;
8
- margin: 0;
9
- }
10
-
11
- div.connect-dialog {
6
+ .connect-dialog {
12
7
  width: 95%;
13
8
  max-width: 33em;
14
9
  margin: 4em auto 0;
@@ -16,7 +11,11 @@
16
11
  text-align: center;
17
12
  }
18
13
 
19
- div.connect-dialog > div {
14
+ .connect-dialog div {
15
+ background-color: white;
16
+ color: #2E2F30;
17
+ text-align: center;
18
+ font-family: arial, sans-serif;
20
19
  margin: 0 0 1em;
21
20
  border: 1px solid #CCC;
22
21
  border-right-color: #999;
@@ -27,19 +26,17 @@
27
26
  border-top-right-radius: 9px;
28
27
  border-bottom-left-radius: 9px;
29
28
  border-bottom-right-radius: 9px;
30
- background-color: white;
31
29
  padding: 7px 12% 0;
32
30
  box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
33
31
  }
34
32
 
35
- div.connect-dialog > h1 {
33
+ .connect-dialog h1 {
36
34
  font-size: 100%;
37
35
  color: #3D4B5A;
38
36
  line-height: 1.5em;
39
37
  }
40
38
 
41
-
42
- div.connect-dialog > div.launch_button {
39
+ .connect-dialog .launch_button {
43
40
  margin: 1em 0 1em;
44
41
  margin-right: auto;
45
42
  margin-left: auto;
@@ -24,9 +24,13 @@ module Resque
24
24
  @appinstance.new_session(holding_pattern: true)
25
25
  rescue ActiveRecord::RecordNotFound => exception
26
26
  # If we can't find app_instance let make sure we cleanup
27
- Rails.logger.info("No instance found, purge")
28
- ZuoraConnect::AppInstance.new(id: args['app_instance_id'].to_i).prune_data
29
- return
27
+ if Redis.current.zscore("AppInstance:Deleted", args['app_instance_id'].to_i).present?
28
+ Rails.logger.info("No instance found, purge")
29
+ ZuoraConnect::AppInstance.new(id: args['app_instance_id'].to_i).prune_data
30
+ return
31
+ else
32
+ raise
33
+ end
30
34
  rescue ActiveRecord::StatementInvalid => exception
31
35
  if (connection_count += 1) <= 3 &&
32
36
  (
@@ -23,6 +23,8 @@ module ZuoraConnect
23
23
  case Rails.env.to_s
24
24
  when 'development'
25
25
  Rails.logger
26
+ when 'test'
27
+ Rails.logger
26
28
  else
27
29
  @logger ||= custom_logger(name: "Connect", level: Rails.logger.level)
28
30
  end
@@ -7,7 +7,7 @@ module ZuoraConnect
7
7
 
8
8
  attr_accessor :oauth_client_id, :oauth_client_secret, :oauth_client_redirect_uri
9
9
 
10
- attr_accessor :dev_mode_logins, :dev_mode_options, :dev_mode_mode, :dev_mode_appinstance, :dev_mode_user, :dev_mode_pass, :dev_mode_admin, :dev_mode_secret_access_key,:dev_mode_access_key_id,:aws_region, :s3_bucket_name, :s3_folder_name, :json_logging
10
+ attr_accessor :dev_mode_logins, :dev_mode_options, :dev_mode_mode, :dev_mode_appinstance, :dev_mode_user, :dev_mode_pass, :dev_mode_admin, :dev_mode_secret_access_key,:dev_mode_access_key_id,:aws_region, :s3_bucket_name, :s3_folder_name, :json_logging, :insert_migrations
11
11
 
12
12
  def initialize
13
13
  @default_locale = :en
@@ -19,6 +19,7 @@ module ZuoraConnect
19
19
  @additional_apartment_models = []
20
20
  @silencer_resque_finish = true
21
21
  @blpop_queue = false
22
+ @insert_migrations = true
22
23
 
23
24
  # Setting the app name for telegraf write
24
25
  @enable_metrics = false
@@ -42,7 +43,7 @@ module ZuoraConnect
42
43
  @aws_region = "us-west-2"
43
44
  @s3_bucket_name = "rbm-apps"
44
45
  @s3_folder_name = Rails.application.class.parent_name
45
- @json_logging = Rails.env.to_s == 'development' ? false : true
46
+ @json_logging = Rails.env.development? || Rails.env.test? ? false : true
46
47
  end
47
48
 
48
49
  def private_key
@@ -19,7 +19,6 @@ module ZuoraConnect
19
19
  ElasticAPM.set_label(:trace_id, request.uuid) if defined?(ElasticAPM) && ElasticAPM.running?
20
20
  end
21
21
  end
22
- start_time = Time.now
23
22
  if request.headers["API-Token"].present?
24
23
  @appinstance = ZuoraConnect::AppInstance.find_by(:api_token => request.headers["API-Token"])
25
24
  ZuoraConnect.logger.debug("API REQUEST - API token") if @appinstance.present?
@@ -48,7 +47,7 @@ module ZuoraConnect
48
47
  render json: {"status": 401, "message": "Missing mapping or no deployment for '#{zuora_host}-#{zuora_entity_id}' ."}, status: :unauthorized
49
48
  return
50
49
  elsif appinstances.size > 1
51
- render json: {"status": 401, "message": "More than one app instance binded to host and entity ids. Please indicate correct instance via 'zuora-instance-id' header"}, status: :unauthorized
50
+ render json: {"status": 401, "message": "More than one app instance binded to host and entity ids. Please indicate correct instance via 'zuora-instance-id' header", "instances": appinstances.map {|instance| instance.id }.sort }, status: :unauthorized
52
51
  return
53
52
  else
54
53
  @appinstance = appinstances.first
@@ -65,10 +64,6 @@ module ZuoraConnect
65
64
  else
66
65
  check_instance
67
66
  end
68
-
69
- if @appinstance.present?
70
- ZuoraConnect.logger.debug("Authenticate App API Request Completed In - #{(Time.now - start_time).round(2)}s")
71
- end
72
67
  end
73
68
  end
74
69
 
@@ -101,7 +96,6 @@ module ZuoraConnect
101
96
  ElasticAPM.set_label(:trace_id, request.uuid)
102
97
  end
103
98
  end
104
- start_time = Time.now
105
99
 
106
100
  if ZuoraConnect.configuration.mode == "Production"
107
101
  setup_instance_via_prod_mode
@@ -141,32 +135,30 @@ module ZuoraConnect
141
135
  rescue
142
136
  ZuoraConnect.logger.error(ex)
143
137
  end
144
-
145
- ZuoraConnect.logger.debug("Authenticate App Request Completed In - #{(Time.now - start_time).round(2)}s")
146
138
  end
147
139
  rescue ZuoraConnect::Exceptions::InvalidCredentialSet => ex
148
140
  id = @appinstance.id
149
141
  ZuoraConnect::AppInstance.destroy(id)
150
142
  Apartment::Tenant.drop(id)
151
143
  render "zuora_connect/static/error_handled", :locals => {
152
- :title => "Application Setup Error",
144
+ :title => "Application Setup Error",
153
145
  :message => "Application cannot be run using Zuora Session. Delete old application \
154
146
  deployment and create new with Zuora Basic or OAuth credentials."
155
147
  }, :layout => false
156
- return
148
+ return
157
149
  rescue ZuoraConnect::Exceptions::AccessDenied => ex
158
150
  respond_to do |format|
159
- format.html {
151
+ format.html {
160
152
  render "zuora_connect/static/error_handled", :locals => {
161
- :title => "Application State Error",
153
+ :title => "Application State Error",
162
154
  :message => ex.message
163
- }, status: 401, layout: false
155
+ }, status: 401, layout: false
164
156
  }
165
- format.js {
157
+ format.js {
166
158
  render "zuora_connect/static/error_handled", :locals => {
167
- :title => "Application State Error",
159
+ :title => "Application State Error",
168
160
  :message => ex.message
169
- }, status: 401, layout: false
161
+ }, status: 401, layout: false
170
162
  }
171
163
  format.json { render json: {'errors' => ex.message}, status: 401 }
172
164
  format.all { render json: ex.message, status: 401 }
@@ -196,17 +188,17 @@ module ZuoraConnect
196
188
  raise ZuoraConnect::Exceptions::AccessDenied.new("User is not an authorized admin for this application") if raise_error
197
189
 
198
190
  respond_to do |format|
199
- format.html {
191
+ format.html {
200
192
  render "zuora_connect/static/error_handled", :locals => {
201
- :title => "Unauthorized",
193
+ :title => "Unauthorized",
202
194
  :message => "User is not an authorized admin for this application"
203
195
  }, status: 401, :layout => false
204
196
  }
205
- format.js {
197
+ format.js {
206
198
  render "zuora_connect/static/error_handled", :locals => {
207
- :title => "Unauthorized",
199
+ :title => "Unauthorized",
208
200
  :message => "User is not an authorized admin for this application"
209
- }, status: 401, :layout => false
201
+ }, status: 401, :layout => false
210
202
  }
211
203
  format.json { render json: {'errors' => ex.message}, status: 401 }
212
204
  format.all { render json: ex.message, status: 401 }
@@ -246,7 +238,7 @@ module ZuoraConnect
246
238
  auth_headers.merge!({'Authorization' => "ZSession-a3N2w #{zuora_client.get_session(prefix: false, auth_type: :basic)}"})
247
239
  else
248
240
  render "zuora_connect/static/error_handled", :locals => {
249
- :title => "Missing Authorization Token",
241
+ :title => "Missing Authorization Token",
250
242
  :message => "Zuora 'Zuora-Auth-Token' header and 'ZSession' cookie not present."
251
243
  }, :layout => false
252
244
  return
@@ -268,27 +260,34 @@ module ZuoraConnect
268
260
  if zuora_tenant_id.to_s == "10548"
269
261
  session.clear
270
262
  render "zuora_connect/static/error_handled", :locals => {
271
- :title => "Security Testing",
263
+ :title => "Security Testing",
272
264
  :message => "Ya we know it you"
273
265
  }, :layout => false
274
266
  return
275
267
  else
276
- raise ZuoraConnect::Exceptions::Error.new("Header entity id does not match identity call entity id.")
268
+ raise ZuoraConnect::Exceptions::Error.new("Header entity id does not match identity call entity id.")
277
269
  end
278
270
  end
279
271
 
272
+ ##
273
+ # If the ZSession was refreshed, but it's still the same user and they aren't launching from the side bar,
274
+ # we don't need to continue
275
+ is_different_user = identity.slice("entityId", "tenantId", "userId", "userProfileId") == (session["ZuoraCurrentIdentity"] || {}).slice("entityId", "tenantId", "userId", "userProfileId")
276
+ zuora_details["identity"]["entityId"] = identity['entityId']
280
277
  session["ZuoraCurrentIdentity"] = identity
281
278
  session["ZuoraCurrentEntity"] = identity['entityId']
282
279
  session["ZSession"] = cookies['ZSession']
283
- zuora_instance_id = nil
284
- zuora_details["identity"]["entityId"] = identity['entityId']
285
-
286
- client_describe, response = zuora_client.rest_call(
287
- url: zuora_client.rest_endpoint("genesis/user/info").gsub('v1/', ''),
288
- session_type: zuora_client.class == ZuoraAPI::Oauth ? :bearer : :basic,
289
- headers: auth_headers
290
- )
291
- session["ZuoraCurrentUserInfo"] = client_describe
280
+ if is_different_user || params[:sidebar_launch].to_s.to_bool
281
+ zuora_instance_id = nil
282
+ ZuoraConnect.logger.debug("UI Authorization", zuora: zuora_details)
283
+
284
+ client_describe, response = zuora_client.rest_call(
285
+ url: zuora_client.rest_endpoint("genesis/user/info").gsub('v1/', ''),
286
+ session_type: zuora_client.class == ZuoraAPI::Oauth ? :bearer : :basic,
287
+ headers: auth_headers
288
+ )
289
+ session["ZuoraCurrentUserInfo"] = client_describe
290
+ end
292
291
  end
293
292
 
294
293
  #Find matching app instances.
@@ -296,7 +295,7 @@ module ZuoraConnect
296
295
  appinstances = ZuoraConnect::AppInstance.where("zuora_entity_ids ?& array[:entities] = true AND zuora_domain = :host AND id = :id", entities: [zuora_entity_id], host: zuora_client.rest_domain, id: zuora_instance_id.to_i).pluck(:id, :name)
297
296
  else
298
297
  #if app_instance_ids is present then permissions still controlled by connect
299
- if params[:app_instance_ids].present?
298
+ if params[:app_instance_ids].present?
300
299
  navbar, response = zuora_client.rest_call(url: zuora_client.rest_endpoint("navigation"))
301
300
  urls = navbar['menus'].map {|x| x['url']}
302
301
  app_env = ENV["DEIS_APP"] || "xyz123"
@@ -304,23 +303,27 @@ module ZuoraConnect
304
303
  if url.blank?
305
304
  if navbar['menus'].map {|x| x['label']}.include?('Link Connect Account')
306
305
  render "zuora_connect/static/error_handled", :locals => {
307
- :title => "Link Account",
306
+ :title => "Link Account",
308
307
  :message => "Link Connect account to gain access to application."
309
308
  }, :layout => false
310
309
  return
311
310
  end
312
- ZuoraConnect::Exceptions::APIError.new(message: "#{app_env} navbar url was blank", response: response)
311
+ raise ZuoraConnect::Exceptions::APIError.new(message: "#{app_env} navbar url was blank", response: response)
313
312
  else
314
- begin
315
- task_ids = JSON.parse(Base64.urlsafe_decode64(CGI.parse(URI.parse(url).query)["app_instance_ids"][0]))
316
- rescue => ex
317
- raise ZuoraConnect::Exceptions::APIError.new(message: "Failure in parsing the navbar urls.", response: response)
313
+ query_params = CGI.parse(URI.parse(url).query)
314
+ app_instance_ids = query_params["app_instance_ids"][0]
315
+ if app_instance_ids.present?
316
+ begin
317
+ task_ids = JSON.parse(Base64.urlsafe_decode64(app_instance_ids))
318
+
319
+ appinstances = ZuoraConnect::AppInstance.where(:id => task_ids).pluck(:id, :name)
320
+ rescue => ex
321
+ raise ZuoraConnect::Exceptions::APIError.new(message: "Failure in parsing the navbar urls.", response: response)
322
+ end
318
323
  end
319
324
  end
320
- appinstances = ZuoraConnect::AppInstance.where(:id => task_ids).pluck(:id, :name)
321
- else
322
- appinstances = ZuoraConnect::AppInstance.where("zuora_entity_ids ?& array[:entities] = true AND zuora_domain = :host", entities: [zuora_entity_id], host: zuora_client.rest_domain).pluck(:id, :name)
323
325
  end
326
+ appinstances ||= ZuoraConnect::AppInstance.where("zuora_entity_ids ?& array[:entities] = true AND zuora_domain = :host", entities: [zuora_entity_id], host: zuora_client.rest_domain).pluck(:id, :name)
324
327
  end
325
328
 
326
329
  zuora_user_id = cookies['Zuora-User-Id'] || session["ZuoraCurrentIdentity"]['userId']
@@ -330,7 +333,7 @@ module ZuoraConnect
330
333
  ZuoraConnect.logger.debug("Instance is #{appinstances.to_h.keys.first}")
331
334
  @appinstance = ZuoraConnect::AppInstance.find(appinstances.to_h.keys.first)
332
335
 
333
- #Add user/update
336
+ #Add user/update
334
337
  begin
335
338
  @zuora_user = ZuoraConnect::ZuoraUser.where(:zuora_user_id => zuora_user_id).first
336
339
  rescue ActiveRecord::StatementInvalid => ex
@@ -350,7 +353,7 @@ module ZuoraConnect
350
353
  else
351
354
  ZuoraConnect.logger.debug("New zuora user object for #{zuora_user_id}")
352
355
  @zuora_user = ZuoraConnect::ZuoraUser.create!(:zuora_user_id => zuora_user_id, :zuora_identity_response => {zuora_entity_id => session["ZuoraCurrentIdentity"]})
353
- end
356
+ end
354
357
  @zuora_user.session = session
355
358
  session["#{@appinstance.id}::user::localUserId"] = @zuora_user.id
356
359
  session["#{@appinstance.id}::user::email"] = session['ZuoraCurrentIdentity']["username"]
@@ -359,19 +362,19 @@ module ZuoraConnect
359
362
  session["appInstance"] = @appinstance.id
360
363
 
361
364
  #We have multiple, user must pick
362
- elsif appinstances.size > 1
365
+ elsif appinstances.size > 1
363
366
  ZuoraConnect.logger.debug("User must select instance. #{@names}")
364
367
  render "zuora_connect/static/launch", :locals => {:names => appinstances.to_h}, :layout => false
365
368
  return
366
369
 
367
370
  #We have no deployed instance for this tenant
368
- else
369
- #Ensure user can access oauth creation API
371
+ else
372
+ #Ensure user can access oauth creation API
370
373
  if !session["ZuoraCurrentUserInfo"]['permissions'].include?("permission.userManagement")
371
374
  Thread.current[:appinstance] = nil
372
375
  session["appInstance"] = nil
373
376
  render "zuora_connect/static/error_handled", :locals => {
374
- :title => "Application can only complete its initial setup via platform administrator",
377
+ :title => "Application can only complete its initial setup via platform administrator",
375
378
  :message => "Please contact admin who has user managment permissions in tenant and have them click and finish setup."
376
379
  }, :layout => false
377
380
  return
@@ -389,20 +392,20 @@ module ZuoraConnect
389
392
  next_id = (ZuoraConnect::AppInstance.all.where('id > 24999999').order(id: :desc).limit(1).pluck(:id).first || 24999999) + 1
390
393
  user = (ENV['DEIS_APP'] || "Application").split('-').map(&:capitalize).join(' ')
391
394
  body = {
392
- 'userId' => zuora_user_id,
393
- 'entityIds' => [zuora_entity_id.unpack("a8a4a4a4a12").join('-')],
394
- 'customAuthorities' => [],
395
+ 'userId' => zuora_user_id,
396
+ 'entityIds' => [zuora_entity_id.unpack("a8a4a4a4a12").join('-')],
397
+ 'customAuthorities' => [],
395
398
  'additionalInformation' => {
396
- 'description' => "This user is for #{user} application.",
399
+ 'description' => "This user is for #{user} application.",
397
400
  'name' => "#{user} API User #{next_id}"
398
401
  }
399
402
  }
400
403
 
401
404
  oauth_response, response = zuora_client.rest_call(
402
- method: :post,
403
- body: body.to_json,
404
- url: zuora_client.rest_endpoint("genesis/clients").gsub('v1/', ''),
405
- session_type: zuora_client.class == ZuoraAPI::Oauth ? :bearer : :basic,
405
+ method: :post,
406
+ body: body.to_json,
407
+ url: zuora_client.rest_endpoint("genesis/clients").gsub('v1/', ''),
408
+ session_type: zuora_client.class == ZuoraAPI::Oauth ? :bearer : :basic,
406
409
  headers: auth_headers
407
410
  )
408
411
 
@@ -444,7 +447,7 @@ module ZuoraConnect
444
447
  Thread.current[:appinstance] = nil
445
448
  session["appInstance"] = nil
446
449
  render "zuora_connect/static/error_handled", :locals => {
447
- :title => "Application could not create unique tokens.",
450
+ :title => "Application could not create unique tokens.",
448
451
  :message => "Please contact support or retry launching application."
449
452
  }, :layout => false
450
453
  return
@@ -472,19 +475,27 @@ module ZuoraConnect
472
475
  ZuoraConnect.logger.warn("UI Authorization Error", ex, zuora: zuora_details.merge({:error => response.body}))
473
476
  elsif final_error != "INVALID_SESSION"
474
477
  ZuoraConnect.logger.warn("UI Authorization Error", ex, zuora: zuora_details.merge({:error => final_error}))
478
+ else
479
+ ZuoraConnect.logger.info("UI Authorization Error", ex, zuora: zuora_details.merge({:error => final_error}))
475
480
  end
476
481
  redirect_to "https://#{zuora_host}/apps/newlogin.do?retURL=#{request.fullpath}"
477
482
  return
478
- rescue => ex
479
- session.clear
480
- if defined?(ex.response) && ex.response.present? && defined?(ex.response.body)
481
- zuora_details.merge!({:error => ex.response.body})
483
+
484
+ rescue ZuoraAPI::Exceptions::ZuoraAPIError, Exception => ex
485
+ if ex.message.include?("Referenced User resource(s) not found") && ex.class == ZuoraAPI::Exceptions::ZuoraAPIError
486
+ locals = {title: "Provisioning Error", message: "New tenats need to be provisioned by API Gateway('#{ex.message}'). Please contact support."}
487
+ render "zuora_connect/static/error_handled", locals: locals, status: 400, layout: false
488
+ else
489
+ session.clear
490
+ if defined?(ex.response) && ex.response.present? && defined?(ex.response.body)
491
+ zuora_details.merge!({:error => ex.response.body})
492
+ end
493
+ ZuoraConnect.logger.error("UI Authorization Error", ex, zuora: zuora_details)
494
+ render "zuora_connect/static/error_unhandled", locals: {exception: ex, skip_exception: true}, layout: false, status: 500
482
495
  end
483
- ZuoraConnect.logger.error("UI Authorization Error", ex, zuora: zuora_details)
484
- render "zuora_connect/static/error_unhandled", locals: {exception: ex, skip_exception: true}, layout: false, status: 500
485
- return
496
+ return
486
497
  end
487
- elsif request["data"] && /^([A-Za-z0-9+\/\-\_]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)$/.match(request["data"].to_s)
498
+ elsif request["data"].present? && (request["connectInstanceId"].present? || /^([A-Za-z0-9+\/\-\_]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+-_\/]{3}=|[A-Za-z0-9+\/]{2}==)$/.match(request["data"].to_s))
488
499
  session.clear
489
500
  values = JSON.parse(ZuoraConnect::AppInstance.decrypt_response(Base64.urlsafe_decode64(request["data"])))
490
501
  values.fetch("param_data", {}).each do |k ,v|
@@ -499,8 +510,6 @@ module ZuoraConnect
499
510
  session["#{values["appInstance"]}::user::email"] = values["current_user"]["email"]
500
511
  end
501
512
 
502
- ZuoraConnect.logger.debug({msg: 'Setup values', connect: values}) if Rails.env != "production"
503
-
504
513
  @appinstance = ZuoraConnect::AppInstance.find_by(:id => values["appInstance"].to_i)
505
514
 
506
515
  if @appinstance.blank?
@@ -521,10 +530,10 @@ module ZuoraConnect
521
530
  else
522
531
  raise ZuoraConnect::Exceptions::AccessDenied.new("Authorization mismatch. Possible tampering with session.")
523
532
  end
524
- end
533
+ end
525
534
  else
526
535
  if session["appInstance"].present?
527
- @appinstance = ZuoraConnect::AppInstance.find_by(:id => session["appInstance"])
536
+ @appinstance = ZuoraConnect::AppInstance.find_by(:id => session["appInstance"])
528
537
  else
529
538
  raise ZuoraConnect::Exceptions::AccessDenied.new("No application state or session found.")
530
539
  end
@@ -16,10 +16,13 @@ module ZuoraConnect
16
16
  end
17
17
  end
18
18
 
19
+
19
20
  initializer :append_migrations do |app|
20
- unless app.root.to_s.match root.to_s
21
- config.paths["db/migrate"].expanded.each do |expanded_path|
22
- app.config.paths["db/migrate"] << expanded_path
21
+ if ZuoraConnect.configuration.insert_migrations
22
+ unless app.root.to_s.match root.to_s
23
+ config.paths["db/migrate"].expanded.each do |expanded_path|
24
+ app.config.paths["db/migrate"] << expanded_path
25
+ end
23
26
  end
24
27
  end
25
28
  end
@@ -13,6 +13,7 @@ module ZuoraConnect
13
13
  PATH_INFO
14
14
  CONTENT_TYPE
15
15
  ORIGINAL_FULLPATH
16
+ QUERY_STRING
16
17
  )
17
18
 
18
19
  config.before_initialize do
@@ -46,7 +47,7 @@ module ZuoraConnect
46
47
  require 'lograge'
47
48
 
48
49
  Rails.configuration.logger = ZuoraConnect.custom_logger(name: "Rails")
49
- if Rails.env != 'development'
50
+ if !Rails.env.test? && !Rails.env.development?
50
51
  Rails.configuration.lograge.enabled = true
51
52
  Rails.configuration.colorize_logging = false
52
53
  end
@@ -1,3 +1,3 @@
1
1
  module ZuoraConnect
2
- VERSION = "2.0.57"
2
+ VERSION = "2.0.58"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zuora_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.57
4
+ version: 2.0.58
5
5
  platform: ruby
6
6
  authors:
7
7
  - Connect Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-13 00:00:00.000000000 Z
11
+ date: 2020-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: apartment
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: ougai-formatters-customizable
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 1.0.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 1.0.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: zuora_api
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -120,6 +120,20 @@ dependencies:
120
120
  - - ">="
121
121
  - !ruby/object:Gem::Version
122
122
  version: '0'
123
+ - !ruby/object:Gem::Dependency
124
+ name: aws-sdk-rails
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ type: :runtime
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
123
137
  - !ruby/object:Gem::Dependency
124
138
  name: mono_logger
125
139
  requirement: !ruby/object:Gem::Requirement