zuora_connect 0

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.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +38 -0
  4. data/app/assets/javascripts/hallway_wrapper/after.js +15 -0
  5. data/app/assets/javascripts/hallway_wrapper/before.js +2 -0
  6. data/app/assets/javascripts/zuora_connect/api/v1/app_instance.js +2 -0
  7. data/app/assets/javascripts/zuora_connect/application.js +13 -0
  8. data/app/assets/stylesheets/zuora_connect/api/v1/app_instance.css +4 -0
  9. data/app/assets/stylesheets/zuora_connect/application.css +15 -0
  10. data/app/controllers/zuora_connect/admin/tenant_controller.rb +11 -0
  11. data/app/controllers/zuora_connect/api/v1/app_instance_controller.rb +58 -0
  12. data/app/controllers/zuora_connect/application_controller.rb +8 -0
  13. data/app/controllers/zuora_connect/static_controller.rb +58 -0
  14. data/app/helpers/zuora_connect/api/v1/app_instance_helper.rb +4 -0
  15. data/app/helpers/zuora_connect/application_helper.rb +5 -0
  16. data/app/models/zuora_connect/app_instance.rb +5 -0
  17. data/app/models/zuora_connect/app_instance_base.rb +952 -0
  18. data/app/models/zuora_connect/login.rb +36 -0
  19. data/app/models/zuora_connect/telegraf.rb +93 -0
  20. data/app/views/layouts/zuora_connect/application.html.erb +14 -0
  21. data/app/views/sql/refresh_aggregate_table.txt +85 -0
  22. data/app/views/zuora_connect/static/invalid_app_instance_error.html.erb +65 -0
  23. data/app/views/zuora_connect/static/invalid_launch_request.html +65 -0
  24. data/app/views/zuora_connect/static/launch.html.erb +80 -0
  25. data/app/views/zuora_connect/static/session_error.html.erb +63 -0
  26. data/config/initializers/apartment.rb +95 -0
  27. data/config/initializers/aws.rb +2 -0
  28. data/config/initializers/elastic_apm.rb +25 -0
  29. data/config/initializers/object_method_hooks.rb +27 -0
  30. data/config/initializers/postgresql_adapter.rb +32 -0
  31. data/config/initializers/prometheus.rb +40 -0
  32. data/config/initializers/redis.rb +13 -0
  33. data/config/initializers/resque.rb +22 -0
  34. data/config/initializers/to_bool.rb +24 -0
  35. data/config/initializers/unicorn.rb +9 -0
  36. data/config/routes.rb +16 -0
  37. data/db/migrate/20100718151733_create_connect_app_instances.rb +9 -0
  38. data/db/migrate/20101024162319_add_tokens_to_app_instance.rb +6 -0
  39. data/db/migrate/20101024220705_add_token_to_app_instance.rb +5 -0
  40. data/db/migrate/20110131211919_add_sessions_table.rb +13 -0
  41. data/db/migrate/20110411200303_add_expiration_to_app_instance.rb +5 -0
  42. data/db/migrate/20110413191512_add_new_api_token.rb +5 -0
  43. data/db/migrate/20110503003602_add_catalog_data_to_app_instance.rb +6 -0
  44. data/db/migrate/20110503003603_add_catalog_mappings_to_app_instance.rb +5 -0
  45. data/db/migrate/20110503003604_catalog_default.rb +5 -0
  46. data/db/migrate/20180301052853_add_catalog_attempted_at.rb +5 -0
  47. data/db/migrate/20181206162339_add_fields_to_instance.rb +5 -0
  48. data/lib/metrics/influx/point_value.rb +79 -0
  49. data/lib/metrics/net.rb +218 -0
  50. data/lib/middleware/metrics_middleware.rb +134 -0
  51. data/lib/resque/additions.rb +53 -0
  52. data/lib/resque/dynamic_queues.rb +222 -0
  53. data/lib/resque/plugins/custom_logger.rb +46 -0
  54. data/lib/resque/self_lookup.rb +19 -0
  55. data/lib/resque/silence_done.rb +71 -0
  56. data/lib/tasks/zuora_connect_tasks.rake +24 -0
  57. data/lib/zuora_connect.rb +42 -0
  58. data/lib/zuora_connect/configuration.rb +53 -0
  59. data/lib/zuora_connect/controllers/helpers.rb +261 -0
  60. data/lib/zuora_connect/engine.rb +34 -0
  61. data/lib/zuora_connect/exceptions.rb +67 -0
  62. data/lib/zuora_connect/railtie.rb +63 -0
  63. data/lib/zuora_connect/version.rb +3 -0
  64. data/lib/zuora_connect/views/helpers.rb +9 -0
  65. data/test/controllers/zuora_connect/api/v1/app_instance_controller_test.rb +13 -0
  66. data/test/dummy/README.rdoc +28 -0
  67. data/test/dummy/Rakefile +6 -0
  68. data/test/dummy/app/assets/javascripts/application.js +13 -0
  69. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  70. data/test/dummy/app/controllers/application_controller.rb +5 -0
  71. data/test/dummy/app/helpers/application_helper.rb +2 -0
  72. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  73. data/test/dummy/bin/bundle +3 -0
  74. data/test/dummy/bin/rails +4 -0
  75. data/test/dummy/bin/rake +4 -0
  76. data/test/dummy/bin/setup +29 -0
  77. data/test/dummy/config.ru +4 -0
  78. data/test/dummy/config/application.rb +26 -0
  79. data/test/dummy/config/boot.rb +5 -0
  80. data/test/dummy/config/database.yml +25 -0
  81. data/test/dummy/config/environment.rb +5 -0
  82. data/test/dummy/config/environments/development.rb +41 -0
  83. data/test/dummy/config/environments/production.rb +79 -0
  84. data/test/dummy/config/environments/test.rb +42 -0
  85. data/test/dummy/config/initializers/assets.rb +11 -0
  86. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  87. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  88. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  89. data/test/dummy/config/initializers/inflections.rb +16 -0
  90. data/test/dummy/config/initializers/mime_types.rb +4 -0
  91. data/test/dummy/config/initializers/session_store.rb +3 -0
  92. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  93. data/test/dummy/config/locales/en.yml +23 -0
  94. data/test/dummy/config/routes.rb +4 -0
  95. data/test/dummy/config/secrets.yml +22 -0
  96. data/test/dummy/public/404.html +67 -0
  97. data/test/dummy/public/422.html +67 -0
  98. data/test/dummy/public/500.html +66 -0
  99. data/test/dummy/public/favicon.ico +0 -0
  100. data/test/fixtures/zuora_connect/app_instances.yml +11 -0
  101. data/test/integration/navigation_test.rb +8 -0
  102. data/test/lib/generators/zuora_connect/datatable_generator_test.rb +16 -0
  103. data/test/models/zuora_connect/app_instance_test.rb +9 -0
  104. data/test/test_helper.rb +21 -0
  105. data/test/zuora_connect_test.rb +7 -0
  106. metadata +443 -0
@@ -0,0 +1,46 @@
1
+ # This Resque extension changes the resque default logger to monologger
2
+ # and formats the log in json format.
3
+ #
4
+ # Monologger supports printing logs in trap block.
5
+ #
6
+ module Resque
7
+ module Plugins
8
+ module CustomLogger
9
+ def before_perform(*args)
10
+ marker = SecureRandom.uuid
11
+
12
+ logger = MonoLogger.new(STDOUT)
13
+ logger.level = Rails.application.config.log_level
14
+ logger.formatter = proc do |serverity, datetime, progname, msg|
15
+ begin
16
+ msg = JSON.parse(msg)
17
+ rescue JSON::ParserError => ex
18
+ end
19
+
20
+ require 'json'
21
+ JSON.dump(
22
+ trace_id: marker,
23
+ level: serverity,
24
+ timestamp: datetime.strftime('%FT%T.%6N'),
25
+ pid: Process.pid,
26
+ msg: msg
27
+ ) + "\n"
28
+ end
29
+
30
+ Resque.logger = logger
31
+ Rails.logger = logger
32
+ case args.class.to_s
33
+ when "Array"
34
+ if args.first.class == Hash
35
+ data = args.first.merge({:worker_class => self.to_s})
36
+ else
37
+ data = {:worker_class => self.to_s, :args => args}
38
+ end
39
+ when "Hash"
40
+ data = args.merge({:worker_class => self.to_s})
41
+ end
42
+ Rails.logger.info(data.to_json) if data.present?
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,19 @@
1
+ module Resque
2
+ module SelfLookup
3
+ def payload_class_enhanced
4
+ @payload_class ||= constantize(@payload['class'])
5
+ @payload_class.instance_eval { class << self; self end }.send(:attr_accessor, :worker)
6
+ @payload_class.instance_eval { class << self; self end }.send(:attr_accessor, :job)
7
+ @payload_class.worker = self.worker
8
+ @payload_class.job = self
9
+ return @payload_class
10
+ end
11
+
12
+ def self.included(receiver)
13
+ receiver.class_eval do
14
+ alias payload_class_old payload_class
15
+ alias payload_class payload_class_enhanced
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,71 @@
1
+ module Resque
2
+ module SilenceDone
3
+ def perform_no_log(job)
4
+ begin
5
+ if fork_per_job?
6
+ reconnect
7
+ run_hook :after_fork, job
8
+ end
9
+ job.perform
10
+ rescue Object => e
11
+ report_failed_job(job,e)
12
+ else
13
+ # log_with_severity :info, "done: #{job.inspect}"
14
+ ensure
15
+ yield job if block_given?
16
+ end
17
+ end
18
+
19
+ # def work(interval = 5.0, &block)
20
+ # interval = Float(interval)
21
+ # startup
22
+
23
+ # loop do
24
+ # break if shutdown?
25
+
26
+ # unless work_one_job(&block)
27
+ # break if interval.zero?
28
+ # log_with_severity :debug, "Sleeping for #{interval} seconds"
29
+ # procline paused? ? "Paused" : "Waiting for #{queues.join(',')}"
30
+ # sleep interval
31
+ # end
32
+ # end
33
+
34
+ # unregister_worker
35
+ # rescue Exception => exception
36
+ # return if exception.class == SystemExit && !@child && run_at_exit_hooks
37
+ # log_with_severity :error, "Failed to start worker : #{exception.inspect}"
38
+ # unregister_worker(exception)
39
+ # end
40
+
41
+ def work_one_job_no_log(job = nil, &block)
42
+ return false if paused?
43
+ return false unless job ||= reserve
44
+
45
+ working_on job
46
+ procline "Processing #{job.queue} since #{Time.now.to_i} [#{job.payload_class_name}]"
47
+
48
+ #log_with_severity :info, "got: #{job.inspect}"
49
+ job.worker = self
50
+
51
+ if fork_per_job?
52
+ perform_with_fork(job, &block)
53
+ else
54
+ perform(job, &block)
55
+ end
56
+
57
+ done_working
58
+ true
59
+ end
60
+
61
+ def self.included(receiver)
62
+ receiver.class_eval do
63
+ alias work_one_job_with_log work_one_job
64
+ alias work_one_job work_one_job_no_log
65
+
66
+ alias perform_with_log perform
67
+ alias perform perform_no_log
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,24 @@
1
+ # desc "Explaining what the task does"
2
+ # task :connect do
3
+ # # Task goes here
4
+ # end
5
+
6
+ namespace :db do
7
+ desc 'Also create shared_extensions Schema'
8
+ task :extensions => :environment do
9
+ # 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;'
15
+ end
16
+ end
17
+
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
@@ -0,0 +1,42 @@
1
+ require 'zuora_connect/configuration'
2
+ require "zuora_connect/engine"
3
+ require 'zuora_connect/exceptions'
4
+ require 'zuora_connect/controllers/helpers'
5
+ require 'zuora_connect/views/helpers'
6
+ require 'zuora_connect/railtie'
7
+ require 'resque/additions'
8
+ require 'resque/dynamic_queues'
9
+ require 'resque/silence_done'
10
+ require 'resque/self_lookup'
11
+ require 'resque/plugins/custom_logger'
12
+ require 'metrics/influx/point_value'
13
+ require 'metrics/net'
14
+
15
+ module ZuoraConnect
16
+ class << self
17
+ attr_accessor :configuration
18
+ end
19
+ module Controllers
20
+ autoload :Helpers, 'zuora_connect/controllers/helpers'
21
+ end
22
+
23
+ module Views
24
+ ActionView::Base.send(:include, Helpers)
25
+ end
26
+
27
+ def self.configuration
28
+ @configuration ||= Configuration.new
29
+ end
30
+
31
+ def self.reset
32
+ @configuration = Configuration.new
33
+ end
34
+
35
+ def self.configure
36
+ yield(configuration)
37
+ ::Apartment.excluded_models << "Delayed::Job" if configuration.delayed_job
38
+ ::Apartment.excluded_models.concat(configuration.additional_apartment_models) if configuration.additional_apartment_models.class == Array
39
+
40
+ return configuration
41
+ end
42
+ end
@@ -0,0 +1,53 @@
1
+ module ZuoraConnect
2
+ class Configuration
3
+
4
+ attr_accessor :default_locale, :default_time_zone, :url, :mode, :delayed_job,:private_key, :additional_apartment_models
5
+
6
+ attr_accessor :enable_metrics, :enable_apm, :telegraf_endpoint, :telegraf_debug, :custom_prometheus_update_block, :silencer_resque_finish, :blpop_queue
7
+
8
+ attr_accessor :oauth_client_id, :oauth_client_secret, :oauth_client_redirect_uri
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
11
+
12
+ def initialize
13
+ @default_locale = :en
14
+ @default_time_zone = Time.zone
15
+ @url = "https://connect.zuora.com"
16
+ @mode = "Production"
17
+ @delayed_job = false
18
+ @private_key = ENV["CONNECT_KEY"]
19
+ @additional_apartment_models = []
20
+ @silencer_resque_finish = true
21
+ @blpop_queue = false
22
+
23
+ # Setting the app name for telegraf write
24
+ @enable_metrics = false
25
+ @telegraf_endpoint = 'udp://telegraf-app-metrics.monitoring.svc.cluster.local:8094'
26
+ @telegraf_debug = false
27
+ @enable_apm = false
28
+ # OAuth Settings
29
+ @oauth_client_id = ""
30
+ @oauth_client_secret = ""
31
+ @oauth_client_redirect_uri = "https://connect.zuora.com/"
32
+
33
+ # DEV MODE OPTIONS
34
+ @dev_mode_logins = { "target_login" => {"tenant_type" => "Zuora", "username" => "user", "password" => "pass", "url" => "url"} }
35
+ @dev_mode_options = {"name" => {"config_name" => "name", "datatype" => "type", "value" => "value"}}
36
+ @dev_mode_mode = "Universal"
37
+ @dev_mode_appinstance = "1"
38
+ @dev_mode_user = "test"
39
+ @dev_mode_pass = "test"
40
+ @dev_mode_admin = false
41
+ @dev_mode_secret_access_key = nil
42
+ @dev_mode_access_key_id = nil
43
+ @aws_region = "us-west-2"
44
+ @s3_bucket_name = "rbm-apps"
45
+ @s3_folder_name = Rails.application.class.parent_name
46
+ end
47
+
48
+ def private_key
49
+ raise "Private Key Not Set" if @private_key.blank?
50
+ @private_key.include?("BEGIN") ? @private_key : Base64.urlsafe_decode64(@private_key)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,261 @@
1
+ require 'apartment/migrator'
2
+ module ZuoraConnect
3
+ module Controllers
4
+ module Helpers
5
+ extend ActiveSupport::Concern
6
+
7
+ def authenticate_app_api_request
8
+ #Skip session for api requests
9
+ Thread.current[:appinstance] = nil
10
+ request.session_options[:skip] = true
11
+ ElasticAPM.set_tag(:trace_id, request.uuid) if defined?(ElasticAPM)
12
+
13
+ start_time = Time.now
14
+ if request.headers["API-Token"].present?
15
+ @appinstance = ZuoraConnect::AppInstance.where(:api_token => request.headers["API-Token"]).first
16
+ Rails.logger.debug("[#{@appinstance.id}] API REQUEST - API token") if @appinstance.present?
17
+ check_instance
18
+ else
19
+ authenticate_or_request_with_http_basic do |username, password|
20
+ @appinstance = ZuoraConnect::AppInstance.where(:token => password).first
21
+ @appinstance ||= ZuoraConnect::AppInstance.where(:api_token => password).first
22
+ Rails.logger.debug("[#{@appinstance.id}] API REQUEST - Basic Auth") if @appinstance.present?
23
+ check_instance
24
+ end
25
+ end
26
+ if @appinstance.present?
27
+ Rails.logger.debug("[#{@appinstance.id}] Authenticate App API Request Completed In - #{(Time.now - start_time).round(2)}s")
28
+ end
29
+ end
30
+
31
+ def verify_with_navbar
32
+ if !session[params[:app_instance_ids]].present?
33
+ host = request.headers["HTTP_X_FORWARDED_HOST"]
34
+ zuora_client = ZuoraAPI::Login.new(url: "https://#{host}")
35
+ menus = zuora_client.get_full_nav(cookies.to_h)["menus"]
36
+ app = menus.select do |item|
37
+ matches = /(?<=.com\/services\/)(.*?)(?=\?|$)/.match(item["url"])
38
+ if !matches.blank?
39
+ matches[0].split("?").first == ENV["DEIS_APP"]
40
+ end
41
+ end
42
+
43
+ session[params[:app_instance_ids]] = app[0]
44
+ return app[0]
45
+ else
46
+ return session[params[:app_instance_ids]]
47
+ end
48
+ end
49
+
50
+ def select_instance
51
+ begin
52
+ app = verify_with_navbar
53
+
54
+ url_tasks = JSON.parse(Base64.urlsafe_decode64(CGI.parse(URI.parse(app["url"]).query)["app_instance_ids"][0]))
55
+ @app_instance_ids = JSON.parse(Base64.urlsafe_decode64(params[:app_instance_ids]))
56
+
57
+ if (url_tasks & @app_instance_ids).size == @app_instance_ids.size
58
+ sql = "select name,id from zuora_connect_app_instances where id = ANY(ARRAY#{@app_instance_ids})"
59
+ result = ActiveRecord::Base.connection.execute(sql)
60
+ @names = {}
61
+ result.each do |x|
62
+ @names[x["id"].to_i] = x["name"]
63
+ end
64
+ render "zuora_connect/static/launch"
65
+ else
66
+ render "zuora_connect/static/invalid_launch_request"
67
+ end
68
+ rescue => ex
69
+ Rails.logger.debug("Error parsing Instance ID's: #{ex.message}")
70
+ render "zuora_connect/static/invalid_launch_request"
71
+ end
72
+ end
73
+
74
+ def authenticate_connect_app_request
75
+ ElasticAPM.set_tag(:trace_id, request.uuid) if defined?(ElasticAPM)
76
+ Thread.current[:appinstance] = nil
77
+ if params[:app_instance_ids].present? && !params[:app_instance_id].present?
78
+ begin
79
+ app_instance_ids = JSON.parse(Base64.urlsafe_decode64(params[:app_instance_ids]))
80
+ if app_instance_ids.length == 1
81
+ verify_with_navbar
82
+ instances = JSON.parse(Base64.urlsafe_decode64(CGI.parse(URI.parse(session[params[:app_instance_ids]]["url"]).query)["app_instance_ids"][0]))
83
+ if instances.include?(app_instance_ids[0])
84
+ @appinstance = ZuoraConnect::AppInstance.find(app_instance_ids[0])
85
+ @appinstance.new_session(session: {})
86
+ @appinstance.cache_app_instance
87
+ session["appInstance"] = app_instance_ids[0]
88
+ else
89
+ Rails.logger.fatal("Launch Error: Param Instance didnt match session data")
90
+ render "zuora_connect/static/invalid_launch_request"
91
+ return
92
+ end
93
+ else
94
+ select_instance
95
+ return
96
+ end
97
+ rescue => ex
98
+ Rails.logger.fatal("Launch Error: #{ex.message}")
99
+ render "zuora_connect/static/invalid_launch_request"
100
+ return
101
+ end
102
+
103
+ elsif params[:app_instance_ids].present? && params[:app_instance_id].present?
104
+ begin
105
+ instances = JSON.parse(Base64.urlsafe_decode64(CGI.parse(URI.parse(session[params[:app_instance_ids]]["url"]).query)["app_instance_ids"][0]))
106
+ if instances.include?(params[:app_instance_id].to_i)
107
+ @appinstance = ZuoraConnect::AppInstance.find(params[:app_instance_id].to_i)
108
+ @appinstance.new_session(session: {})
109
+ @appinstance.cache_app_instance
110
+ session["appInstance"] = params[:app_instance_id].to_i
111
+ else
112
+ render "zuora_connect/static/invalid_launch_request"
113
+ return
114
+ end
115
+ rescue => ex
116
+ Rails.logger.fatal("Launch Error: #{ex.message}")
117
+ render "zuora_connect/static/invalid_launch_request"
118
+ return
119
+ end
120
+ end
121
+ start_time = Time.now
122
+ if ZuoraConnect.configuration.mode == "Production"
123
+ if request["data"] && /^([A-Za-z0-9+\/\-\_]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)$/.match(request["data"].to_s)
124
+ setup_instance_via_data
125
+ else
126
+ setup_instance_via_session
127
+ end
128
+ else
129
+ setup_instance_via_dev_mode
130
+ end
131
+ #Call .data_lookup with the current session to retrieve session. In some cases session may be stored/cache in redis
132
+ #so data lookup provides a model method that can be overriden per app.
133
+ if params[:controller] != 'zuora_connect/api/v1/app_instance' && params[:action] != 'drop'
134
+ if @appinstance.new_session_for_ui_requests(:params => params)
135
+ @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
136
+ end
137
+ end
138
+ if session["#{@appinstance.id}::user::email"].present?
139
+ ElasticAPM.set_user(session["#{@appinstance.id}::user::email"]) if defined?(ElasticAPM)
140
+ PaperTrail.whodunnit = session["#{@appinstance.id}::user::email"] if defined?(PaperTrail)
141
+ end
142
+ begin
143
+ I18n.locale = session["#{@appinstance.id}::user::locale"] ? session["#{@appinstance.id}::user::locale"] : @appinstance.locale
144
+ rescue I18n::InvalidLocale => ex
145
+ Rails.logger.error("Invalid Locale: #{ex.message}")
146
+ end
147
+ Time.zone = session["#{@appinstance.id}::user::timezone"] ? session["#{@appinstance.id}::user::timezone"] : @appinstance.timezone
148
+ Rails.logger.debug("[#{@appinstance.blank? ? "N/A" : @appinstance.id}] Authenticate App Request Completed In - #{(Time.now - start_time).round(2)}s")
149
+ end
150
+
151
+ def persist_connect_app_session
152
+ if @appinstance.present?
153
+ if defined?(Redis.current)
154
+ @appinstance.cache_app_instance
155
+ else
156
+ session.merge!(@appinstance.save_data)
157
+ end
158
+ end
159
+ end
160
+
161
+ def check_connect_admin!
162
+ raise ZuoraConnect::Exceptions::AccessDenied.new("User is not an authorized admin for this application") if !session["#{@appinstance.id}::admin"]
163
+ end
164
+
165
+ def check_connect_admin
166
+ return session["#{@appinstance.id}::admin"]
167
+ end
168
+
169
+ private
170
+ def setup_instance_via_data
171
+ session.clear
172
+ values = JSON.parse(ZuoraConnect::AppInstance.decrypt_response(Base64.urlsafe_decode64(request["data"])))
173
+ Rails.logger.debug("Data: #{values.to_json}")
174
+ if values["param_data"]
175
+ values["param_data"].each do |k ,v|
176
+ params[k] = v
177
+ end
178
+ end
179
+ session["#{values["appInstance"]}::destroy"] = values["destroy"]
180
+ session["appInstance"] = values["appInstance"]
181
+ if values["current_user"]
182
+ session["#{values["appInstance"]}::admin"] = values["current_user"]["admin"] ? values["current_user"]["admin"] : false
183
+ session["#{values["appInstance"]}::user::timezone"] = values["current_user"]["timezone"]
184
+ session["#{values["appInstance"]}::user::locale"] = values["current_user"]["locale"]
185
+ session["#{values["appInstance"]}::user::email"] = values["current_user"]["email"]
186
+ end
187
+
188
+ Rails.logger.debug("App Params: #{values.to_json}}") if Rails.env != "production"
189
+
190
+ @appinstance = ZuoraConnect::AppInstance.where(:id => values["appInstance"].to_i).first
191
+ if @appinstance.blank?
192
+ Apartment::Tenant.switch!("public")
193
+ begin
194
+ Apartment::Tenant.create(values["appInstance"].to_s)
195
+ rescue Apartment::TenantExists => ex
196
+ Rails.logger.debug("Tenant Already Exists")
197
+ end
198
+ @appinstance = ZuoraConnect::AppInstance.new(:api_token => values[:api_token],:id => values["appInstance"].to_i, :access_token => values["access_token"].blank? ? values["user"] : values["access_token"], :token => values["refresh_token"] , :refresh_token => values["refresh_token"].blank? ? values["key"] : values["refresh_token"], :oauth_expires_at => values["expires"])
199
+ @appinstance.save(:validate => false)
200
+ else
201
+ @appinstance.access_token = values["access_token"] if !values["access_token"].blank? && @appinstance.access_token != values["access_token"]
202
+ @appinstance.refresh_token = values["refresh_token"] if !values["refresh_token"].blank? && @appinstance.refresh_token != values["refresh_token"]
203
+ @appinstance.oauth_expires_at = values["expires"] if !values["expires"].blank?
204
+ @appinstance.api_token = values["api_token"] if !values["api_token"].blank? && @appinstance.api_token != values["api_token"]
205
+ if @appinstance.access_token_changed? && @appinstance.refresh_token_changed?
206
+ @appinstance.save(:validate => false)
207
+ else
208
+ raise ZuoraConnect::Exceptions::AccessDenied.new("Authorization mistmatch. Possible tampering")
209
+ end
210
+ end
211
+ end
212
+
213
+ def setup_instance_via_session
214
+ if session["appInstance"].present?
215
+ @appinstance = ZuoraConnect::AppInstance.where(:id => session["appInstance"]).first
216
+ else
217
+ raise ZuoraConnect::Exceptions::SessionInvalid.new("Session Blank -- Relaunch Application")
218
+ end
219
+ end
220
+
221
+ def setup_instance_via_dev_mode
222
+ session["appInstance"] = ZuoraConnect.configuration.dev_mode_appinstance
223
+ user = ZuoraConnect.configuration.dev_mode_user
224
+ key = ZuoraConnect.configuration.dev_mode_pass
225
+ values = {:user => user , :key => key, :appinstance => session["appInstance"]}
226
+ @appinstance = ZuoraConnect::AppInstance.where(:id => values[:appinstance].to_i).first
227
+ if @appinstance.blank?
228
+ Apartment::Tenant.switch!("public")
229
+ begin
230
+ Apartment::Tenant.create(values[:appinstance].to_s)
231
+ rescue Apartment::TenantExists => ex
232
+ Apartment::Tenant.drop(values[:appinstance].to_s)
233
+ retry
234
+ end
235
+
236
+ @appinstance = ZuoraConnect::AppInstance.new(:id => values[:appinstance].to_i, :access_token => values[:user], :refresh_token => values[:key], :token => "#{values[:key]}#{values[:key]}", :api_token => "#{values[:key]}#{values[:key]}")
237
+ @appinstance.save(:validate => false)
238
+ end
239
+ if @appinstance.access_token.blank? || @appinstance.refresh_token.blank? || @appinstance.token.blank? || @appinstance.api_token.blank?
240
+ @appinstance.update_attributes!(:access_token => values["user"], :refresh_token => values["key"], :token => "#{values[:key]}#{values[:key]}", :api_token => "#{values[:key]}#{values[:key]}")
241
+ end
242
+ session["#{@appinstance.id}::admin"] = ZuoraConnect.configuration.dev_mode_admin
243
+ end
244
+
245
+ #API ONLY
246
+ def check_instance
247
+ if @appinstance.present?
248
+ if @appinstance.new_session_for_api_requests(:params => params)
249
+ @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
250
+ end
251
+ Thread.current[:appinstance] = @appinstance
252
+ PaperTrail.whodunnit = "API User" if defined?(PaperTrail)
253
+ ElasticAPM.set_user("API User") if defined?(ElasticAPM)
254
+ return true
255
+ else
256
+ render text: "Access Denied", status: :unauthorized
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end