zuora_connect 3.1.0 → 3.1.1.pre.a

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: 689c9d74cda46ebd41a5d98dba982700dd365fa3746378276ceb0da4f5d0c493
4
- data.tar.gz: 719e7beb03b156986160f8fa881960a7b7231b706c9a6bcd50af1788d622a125
3
+ metadata.gz: 575850a90d1e2c6aaca6a638ce4c353f337c617d3ff1460731b48a208d8942c1
4
+ data.tar.gz: 5e2a26d1ff920f57243bca6cd1de689158d0c996bb31b6c3793c9d004572d248
5
5
  SHA512:
6
- metadata.gz: 4f905b5518a0b7e556d3cf4a45e73e86b149a4b95d111a315e46a2f91e9a07b43b2e9b77f0bd1c34e6fbf5848d321b64615ec612fc907b7f3fb9fd2f56944be3
7
- data.tar.gz: a61a9c662b80a4d8af8a98f6eeef2be56b79cc9bc0853ae36a57ce22a59dde8bae5a7ab1b175aedec703743b6ccae8e81f2e565b028a23cdda9b7dce7544eb1a
6
+ metadata.gz: e5592409632f985f3db6c42c2cc4c28e86ad7daed2f359ef08e4cb503efdef0095388a62f48832a1498f9ce7d7f8bdccc0155af1a4d68dc32412ae061dec45c4
7
+ data.tar.gz: 12c7cdb0591645a712ee19ead68473d8a67763c8b88dcb02e9b2195112577b898636079c681a164ea6e3bbd1d03a37c0af5c7941caa93946ef391fbf7ba69ef1
@@ -187,7 +187,7 @@ module ZuoraConnect
187
187
  raise ZuoraConnect::Exceptions::HoldingPattern if holding_pattern && !self.mark_for_refresh
188
188
  self.refresh(session: session)
189
189
 
190
- elsif session["#{self.id}::task_data"].blank?
190
+ elsif session["#{self.id}::task_data"].blank? && !ZuoraConnect.configuration.local_task_data
191
191
  self.new_session_message = "REFRESHING - Task Data Blank"
192
192
  ZuoraConnect.logger.debug(self.new_session_message)
193
193
  raise ZuoraConnect::Exceptions::HoldingPattern if holding_pattern && !self.mark_for_refresh
@@ -354,7 +354,8 @@ module ZuoraConnect
354
354
 
355
355
  def fetch_connect_data(session: {})
356
356
  self.check_oauth_state
357
- response = HTTParty.get(ZuoraConnect.configuration.url + "/api/#{self.api_version}/tools/tasks/#{self.id}.json",:body => {:access_token => self.access_token})
357
+ request_url = ZuoraConnect.configuration.url + "/api/#{self.api_version}/tools/tasks/#{self.id}.json"
358
+ response = HTTParty.get(request_url,:body => {:access_token => self.access_token})
358
359
 
359
360
  if response.code == 200
360
361
  begin
@@ -367,7 +368,7 @@ module ZuoraConnect
367
368
  self.set_backup_creds
368
369
  self.save(validate: false) if self.changed?
369
370
  else
370
- raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("Error Communicating with Connect", response.body, response.code)
371
+ raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("Error communicating with Connect for '#{request_url}' with #{response.code}", response.body, response.code)
371
372
  end
372
373
  end
373
374
 
@@ -416,10 +417,6 @@ module ZuoraConnect
416
417
  raise
417
418
  end
418
419
 
419
- def aws_secrets
420
- (Rails.application.secrets.aws || {}).transform_keys { |key| key.to_s }
421
- end
422
-
423
420
  #### START KMS ENCRYPTION Methods ####
424
421
  def set_backup_creds
425
422
  if self.kms_key.present? && self.kms_key.match(/^arn:aws:.*/) && self.task_data.present?
@@ -435,14 +432,105 @@ module ZuoraConnect
435
432
 
436
433
  def zuora_logins
437
434
  raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("Zuora Logins is blank, cannot decrypt.") if super.blank?
