zuora_connect 2.0.57zb → 2.0.57zc

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: dff6ce91c55f80094866e0149b3043f112cdcf9ec1a7fc19f94429ed23dd9ab0
4
- data.tar.gz: b5db9f1464450a0ea7c08ef170bc3a675d5e2aa106525ff0a1d0437baa87b73e
3
+ metadata.gz: 0f5d12d5e34b5917eaf15c805ea90654725699822cb086f3461a20cd67401552
4
+ data.tar.gz: c00aed1135d2ce2efa0380f2079af2688fdbec7062f827931356ccacf9a4320c
5
5
  SHA512:
6
- metadata.gz: 2abb08d555d8754e1f83160e13c88d1ecd794b875aa53a5cd4b59adf7ca471cad6898b8a1d10d39383bba3246e08893e3b21a971a94ee9253ce5e7726127ecd5
7
- data.tar.gz: 24157ed2e3f4bd760cbabfb1876bb6bc294986cda03137ebaa9f3d3fcbe6849c3ffcdd2ee088aed65bf975a54e951f5759c0e2cc2e0437fc7eae0738e387c024
6
+ metadata.gz: 7d01328db6ff56b2ae3470c7aa027a53f46ee4ab0802a0344d4bc6bb27afdba0147b257cfc92a8977a778e6af84cec8c1a80cd169fbbb8ba6f15efacfcf2135a
7
+ data.tar.gz: cce5a5fbbc65781d1cd17764c1b6d889b40b7eda3bfb5d5a491b961494a2789f3a8c04c1478ff53fb2901b58c249991b68cea315ef0b5d36ec86802a10d83000
@@ -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
data/config/routes.rb CHANGED
@@ -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,12 +346,12 @@ 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_same_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']
279
353
  session["ZSession"] = cookies['ZSession']
280
- unless is_same_user && !params[:sidebar_launch].to_s.to_bool
354
+ if is_different_user || params[:sidebar_launch].to_s.to_bool
281
355
  zuora_instance_id = nil
282
356
  ZuoraConnect.logger.debug("UI Authorization", zuora: zuora_details)
283
357
 
@@ -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'].present?
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
501
+
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
418
521
 
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
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,43 @@ 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
+ :zuora_logins => task_data,
636
+ :oauth_expires_at => Time.now + 1000.years,
637
+ :zuora_domain => rest_domain,
638
+ :zuora_entity_ids => [zuora_entity_id]
639
+ )
640
+
641
+ begin
642
+ app_instance.save(:validate => false)
643
+ rescue ActiveRecord::RecordNotUnique
644
+ raise if retry_count > 1
645
+
646
+ Thread.current[:appinstance] = nil
647
+ session['appInstance'] = nil
648
+ render 'zuora_connect/static/error_handled', :locals => {
649
+ :title => 'Application could not create unique tokens.',
650
+ :message => 'Please contact support or retry launching application.'
651
+ }, :layout => false
652
+ return
653
+ end
654
+
655
+ app_instance
656
+ end
657
+
658
+ def generate_token
659
+ rand(36**64).to_s(36)
660
+ end
661
+
543
662
  def setup_instance_via_dev_mode
544
663
  session["appInstance"] = ZuoraConnect.configuration.dev_mode_appinstance
545
664
  user = ZuoraConnect.configuration.dev_mode_user
@@ -1,3 +1,3 @@
1
1
  module ZuoraConnect
2
- VERSION = "2.0.57zb"
2
+ VERSION = "2.0.57zc"
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.57zb
4
+ version: 2.0.57zc
5
5
  platform: ruby
6
6
  authors:
7
7
  - Connect Team