zuora_connect 2.0.57 → 2.0.60
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/hallway_wrapper/after.js +22 -3
- data/app/models/zuora_connect/app_instance_base.rb +49 -34
- data/app/views/zuora_connect/static/launch.html.erb +8 -11
- data/lib/resque/plugins/app_instance_job.rb +8 -4
- data/lib/zuora_connect.rb +2 -0
- data/lib/zuora_connect/configuration.rb +3 -2
- data/lib/zuora_connect/controllers/helpers.rb +80 -71
- data/lib/zuora_connect/engine.rb +6 -3
- data/lib/zuora_connect/railtie.rb +2 -1
- data/lib/zuora_connect/version.rb +1 -1
- metadata +20 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bae96287832facbb0f512eedca7038f2bd566650d4e057f0d623613cb3acb559
|
4
|
+
data.tar.gz: d3b1f756842c3231a23719669d81c7aa206dfc677ae19ae2e537d3c3f6c089ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 872a07f80dfbe1c12428cacc4369fe83a0f59eb20d953c0c43f609d19cd75556138e1162f4e175c6fdf10844f4bf2a01c0f8f1529c7a6e0774d7b53b47f4e68a
|
7
|
+
data.tar.gz: c2f5653b77bbc93521c37062542d12697fb21e055cff18a55846837e6f454dd2ce15963580f6623e523d6b30f677bce8e1fb7820a28b981cfa69c73bd6f7333a
|
@@ -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.
|
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("
|
14
|
-
|
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.
|
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
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
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
|
(
|
@@ -43,7 +47,7 @@ module Resque
|
|
43
47
|
raise
|
44
48
|
end
|
45
49
|
rescue PG::ConnectionBad => exception
|
46
|
-
Rails.logger.
|
50
|
+
Rails.logger.warn("Bad Connection Restart", exception)
|
47
51
|
Resque.enqueue_to(self.job.queue, self.job.payload['class'], args)
|
48
52
|
return
|
49
53
|
rescue ZuoraConnect::Exceptions::ConnectCommunicationError => exception
|
data/lib/zuora_connect.rb
CHANGED
@@ -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.
|
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
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
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
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
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
|
-
|
479
|
-
|
480
|
-
if
|
481
|
-
|
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
|
-
|
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
|
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
|
data/lib/zuora_connect/engine.rb
CHANGED
@@ -16,10 +16,13 @@ module ZuoraConnect
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
|
19
20
|
initializer :append_migrations do |app|
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
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
|
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.
|
4
|
+
version: 2.0.60
|
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-
|
11
|
+
date: 2020-07-02 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:
|
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:
|
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
|