438
- return JSON.parse(kms_decrypt(super))
435
+ return JSON.parse(kms_decrypt(super, field_name: :zuora_logins))
436
+ end
437
+
438
+ def kms_client
439
+ @kms_client ||= Aws::KMS::Client.new({region: aws_secrets['AWS_REGION'], credentials: self.aws_auth_client}.delete_if { |k, v| v.blank? })
440
+ return @kms_client
441
+ end
442
+
443
+ def decrypted_data_key
444
+ $cleartextkey ||= kms_client.decrypt(ciphertext_blob: Base64.strict_decode64(encrypted_data_key)).plaintext
445
+ return $cleartextkey
446
+ end
447
+
448
+ def aws_secrets
449
+ (Rails.application.secrets.aws || {}).transform_keys { |key| key.to_s }
450
+ end
451
+
452
+ def connect_secrets
453
+ (Rails.application.secrets.connect || {}).transform_keys { |key| key.to_s }
454
+ end
455
+
456
+ def kms_key(raise_on_blank: false)
457
+ kms_value = ENV['AWS_KMS_ARN'] || aws_secrets['AWS_KMS_ARN']
458
+ raise ZuoraConnect::Exceptions::Error.new("Missing KMS key") if raise_on_blank && kms_value.blank?
459
+ return kms_value
460
+ end
461
+
462
+ def iv_key
463
+ iv_key_value = ENV['IV_KEY'] || connect_secrets['IV_KEY']
464
+ #Create new one 'Base64.strict_encode64(OpenSSL::Cipher.new('AES-256-CBC').random_iv)'
465
+ raise ZuoraConnect::Exceptions::Error.new("Missing IV cipher key") if iv_key_value.blank?
466
+ return iv_key_value
467
+ end
468
+
469
+ def encrypted_data_key
470
+ #Base64.strict_encode64(kms_client.generate_data_key(key_id: kms_key, key_spec: 'AES_256').ciphertext_blob)
471
+ encrypted_data_key_value = ENV['ENCRYPTED_DATA_KEY'] || connect_secrets['ENCRYPTED_DATA_KEY']
472
+ raise ZuoraConnect::Exceptions::Error.new("Missing encrypted data key 'ENCRYPTED_DATA_KEY'.") if encrypted_data_key_value.blank?
473
+ return encrypted_data_key_value
474
+ end
475
+
476
+ def aws_auth_client
477
+ if Rails.env.to_s == 'development'
478
+ return Aws::Credentials.new(aws_secrets['AWS_ACCESS_KEY_ID'], aws_secrets['AWS_SECRET_ACCESS_KEY'])
479
+ else
480
+ return nil
481
+ end
482
+ end
483
+
484
+ def fetch_cipher(type)
485
+ raise "Type must be set to 'encrypt' or 'decrypt'" if !['decrypt','encrypt'].include?(type)
486
+ cipher = OpenSSL::Cipher.new('AES-256-CBC')
487
+ cipher.send(type)
488
+ cipher.key = self.decrypted_data_key
489
+ cipher.iv = Base64.strict_decode64(self.iv_key)
490
+ return cipher
439
491
  end
440
492
 
441
- def kms_decrypt(value)
493
+ def kms_decrypt(value, field_name: nil, encryption_type: ZuoraConnect.configuration.encryption_type)
442
494
  kms_tries ||= 0
