zuora_connect 2.0.59 → 2.0.60a

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: 98cdc050053f90626d6df8e259de4ff0089091d968f94da492b30dadd1e60afb
4
- data.tar.gz: f0517e432e3554c4d751419889c01899fcaf4c6b04febd093b29a7eb02089344
3
+ metadata.gz: b422585e16ec26ecaf39bf40095d9067c162bf23e8d4d5ce12889e653d8da5f1
4
+ data.tar.gz: bb96e31845214e4a77274ec8afbd6d5c0a95e11701e842d74616f95ba6fcdf3d
5
5
  SHA512:
6
- metadata.gz: 5f3f2ead635cb47c3d42aa1415b30d1405553553b9bc3a3b387061974309c7525f1755ae4546084d4406174cd0e4c051c3b596e101f5d3134360f55d328147c5
7
- data.tar.gz: 3a579ea74120c205588cc62af5d8eef28266a0ddf85e4a8ead2b07bbcd4b4ee1ec9c8b39079a58b48473d2f107d72389eea017cbb667aef22e6db9f647087354
6
+ metadata.gz: '078c3ab13f7bb7ad02fa09ebee0b52608e8e40c361b0ca112a3f69cdb06a12e5e834aff0b618c990fe839dda4df8b305324cd6750f9a5a3ae9138c54fee63953'
7
+ data.tar.gz: 92a9e8797ec7d3fa5e6da94309bacfa412cb20cab9a5f6be751f2ccdea5578155492a72e7aa47c58e8b92284a620f52d7fa92f4d6f5f6522cf72b0c4de0f67ea
@@ -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
@@ -47,7 +47,7 @@ module Resque
47
47
  raise
48
48
  end
49
49
  rescue PG::ConnectionBad => exception
50
- Rails.logger.info("Bad Connection Restart")
50
+ Rails.logger.warn("Bad Connection Restart", exception)
51
51
  Resque.enqueue_to(self.job.queue, self.job.payload['class'], args)
52
52
  return
53
53
  rescue ZuoraConnect::Exceptions::ConnectCommunicationError => exception
@@ -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 = {}
@@ -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.59"
2
+ VERSION = "2.0.60a"
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.59
4
+ version: 2.0.60a
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-06-26 00:00:00.000000000 Z
11
+ date: 2020-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: apartment
@@ -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: