zuora_connect 2.0.58 → 2.0.59a

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1b0443ea374a1f1f82e212960a7df80fb9aa953fb4bf0fcb123949e73dfc622d
4
- data.tar.gz: a356f5120206bf8febbdca0db439c5792dca19156776356f09f5a39da50cf7b1
3
+ metadata.gz: a40ca87d7094e3f69418c9e339a61f3d89be11ca4e4d4c20df1cdca3c7a9af14
4
+ data.tar.gz: a30171ac13b845b3b9c2871af570564e5d1d0ae57e625809b4217d2dc0a4a2a5
5
5
  SHA512:
6
- metadata.gz: 34e40410cfcd4752b174d584d2cf883084630b56e7e4d897733da177fa66ece76c9ec3b2556e0ea3778b05eed949c6dba9e4c37f635d178fb9d77f776ec5221f
7
- data.tar.gz: '08dde90f26d809089f79928c0cfa6d7c43d551b61448b7ce040b0ba05aa64552599ff3e3c49f46feb54340d846565faa75f891730501e2ad1ffe6a8c554856e5'
6
+ metadata.gz: 9cbfc416d448d4d800f4704361306e80d3033bc38e6128227725eb49c3d67ac27e05ef672fdf591b5919e3c27348f65ff6e1d05c5f38f8c27f42d68c7a2103a0
7
+ data.tar.gz: 6aa04b8bea5686529095e693db98be19839f36a48cab820f61145d6649571c212a1e10a659efc08cab61ee92053607ba003810c7e74ddb5ab9bebc5c0af3d87a
@@ -1,10 +1,11 @@
1
1
  module ZuoraConnect
2
2
  class StaticController < ApplicationController
3
- before_action :authenticate_connect_app_request, :except => [:metrics, :health, :initialize_app]
4
- before_action :clear_connect_app_session, :only => [:metrics, :health, :initialize_app]
5
- after_action :persist_connect_app_session, :except => [:metrics, :health, :initialize_app]
6
-
7
- skip_before_action :verify_authenticity_token, :only => [:initialize_app]
3
+ before_action :authenticate_connect_app_request, :except => [:metrics, :health, :initialize_app, :provision]
4
+ before_action :clear_connect_app_session, :only => [:metrics, :health, :initialize_app, :provision]
5
+ after_action :persist_connect_app_session, :except => [:metrics, :health, :initialize_app, :provision]
6
+
7
+ skip_before_action :verify_authenticity_token, :only => [:initialize_app, :provision]
8
+ http_basic_authenticate_with name: ENV['PROVISION_USER'], password: ENV['PROVISION_SECRET'], :only => [:provision]
8
9
 
9
10
  def metrics
10
11
  type = params[:type].present? ? params[:type] : "versions"
@@ -34,11 +35,13 @@ module ZuoraConnect
34
35
  def initialize_app
35
36
  begin
36
37
  authenticate_connect_app_request
37
- @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
38
- render json: {
39
- message: "Success",
40
- status: 200
41
- }, status: 200
38
+ unless performed?
39
+ @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
40
+ render json: {
41
+ message: 'Success',
42
+ status: 200
43
+ }, status: 200
44
+ end
42
45
  rescue => ex
43
46
  Rails.logger.error("Failed to Initialize application", ex)
44
47
  if performed?
@@ -52,6 +55,28 @@ module ZuoraConnect
52
55
  end
53
56
  end
54
57
 
58
+ def provision
59
+ create_new_instance
60
+ unless performed?
61
+ render json: {
62
+ status: 200,
63
+ message: 'Success',
64
+ app_instance_id: @appinstance.id
65
+ }, status: 200
66
+ end
67
+ rescue StandardError => e
68
+ message = 'Failed to provision new instance'
69
+ if performed?
70
+ Rails.logger.error("#{message}: #{performed?}", e)
71
+ else
72
+ Rails.logger.error(message, e)
73
+ render json: {
74
+ status: 500,
75
+ message: message
76
+ }, status: 500
77
+ end
78
+ end
79
+
55
80
  private
56
81
 
57
82
  def clear_connect_app_session
@@ -3,6 +3,10 @@ ZuoraConnect::Engine.routes.draw do
3
3
  get '/internal/data' => 'static#metrics'
4
4
  post '/initialize_app' => 'static#initialize_app'
5
5
 
6
+ if ENV['PROVISION_USER'].present? && ENV['PROVISION_SECRET'].present?
7
+ post '/provision' => 'static#provision'
8
+ end
9
+
6
10
  namespace :api do
7
11
  namespace :v1 do
8
12
  resources :app_instance, :only => [:index], defaults: {format: :json} do
@@ -219,6 +219,80 @@ module ZuoraConnect
219
219
  return (request.headers['ZuoraCurrentEntity'].present? || cookies['ZuoraCurrentEntity'].present?)
220
220
  end
221
221
 
222
+ def create_new_instance
223
+ ZuoraConnect::AppInstance.read_master_db do
224
+ Thread.current[:appinstance] = nil
225
+ ZuoraConnect.logger.with_fields = {} if ZuoraConnect.logger.is_a?(Ougai::Logger)
226
+ Rails.logger.with_fields = {} if Rails.logger.is_a?(Ougai::Logger)
227
+
228
+ if defined?(ElasticAPM) && ElasticAPM.running? && ElasticAPM.respond_to?(:set_label)
229
+ ElasticAPM.set_label(:trace_id, request.uuid)
230
+ end
231
+
232
+ zuora_host = request.headers['zuora-host']
233
+ zuora_entity_id = (request.headers['zuora-entity-ids'] || '').gsub(
234
+ '-',
235
+ ''
236
+ ).split(',').first
237
+
238
+ # Validate host present
239
+ if zuora_host.blank?
240
+ render json: {
241
+ status: 401,
242
+ message: 'zuora-host header was not supplied.'
243
+ }, status: :unauthorized
244
+ return
245
+ end
246
+
247
+ # Validate entity-ids present
248
+ if zuora_entity_id.blank?
249
+ render json: {
250
+ status: 401,
251
+ message: 'zuora-entity-ids header was not supplied.'
252
+ }, status: :unauthorized
253
+ return
254
+ end
255
+
256
+ rest_domain = ZuoraAPI::Login.new(url: "https://#{zuora_host}").rest_domain
257
+ app_instance_id = ZuoraConnect::AppInstance.where(
258
+ 'zuora_entity_ids ?& array[:entities] AND zuora_domain = :host',
259
+ entities: [zuora_entity_id],
260
+ host: rest_domain
261
+ ).pluck(:id).first
262
+
263
+ if app_instance_id.present?
264
+ render json: {
265
+ status: 409,
266
+ message: 'Instance already exists.',
267
+ app_instance_id: app_instance_id
268
+ }, status: 409
269
+ else
270
+ Apartment::Tenant.switch!("public")
271
+ retry_count = 3
272
+ begin
273
+ @appinstance = new_instance(
274
+ next_instance_id,
275
+ zuora_entity_id,
276
+ rest_domain,
277
+ retry_count: retry_count
278
+ )
279
+ rescue ActiveRecord::RecordNotUnique
280
+ retry if (retry_count -= 1).positive?
281
+ return
282
+ end
283
+
284
+ app_instance_id = @appinstance.id
285
+ end
286
+
287
+ begin
288
+ Apartment::Tenant.switch!('public')
289
+ Apartment::Tenant.create(app_instance_id.to_s)
290
+ rescue Apartment::TenantExists
291
+ ZuoraConnect.logger.debug('Tenant Already Exists')
292
+ end
293
+ end
294
+ end
295
+
222
296
  private
223
297
  def setup_instance_via_prod_mode
224
298
  zuora_entity_id = request.headers['ZuoraCurrentEntity'] || cookies['ZuoraCurrentEntity']
@@ -226,7 +300,7 @@ module ZuoraConnect
226
300
  if zuora_entity_id.present?
227
301
  zuora_tenant_id = cookies['Zuora-Tenant-Id']
228
302
  zuora_user_id = cookies['Zuora-User-Id']