443
- kms_client = Aws::KMS::Client.new({region: aws_secrets['AWS_REGION'], credentials: self.aws_auth_client}.delete_if { |k, v| v.blank? })
444
- resp = kms_client.decrypt({ciphertext_blob: [value].pack("H*") })
445
- return resp.plaintext
495
+ original_encryption_type ||= encryption_type.dup
496
+
497
+ case encryption_type
498
+ when :direct
499
+ result = kms_client.decrypt(ciphertext_blob: [value].pack("H*") ).plaintext
500
+ #Update original encryption
501
+ if original_encryption_type != encryption_type && field_name.present?
502
+ ZuoraConnect.logger.debug("Updating encryption to '#{original_encryption_type}', from '#{encryption_type}' for field '#{field_name}'", self.default_ougai_items)
503
+ self.update_column(field_name, self.kms_encrypt(result, encryption_type: original_encryption_type))
504
+ end
505
+
506
+ return result
507
+ when :envelope
508
+ cipher = fetch_cipher('decrypt')
509
+ result = cipher.update(Base64.strict_decode64(value)) + cipher.final
510
+
511
+ #Update original encryption
512
+ if original_encryption_type != encryption_type && field_name.present?
513
+ ZuoraConnect.logger.debug("Updating encryption to '#{original_encryption_type}', from '#{encryption_type}' for field '#{field_name}'", self.default_ougai_items)
514
+ self.update_column(field_name, self.kms_encrypt(result, encryption_type: original_encryption_type))
515
+ end
516
+ return result
517
+ else
518
+ ZuoraConnect::Exceptions::Error.new("Invalid encryption method '#{encryption_type}'.")
519
+ end
520
+ rescue ArgumentError => ex
521
+ if ex.message == 'invalid base64' && encryption_type == :envelope && (kms_tries += 1) < 3
522
+ ZuoraConnect.logger.warn("Fallback to encryption 'direct', from '#{encryption_type}'", ex, self.default_ougai_items)
523
+ encryption_type = :direct
524
+ retry
525
+ end
526
+ raise#Add protection when decrypting
527
+ rescue Aws::KMS::Errors::InvalidCiphertextException => ex
528
+ if encryption_type == :direct && (kms_tries += 1) < 3
529
+ ZuoraConnect.logger.warn("Fallback to encryption 'envelope', from '#{encryption_type}'", ex, self.default_ougai_items)
530
+ encryption_type = :envelope
531
+ retry
532
+ end
533
+ raise
446
534
  rescue *AWS_AUTH_ERRORS => ex
447
535
  if (kms_tries += 1) < 3
448
536
  Rails.logger.warn(AWS_AUTH_ERRORS_MSG, ex)
@@ -453,12 +541,20 @@ module ZuoraConnect
453
541
  end
454
542
  end
455
543
 
456
- def kms_encrypt(value)
544
+ def kms_encrypt(value, encryption_type: ZuoraConnect.configuration.encryption_type)
457
545
  kms_tries ||= 0
458
- kms_client = Aws::KMS::Client.new({region: aws_secrets['AWS_REGION'], credentials: self.aws_auth_client}.delete_if {|k,v| v.blank? })
459
-
460
- resp = kms_client.encrypt({key_id: kms_key, plaintext: value})
461
- return resp.ciphertext_blob.unpack('H*').first
546
+ case encryption_type
547
+ when :direct
548
+ resp = kms_client.encrypt({key_id: kms_key(raise_on_blank: true), plaintext: value})
549
+ return resp.ciphertext_blob.unpack('H*').first
550
+ when :envelope
551
+ cipher = fetch_cipher('encrypt')
552
+ value = cipher.update(value.to_s)
553
+ value << cipher.final
554
+ return Base64.strict_encode64(value)
555
+ else
556
+ ZuoraConnect::Exceptions::Error.new("Invalid encryption method '#{encryption_type}'.")
557
+ end
462
558
  rescue *AWS_AUTH_ERRORS => ex
463
559
  if (kms_tries += 1) < 3
464
560
  Rails.logger.warn(AWS_AUTH_ERRORS_MSG, ex)
@@ -468,18 +564,6 @@ module ZuoraConnect
468
564
  raise
469
565
  end
470
566
  end
471
-
472
- def kms_key
473
- return ENV['AWS_KMS_ARN'] || aws_secrets['AWS_KMS_ARN']
474
- end
475
-
476
- def aws_auth_client
477
- if Rails.env.to_s == 'development'
478
- return Aws::Credentials.new(aws_secrets['AWS_ACCESS_KEY_ID'], aws_secrets['AWS_SECRET_ACCESS_KEY'])
479
- else
480
- return nil
481
- end
482
- end
483
567
  #### END KMS ENCRYPTION Methods ####
484
568
 
485
569
  #### START Metrics Methods ####
@@ -505,9 +589,13 @@ module ZuoraConnect
505
589
  def build_task(task_data: {}, session: {})
506
590
  session = {} if session.blank?
507
591
  self.task_data = task_data
592
+ if self.task_data.blank? && ZuoraConnect.configuration.local_task_data
593
+ self.task_data = self.zuora_logins
594
+ end
595
+
508
596
  self.mode = self.task_data["mode"]
509
597
 
