zuora_connect 3.1.0 → 3.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/zuora_connect/app_instance_base.rb +126 -36
- data/config/initializers/redis.rb +9 -0
- data/db/migrate/20190520232224_add_environment_fields.rb +3 -0
- data/lib/tasks/zuora_connect_tasks.rake +9 -17
- data/lib/zuora_connect/configuration.rb +3 -1
- data/lib/zuora_connect/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5eedfed1cc9d304e303303bbda985be007df987f6c50c8cebf4bef6ee2f630a2
|
4
|
+
data.tar.gz: 77bbf5a323c63814cb50521ffd244c601b40e3f5c07bc8208f9996b83fe5090e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 519cf6f3002ff33a5849e297e74ccd7a541a9677fdbf28e7481848d3ef74f2521555c129fa215db87dc5565fa7c0afa4ea3ce19c6555ad0bec8878fe41d48d78
|
7
|
+
data.tar.gz: 6db95ad4869e55739c648492a830054c8f59b574a6ddabf80b8de24ff1e67356e7df492fcf742a6afea5bb65f34f215252dd2466d5c264578c5c0cd224866fe4
|
@@ -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
|
@@ -416,10 +416,6 @@ module ZuoraConnect
|
|
416
416
|
raise
|
417
417
|
end
|
418
418
|
|
419
|
-
def aws_secrets
|
420
|
-
(Rails.application.secrets.aws || {}).transform_keys { |key| key.to_s }
|
421
|
-
end
|
422
|
-
|
423
419
|
#### START KMS ENCRYPTION Methods ####
|
424
420
|
def set_backup_creds
|
425
421
|
if self.kms_key.present? && self.kms_key.match(/^arn:aws:.*/) && self.task_data.present?
|
@@ -435,14 +431,105 @@ module ZuoraConnect
|
|
435
431
|
|
436
432
|
def zuora_logins
|
437
433
|
raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("Zuora Logins is blank, cannot decrypt.") if super.blank?
|
438
|
-
return JSON.parse(kms_decrypt(super))
|
434
|
+
return JSON.parse(kms_decrypt(super, field_name: :zuora_logins))
|
435
|
+
end
|
436
|
+
|
437
|
+
def kms_client
|
438
|
+
@kms_client ||= Aws::KMS::Client.new({region: aws_secrets['AWS_REGION'], credentials: self.aws_auth_client}.delete_if { |k, v| v.blank? })
|
439
|
+
return @kms_client
|
440
|
+
end
|
441
|
+
|
442
|
+
def decrypted_data_key
|
443
|
+
$cleartextkey ||= kms_client.decrypt(ciphertext_blob: Base64.strict_decode64(encrypted_data_key)).plaintext
|
444
|
+
return $cleartextkey
|
445
|
+
end
|
446
|
+
|
447
|
+
def aws_secrets
|
448
|
+
(Rails.application.secrets.aws || {}).transform_keys { |key| key.to_s }
|
449
|
+
end
|
450
|
+
|
451
|
+
def connect_secrets
|
452
|
+
(Rails.application.secrets.connect || {}).transform_keys { |key| key.to_s }
|
453
|
+
end
|
454
|
+
|
455
|
+
def kms_key(raise_on_blank: false)
|
456
|
+
kms_value = ENV['AWS_KMS_ARN'] || aws_secrets['AWS_KMS_ARN']
|
457
|
+
raise ZuoraConnect::Exceptions::Error.new("Missing KMS key") if raise_on_blank && kms_value.blank?
|
458
|
+
return kms_value
|
459
|
+
end
|
460
|
+
|
461
|
+
def iv_key
|
462
|
+
iv_key_value = ENV['IV_KEY'] || connect_secrets['IV_KEY']
|
463
|
+
#Create new one 'Base64.strict_encode64(OpenSSL::Cipher.new('AES-256-CBC').random_iv)'
|
464
|
+
raise ZuoraConnect::Exceptions::Error.new("Missing IV cipher key") if iv_key_value.blank?
|
465
|
+
return iv_key_value
|
466
|
+
end
|
467
|
+
|
468
|
+
def encrypted_data_key
|
469
|
+
#Base64.strict_encode64(kms_client.generate_data_key(key_id: kms_key, key_spec: 'AES_256').ciphertext_blob)
|
470
|
+
encrypted_data_key_value = ENV['ENCRYPTED_DATA_KEY'] || connect_secrets['ENCRYPTED_DATA_KEY']
|
471
|
+
raise ZuoraConnect::Exceptions::Error.new("Missing encrypted data key 'ENCRYPTED_DATA_KEY'.") if encrypted_data_key_value.blank?
|
472
|
+
return encrypted_data_key_value
|
473
|
+
end
|
474
|
+
|
475
|
+
def aws_auth_client
|
476
|
+
if Rails.env.to_s == 'development'
|
477
|
+
return Aws::Credentials.new(aws_secrets['AWS_ACCESS_KEY_ID'], aws_secrets['AWS_SECRET_ACCESS_KEY'])
|
478
|
+
else
|
479
|
+
return nil
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
def fetch_cipher(type)
|
484
|
+
raise "Type must be set to 'encrypt' or 'decrypt'" if !['decrypt','encrypt'].include?(type)
|
485
|
+
cipher = OpenSSL::Cipher.new('AES-256-CBC')
|
486
|
+
cipher.send(type)
|
487
|
+
cipher.key = self.decrypted_data_key
|
488
|
+
cipher.iv = Base64.strict_decode64(self.iv_key)
|
489
|
+
return cipher
|
439
490
|
end
|
440
491
|
|
441
|
-
def kms_decrypt(value)
|
492
|
+
def kms_decrypt(value, field_name: nil, encryption_type: ZuoraConnect.configuration.encryption_type)
|
442
493
|
kms_tries ||= 0
|
443
|
-
|
444
|
-
|
445
|
-
|
494
|
+
original_encryption_type ||= encryption_type.dup
|
495
|
+
|
496
|
+
case encryption_type
|
497
|
+
when :direct
|
498
|
+
result = kms_client.decrypt(ciphertext_blob: [value].pack("H*") ).plaintext
|
499
|
+
#Update original encryption
|
500
|
+
if original_encryption_type != encryption_type && field_name.present?
|
501
|
+
ZuoraConnect.logger.debug("Updating encryption to '#{original_encryption_type}', from '#{encryption_type}' for field '#{field_name}'", self.default_ougai_items)
|
502
|
+
self.update_column(field_name, self.kms_encrypt(result, encryption_type: original_encryption_type))
|
503
|
+
end
|
504
|
+
|
505
|
+
return result
|
506
|
+
when :envelope
|
507
|
+
cipher = fetch_cipher('decrypt')
|
508
|
+
result = cipher.update(Base64.strict_decode64(value)) + cipher.final
|
509
|
+
|
510
|
+
#Update original encryption
|
511
|
+
if original_encryption_type != encryption_type && field_name.present?
|
512
|
+
ZuoraConnect.logger.debug("Updating encryption to '#{original_encryption_type}', from '#{encryption_type}' for field '#{field_name}'", self.default_ougai_items)
|
513
|
+
self.update_column(field_name, self.kms_encrypt(result, encryption_type: original_encryption_type))
|
514
|
+
end
|
515
|
+
return result
|
516
|
+
else
|
517
|
+
ZuoraConnect::Exceptions::Error.new("Invalid encryption method '#{encryption_type}'.")
|
518
|
+
end
|
519
|
+
rescue ArgumentError => ex
|
520
|
+
if ex.message == 'invalid base64' && encryption_type == :envelope && (kms_tries += 1) < 3
|
521
|
+
ZuoraConnect.logger.warn("Fallback to encryption 'direct', from '#{encryption_type}'", ex, self.default_ougai_items)
|
522
|
+
encryption_type = :direct
|
523
|
+
retry
|
524
|
+
end
|
525
|
+
raise#Add protection when decrypting
|
526
|
+
rescue Aws::KMS::Errors::InvalidCiphertextException => ex
|
527
|
+
if encryption_type == :direct && (kms_tries += 1) < 3
|
528
|
+
ZuoraConnect.logger.warn("Fallback to encryption 'envelope', from '#{encryption_type}'", ex, self.default_ougai_items)
|
529
|
+
encryption_type = :envelope
|
530
|
+
retry
|
531
|
+
end
|
532
|
+
raise
|
446
533
|
rescue *AWS_AUTH_ERRORS => ex
|
447
534
|
if (kms_tries += 1) < 3
|
448
535
|
Rails.logger.warn(AWS_AUTH_ERRORS_MSG, ex)
|
@@ -453,12 +540,20 @@ module ZuoraConnect
|
|
453
540
|
end
|
454
541
|
end
|
455
542
|
|
456
|
-
def kms_encrypt(value)
|
543
|
+
def kms_encrypt(value, encryption_type: ZuoraConnect.configuration.encryption_type)
|
457
544
|
kms_tries ||= 0
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
545
|
+
case encryption_type
|
546
|
+
when :direct
|
547
|
+
resp = kms_client.encrypt({key_id: kms_key(raise_on_blank: true), plaintext: value})
|
548
|
+
return resp.ciphertext_blob.unpack('H*').first
|
549
|
+
when :envelope
|
550
|
+
cipher = fetch_cipher('encrypt')
|
551
|
+
value = cipher.update(value.to_s)
|
552
|
+
value << cipher.final
|
553
|
+
return Base64.strict_encode64(value)
|
554
|
+
else
|
555
|
+
ZuoraConnect::Exceptions::Error.new("Invalid encryption method '#{encryption_type}'.")
|
556
|
+
end
|
462
557
|
rescue *AWS_AUTH_ERRORS => ex
|
463
558
|
if (kms_tries += 1) < 3
|
464
559
|
Rails.logger.warn(AWS_AUTH_ERRORS_MSG, ex)
|
@@ -468,18 +563,6 @@ module ZuoraConnect
|
|
468
563
|
raise
|
469
564
|
end
|
470
565
|
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
566
|
#### END KMS ENCRYPTION Methods ####
|
484
567
|
|
485
568
|
#### START Metrics Methods ####
|
@@ -505,9 +588,13 @@ module ZuoraConnect
|
|
505
588
|
def build_task(task_data: {}, session: {})
|
506
589
|
session = {} if session.blank?
|
507
590
|
self.task_data = task_data
|
591
|
+
if self.task_data.blank? && ZuoraConnect.configuration.local_task_data
|
592
|
+
self.task_data = self.zuora_logins
|
593
|
+
end
|
594
|
+
|
508
595
|
self.mode = self.task_data["mode"]
|
509
596
|
|
510
|
-
if task_data['id'].to_s != self.id.to_s
|
597
|
+
if self.task_data['id'].to_s != self.id.to_s
|
511
598
|
raise ZuoraConnect::Exceptions::MissMatch.new("Wrong Instance Identifier/Lookup")
|
512
599
|
end
|
513
600
|
|
@@ -545,7 +632,7 @@ module ZuoraConnect
|
|
545
632
|
raise
|
546
633
|
rescue => ex
|
547
634
|
ZuoraConnect.logger.error("Build Task Error", ex)
|
548
|
-
ZuoraConnect.logger.error("Task Data: #{task_data}") if task_data.present?
|
635
|
+
ZuoraConnect.logger.error("Task Data: #{self.task_data}") if self.task_data.present?
|
549
636
|
if session.present?
|
550
637
|
ZuoraConnect.logger.error("Task Session: #{session.to_h}") if session.methods.include?(:to_h)
|
551
638
|
ZuoraConnect.logger.error("Task Session: #{session.to_hash}") if session.methods.include?(:to_hash)
|
@@ -796,19 +883,19 @@ module ZuoraConnect
|
|
796
883
|
if login.tenant_type == "Zuora"
|
797
884
|
if login.available_entities.size > 1 && Rails.application.config.session_store != ActionDispatch::Session::CookieStore
|
798
885
|
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)
|
886
|
+
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?
|
887
|
+
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?
|
888
|
+
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
889
|
end
|
803
890
|
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)
|
891
|
+
session["#{self.id}::#{key}:current_session"] = login.client.current_session if login.client.respond_to?(:current_session) && login.client.current_session.present?
|
892
|
+
session["#{self.id}::#{key}:bearer_token"] = login.client.bearer_token if login.client.respond_to?(:bearer_token) && login.client.bearer_token.present?
|
893
|
+
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
894
|
end
|
808
895
|
end
|
809
896
|
end
|
810
897
|
|
811
|
-
session["#{self.id}::task_data"] = self.task_data
|
898
|
+
session["#{self.id}::task_data"] = self.task_data if !ZuoraConnect.configuration.local_task_data
|
812
899
|
|
813
900
|
#Redis is not defined strip out old data
|
814
901
|
if !defined?(Redis.current)
|
@@ -848,6 +935,9 @@ module ZuoraConnect
|
|
848
935
|
else
|
849
936
|
begin
|
850
937
|
return JSON.parse(encryptor.decrypt_and_verify(CGI::unescape(data)))
|
938
|
+
rescue ActiveSupport::MessageEncryptor::InvalidMessage => ex
|
939
|
+
Rails.logger.error('Error Decrypting', ex, self.default_ougai_items) if log_fatal && !Rails.env.test?
|
940
|
+
return JSON.parse(encryptor.decrypt_and_verify(data))
|
851
941
|
rescue ActiveSupport::MessageVerifier::InvalidSignature => ex
|
852
942
|
ZuoraConnect.logger.error("Error Decrypting", ex, self.default_ougai_items) if log_fatal
|
853
943
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
19
|
-
|
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
|
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.
|
4
|
+
version: 3.1.1
|
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
|
11
|
+
date: 2022-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: apartment
|