229
- zuora_host = request.headers["HTTP_X_FORWARDED_HOST"] || "apisandbox.zuora.com"
303
+ zuora_host = request.headers['HTTP_X_FORWARDED_HOST'] || request.headers['Zuora-Host'] || 'apisandbox.zuora.com'
230
304
 
231
305
  zuora_details = {'host' => zuora_host, 'user_id' => zuora_user_id, 'tenant_id' => zuora_tenant_id, 'entity_id' => zuora_entity_id}
232
306
  auth_headers = {}
@@ -272,7 +346,7 @@ module ZuoraConnect
272
346
  ##
273
347
  # If the ZSession was refreshed, but it's still the same user and they aren't launching from the side bar,
274
348
  # we don't need to continue
275
- is_different_user = identity.slice("entityId", "tenantId", "userId", "userProfileId") == (session["ZuoraCurrentIdentity"] || {}).slice("entityId", "tenantId", "userId", "userProfileId")
349
+ is_different_user = identity.slice("entityId", "tenantId", "userId", "userProfileId") != (session["ZuoraCurrentIdentity"] || {}).slice("entityId", "tenantId", "userId", "userProfileId")
276
350
  zuora_details["identity"]["entityId"] = identity['entityId']
277
351
  session["ZuoraCurrentIdentity"] = identity
278
352
  session["ZuoraCurrentEntity"] = identity['entityId']
@@ -328,11 +402,13 @@ module ZuoraConnect
328
402
 
329
403
  zuora_user_id = cookies['Zuora-User-Id'] || session["ZuoraCurrentIdentity"]['userId']
330
404
 
331
- #One deployed instance
332
405
  if appinstances.size == 1
333
406
  ZuoraConnect.logger.debug("Instance is #{appinstances.to_h.keys.first}")
334
407
  @appinstance = ZuoraConnect::AppInstance.find(appinstances.to_h.keys.first)
408
+ end
335
409
 
410
+ # One deployed instance with credentials
411
+ if defined?(@appinstance) && !@appinstance['zuora_logins'].nil?
336
412
  #Add user/update
337
413
  begin
338
414
  @zuora_user = ZuoraConnect::ZuoraUser.where(:zuora_user_id => zuora_user_id).first
@@ -380,79 +456,85 @@ module ZuoraConnect
380
456
  return
381
457
  end
382
458
  Apartment::Tenant.switch!("public")
383
- ActiveRecord::Base.transaction do
384
- ActiveRecord::Base.connection.execute('LOCK public.zuora_users IN ACCESS EXCLUSIVE MODE')
385
- 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)
459
+ retry_count = 3
460
+ task_data = {}
461
+ begin
462
+ ActiveRecord::Base.transaction do
463
+ ActiveRecord::Base.connection.execute('LOCK public.zuora_users IN ACCESS EXCLUSIVE MODE')
386
464
 
387
- if appinstances.size > 0
388
- redirect_to "https://#{zuora_host}/apps/newlogin.do?retURL=#{request.fullpath}"
389
- return
390
- end
465
+ unless defined?(@appinstance)
466
+ 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)
391
467
 
392
- next_id = (ZuoraConnect::AppInstance.all.where('id > 24999999').order(id: :desc).limit(1).pluck(:id).first || 24999999) + 1
393
- user = (ENV['DEIS_APP'] || "Application").split('-').map(&:capitalize).join(' ')
394
- body = {
395
- 'userId' => zuora_user_id,
396
- 'entityIds' => [zuora_entity_id.unpack("a8a4a4a4a12").join('-')],
397
- 'customAuthorities' => [],
398
- 'additionalInformation' => {
399
- 'description' => "This user is for #{user} application.",
400
- 'name' => "#{user} API User #{next_id}"
401
- }
402
- }
403
-
404
- oauth_response, response = zuora_client.rest_call(
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,
409
- headers: auth_headers
410
- )
468
+ if appinstances.size > 0
469
+ redirect_to "https://#{zuora_host}/apps/newlogin.do?retURL=#{request.fullpath}"
470
+ return
471
+ end
472
+ end
411
473
 