510
- if task_data['id'].to_s != self.id.to_s
598
+ if self.task_data['id'].to_s != self.id.to_s
511
599
  raise ZuoraConnect::Exceptions::MissMatch.new("Wrong Instance Identifier/Lookup")
512
600
  end
513
601
 
@@ -545,7 +633,7 @@ module ZuoraConnect
545
633
  raise
546
634
  rescue => ex
547
635
  ZuoraConnect.logger.error("Build Task Error", ex)
548
- ZuoraConnect.logger.error("Task Data: #{task_data}") if task_data.present?
636
+ ZuoraConnect.logger.error("Task Data: #{self.task_data}") if self.task_data.present?
549
637
  if session.present?
550
638
  ZuoraConnect.logger.error("Task Session: #{session.to_h}") if session.methods.include?(:to_h)
551
639
  ZuoraConnect.logger.error("Task Session: #{session.to_hash}") if session.methods.include?(:to_hash)
@@ -796,19 +884,19 @@ module ZuoraConnect
796
884
  if login.tenant_type == "Zuora"
797
885
  if login.available_entities.size > 1 && Rails.application.config.session_store != ActionDispatch::Session::CookieStore
798
886
  login.available_entities.each do |entity_key|
799
- session["#{self.id}::#{key}::#{entity_key}:current_session"] = login.client(entity_key).current_session if login.client.respond_to?(:current_session)
800
- session["#{self.id}::#{key}::#{entity_key}:bearer_token"] = login.client(entity_key).bearer_token if login.client.respond_to?(:bearer_token)
801
- session["#{self.id}::#{key}::#{entity_key}:oauth_session_expires_at"] = login.client(entity_key).oauth_session_expires_at if login.client.respond_to?(:oauth_session_expires_at)
887
+ session["#{self.id}::#{key}::#{entity_key}:current_session"] = login.client(entity_key).current_session if login.client.respond_to?(:current_session) && login.client(entity_key).current_session.present?
888
+ session["#{self.id}::#{key}::#{entity_key}:bearer_token"] = login.client(entity_key).bearer_token if login.client.respond_to?(:bearer_token) && login.client(entity_key).bearer_token.present?
889
+ session["#{self.id}::#{key}::#{entity_key}:oauth_session_expires_at"] = login.client(entity_key).oauth_session_expires_at if login.client.respond_to?(:oauth_session_expires_at) && login.client(entity_key).oauth_session_expires_at.present?
802
890
  end
803
891
  else
804
- session["#{self.id}::#{key}:current_session"] = login.client.current_session if login.client.respond_to?(:current_session)
805
- session["#{self.id}::#{key}:bearer_token"] = login.client.bearer_token if login.client.respond_to?(:bearer_token)
806
- session["#{self.id}::#{key}:oauth_session_expires_at"] = login.client.oauth_session_expires_at if login.client.respond_to?(:oauth_session_expires_at)
892
+ session["#{self.id}::#{key}:current_session"] = login.client.current_session if login.client.respond_to?(:current_session) && login.client.current_session.present?
893
+ session["#{self.id}::#{key}:bearer_token"] = login.client.bearer_token if login.client.respond_to?(:bearer_token) && login.client.bearer_token.present?
894
+ session["#{self.id}::#{key}:oauth_session_expires_at"] = login.client.oauth_session_expires_at if login.client.respond_to?(:oauth_session_expires_at) && login.client.oauth_session_expires_at.present?
807
895
  end
808
896
  end
809
897
  end
810
898
 
811
- session["#{self.id}::task_data"] = self.task_data
899
+ session["#{self.id}::task_data"] = self.task_data if !ZuoraConnect.configuration.local_task_data
812
900
 
813
901
  #Redis is not defined strip out old data
814
902
  if !defined?(Redis.current)
@@ -848,6 +936,9 @@ module ZuoraConnect
848
936
  else
849
937
  begin
850
938
  return JSON.parse(encryptor.decrypt_and_verify(CGI::unescape(data)))
939
+ rescue ActiveSupport::MessageEncryptor::InvalidMessage => ex
940
+ Rails.logger.error('Error Decrypting', ex, self.default_ougai_items) if log_fatal && !Rails.env.test?
941
+ return JSON.parse(encryptor.decrypt_and_verify(data))
851
942
  rescue ActiveSupport::MessageVerifier::InvalidSignature => ex
852
943
  ZuoraConnect.logger.error("Error Decrypting", ex, self.default_ougai_items) if log_fatal
853
944
  return rescue_return
@@ -11,6 +11,15 @@ class RedisFlash
11
11
  end
12
12
  end
13
13
 
14
+ class Redis
15
+ def self.current
16
+ @current ||= Redis.new()
17
+ end
18
+ def self.current=(redis)
19
+ @current = redis
20
+ end
21
+ end
22
+
14
23
  if defined?(Redis.current)
15
24
  Redis.current = Redis.new(:id => "#{ZuoraObservability::Env.full_process_name(process_name: 'Redis')}", :url => redis_url, :timeout => 6, :reconnect_attempts => 2)
16
25
  browser_urls['Redis'] = { "url" => redis_url }
@@ -9,5 +9,8 @@ class AddEnvironmentFields < ActiveRecord::Migration[5.0]
9
9
  if column_exists? :zuora_connect_app_instances, :organizations
10
10
  change_column :zuora_connect_app_instances, :organizations, :jsonb, default: []
11
11
  end
12
+ unless column_exists? :zuora_connect_app_instances, :zuora_global_tenant_id
13
+ add_column :zuora_connect_app_instances, :zuora_global_tenant_id, :text, default: ""
14
+ end
12
15
  end
13
16
  end
@@ -1,24 +1,16 @@
1
- # desc "Explaining what the task does"
2
- # task :connect do
3
- # # Task goes here
4
- # end
5
-
6
1
  namespace :db do
7
2
  desc 'Also create shared_extensions Schema'
8
3
  task :extensions => :environment do
9
4
  # Create Schema
10
- ActiveRecord::Base.connection.execute 'CREATE SCHEMA IF NOT EXISTS shared_extensions;'
11
- # Enable Hstore
12
- ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS HSTORE SCHEMA shared_extensions;'
13
- # Enable UUID-OSSP
14
- ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp" SCHEMA shared_extensions;'
5
+ at_exit {
6
+ ActiveRecord::Base.connection.execute 'CREATE SCHEMA IF NOT EXISTS shared_extensions;'
7
+ # Enable Hstore
8
+ ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS HSTORE SCHEMA shared_extensions;'
9
+ # Enable UUID-OSSP
10
+ ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp" SCHEMA shared_extensions;'
11
+ }
15
12
  end
16
13
  end
17
14
 
18
- Rake::Task["db:create"].enhance do
19
- Rake::Task["db:extensions"].invoke
20
- end
21
-
22
- Rake::Task["db:test:purge"].enhance do
23
- Rake::Task["db:extensions"].invoke
24
- end
15
+ Rake::Task["db:create"].enhance [:extensions]
16
+ Rake::Task["db:test:purge"].enhance [:extensions]
@@ -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, :insert_migrations, :skip_connect
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, :insert_migrations, :skip_connect, :encryption_type, :local_task_data
11
11
 
12
12
  def initialize
13
13
  @default_locale = :en
@@ -21,6 +21,8 @@ module ZuoraConnect
21
21
  @blpop_queue = false
22
22
  @insert_migrations = true
23
23
  @skip_connect = false
24
+ @encryption_type = :direct
25
+ @local_task_data = false
24
26
 
25
27
  # Setting the app name for telegraf write
26
28
  @enable_metrics = false
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ZuoraConnect
4
- VERSION = "3.1.0"
4
+ VERSION = "3.1.1-a"
5
5
  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: 3.1.0
4
+ version: 3.1.1.pre.a
5
5
  platform: ruby
6
6
  authors:
7
7
  - Connect Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-23 00:00:00.000000000 Z
11
+ date: 2022-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: apartment
@@ -452,9 +452,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
452
452
  version: '0'
453
453
  required_rubygems_version: !ruby/object:Gem::Requirement
454
454
  requirements:
455
- - - ">="
455
+ - - ">"
456
456
  - !ruby/object:Gem::Version
457
- version: '0'
457
+ version: 1.3.1
458
458
  requirements: []
459
459
  rubygems_version: 3.3.7
460
460
  signing_key: