zuora_connect 3.1.0 → 3.1.1.pre.a
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 +129 -38
- 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 +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 575850a90d1e2c6aaca6a638ce4c353f337c617d3ff1460731b48a208d8942c1
|
4
|
+
data.tar.gz: 5e2a26d1ff920f57243bca6cd1de689158d0c996bb31b6c3793c9d004572d248
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
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
|
-
|
444
|
-
|
445
|
-
|
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
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
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
|
-
|
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.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-
|
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:
|
457
|
+
version: 1.3.1
|
458
458
|
requirements: []
|
459
459
|
rubygems_version: 3.3.7
|
460
460
|
signing_key:
|