412
- new_zuora_client = ZuoraAPI::Oauth.new(url: "https://#{zuora_host}", oauth_client_id: oauth_response["clientId"], oauth_secret: oauth_response["clientSecret"] )
413
- if session["ZuoraCurrentUserInfo"].blank?
414
- client_describe, response = new_zuora_client.rest_call(url: zuora_client.rest_endpoint("genesis/user/info").gsub('v1/', ''), session_type: :bearer)
415
- else
416
- client_describe = session["ZuoraCurrentUserInfo"]
417
- end
474
+ next_id = defined?(@appinstance) ? @appinstance.id : next_instance_id
475
+ if task_data.blank?
476
+ user = (ENV['DEIS_APP'] || "Application").split('-').map(&:capitalize).join(' ')
477
+ body = {
478
+ 'userId' => zuora_user_id,
479
+ 'entityIds' => [zuora_entity_id.unpack("a8a4a4a4a12").join('-')],
480
+ 'customAuthorities' => [],
481
+ 'additionalInformation' => {
482
+ 'description' => "This user is for #{user} application.",
483
+ 'name' => "#{user} API User #{next_id}"
484
+ }
485
+ }
486
+
487
+ oauth_response, response = zuora_client.rest_call(
488
+ method: :post,
489
+ body: body.to_json,
490
+ url: zuora_client.rest_endpoint("genesis/clients").gsub('v1/', ''),
491
+ session_type: zuora_client.class == ZuoraAPI::Oauth ? :bearer : :basic,
492
+ headers: auth_headers
493
+ )
494
+
495
+ new_zuora_client = ZuoraAPI::Oauth.new(url: "https://#{zuora_host}", oauth_client_id: oauth_response["clientId"], oauth_secret: oauth_response["clientSecret"] )
496
+ if session["ZuoraCurrentUserInfo"].blank?
497
+ client_describe, response = new_zuora_client.rest_call(url: zuora_client.rest_endpoint("genesis/user/info").gsub('v1/', ''), session_type: :bearer)
498
+ else
499
+ client_describe = session["ZuoraCurrentUserInfo"]
500
+ end
418
501
 
419
- available_entities = client_describe["accessibleEntities"].select {|entity| entity['id'] == zuora_entity_id}
420
- task_data = {
421
- "id": next_id,
422
- "name": client_describe["tenantName"],
423
- "mode": "Collections",
424
- "status": "Running",
425
- ZuoraConnect::AppInstance::LOGIN_TENANT_DESTINATION => {
426
- "tenant_type": "Zuora",
427
- "username": session["ZuoraCurrentIdentity"]["username"],
428
- "url": new_zuora_client.url,
429
- "status": "Active",
430
- "oauth_client_id": oauth_response['clientId'],
431
- "oauth_secret": oauth_response['clientSecret'],
432
- "authentication_type": "OAUTH",
433
- "entities": available_entities.map {|e| e.merge({'displayName' => client_describe["tenantName"]})}
434
- },
435
- "tenant_ids": available_entities.map{|e| e['entityId']}.uniq,
436
- }
437
- mapped_values = {:id => next_id, :api_token => rand(36**64).to_s(36), :token => rand(36**64).to_s(36), :zuora_logins => task_data, :oauth_expires_at => Time.now + 1000.years, :zuora_domain => zuora_client.rest_domain, :zuora_entity_ids => [zuora_entity_id]}
438
- @appinstance = ZuoraConnect::AppInstance.new(mapped_values)
439
- retry_count = 0
440
- begin
441
- @appinstance.save(:validate => false)
442
- rescue ActiveRecord::RecordNotUnique => ex
443
- if (retry_count += 1) < 3
444
- @appinstance.assign_attributes({:api_token => rand(36**64).to_s(36), :token => rand(36**64).to_s(36)})
445
- retry
502
+ available_entities = client_describe["accessibleEntities"].select {|entity| entity['id'] == zuora_entity_id}
503
+ task_data = {
504
+ "id": next_id,
505
+ "name": client_describe["tenantName"],
506
+ "mode": "Collections",
507
+ "status": "Running",
508
+ ZuoraConnect::AppInstance::LOGIN_TENANT_DESTINATION => {
509
+ "tenant_type": "Zuora",
510
+ "username": session["ZuoraCurrentIdentity"]["username"],
511
+ "url": new_zuora_client.url,
512
+ "status": "Active",
513
+ "oauth_client_id": oauth_response['clientId'],
514
+ "oauth_secret": oauth_response['clientSecret'],
515
+ "authentication_type": "OAUTH",
516
+ "entities": available_entities.map {|e| e.merge({'displayName' => client_describe["tenantName"]})}
517
+ },
518
+ "tenant_ids": available_entities.map{|e| e['entityId']}.uniq,
519
+ }
520
+ end
521
+
522
+ if defined?(@appinstance)
523
+ @appinstance.zuora_logins = task_data
524
+ @appinstance.save(:validate => false)
446
525
  else
447
- Thread.current[:appinstance] = nil
448
- session["appInstance"] = nil
449
- render "zuora_connect/static/error_handled", :locals => {
450
- :title => "Application could not create unique tokens.",
451
- :message => "Please contact support or retry launching application."
452
- }, :layout => false
453
- return
526
+ @appinstance = new_instance(
527
+ next_id,
528
+ zuora_entity_id,
529
+ zuora_client.rest_domain,
530
+ task_data: task_data,
531
+ retry_count: retry_count
532
+ )
454
533
  end
455
534
  end
535
+ rescue ActiveRecord::RecordNotUnique
536
+ retry if (retry_count -= 1).positive?
537
+ return
456
538
  end
457
539
 
458
540
  Apartment::Tenant.switch!("public")
@@ -540,6 +622,50 @@ module ZuoraConnect
540
622
  end
541
623
  end
542
624
 
625
+ def next_instance_id
626
+ min_instance_id = 24_999_999
627
+ (ZuoraConnect::AppInstance.all.where("id > #{min_instance_id}").order(id: :desc).limit(1).pluck(:id).first || min_instance_id) + 1
628
+ end
629
+
630
+ def new_instance(id, zuora_entity_id, rest_domain, task_data: nil, retry_count: 0)
631
+ app_instance = ZuoraConnect::AppInstance.new(
632
+ :id => id,
633
+ :api_token => generate_token,
634
+ :token => generate_token,
635
+ :oauth_expires_at => Time.now + 1000.years,
636
+ :zuora_domain => rest_domain,
637
+ :zuora_entity_ids => [zuora_entity_id]
638
+ )
639
+
640
+ if task_data.nil?
641
+ # no encryption
642
+ app_instance['zuora_logins'] = task_data
643
+ else
644
+ # kms encrypt
645
+ app_instance.zuora_logins = task_data
646
+ end
647
+
648
+ begin
649
+ app_instance.save(:validate => false)
650
+ rescue ActiveRecord::RecordNotUnique
651
+ raise if retry_count > 1
652
+
653
+ Thread.current[:appinstance] = nil
654
+ session['appInstance'] = nil
655
+ render 'zuora_connect/static/error_handled', :locals => {
656
+ :title => 'Application could not create unique tokens.',
657
+ :message => 'Please contact support or retry launching application.'
658
+ }, :layout => false
659
+ return
660
+ end
661
+
662
+ app_instance
663
+ end
664
+
665
+ def generate_token
666
+ rand(36**64).to_s(36)
667
+ end
668
+
543
669
  def setup_instance_via_dev_mode
544
670
  session["appInstance"] = ZuoraConnect.configuration.dev_mode_appinstance
545
671
  user = ZuoraConnect.configuration.dev_mode_user
@@ -1,3 +1,3 @@
1
1
  module ZuoraConnect
2
- VERSION = "2.0.58"
2
+ VERSION = "2.0.59a"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zuora_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.58
4
+ version: 2.0.59a
5
5
  platform: ruby
6
6
  authors:
7
7
  - Connect Team
@@ -429,9 +429,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
429
429
  version: '0'
430
430
  required_rubygems_version: !ruby/object:Gem::Requirement
431
431
  requirements:
432
- - - ">="
432
+ - - ">"
433
433
  - !ruby/object:Gem::Version
434
- version: '0'
434
+ version: 1.3.1
435
435
  requirements: []
436
436
  rubygems_version: 3.0.3
437
437
  signing_key: