zuora_connect_oauth_alpha 2

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 (90) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +38 -0
  4. data/app/assets/javascripts/zuora_connect/api/v1/app_instance.js +2 -0
  5. data/app/assets/javascripts/zuora_connect/application.js +13 -0
  6. data/app/assets/stylesheets/zuora_connect/api/v1/app_instance.css +4 -0
  7. data/app/assets/stylesheets/zuora_connect/application.css +15 -0
  8. data/app/controllers/zuora_connect/admin/tenant_controller.rb +11 -0
  9. data/app/controllers/zuora_connect/api/v1/app_instance_controller.rb +37 -0
  10. data/app/controllers/zuora_connect/application_controller.rb +8 -0
  11. data/app/controllers/zuora_connect/static_controller.rb +26 -0
  12. data/app/helpers/zuora_connect/api/v1/app_instance_helper.rb +4 -0
  13. data/app/helpers/zuora_connect/application_helper.rb +5 -0
  14. data/app/models/zuora_connect/app_instance.rb +5 -0
  15. data/app/models/zuora_connect/app_instance_base.rb +734 -0
  16. data/app/models/zuora_connect/login.rb +37 -0
  17. data/app/views/layouts/zuora_connect/application.html.erb +14 -0
  18. data/app/views/sql/refresh_aggregate_table.txt +84 -0
  19. data/app/views/zuora_connect/static/invalid_app_instance_error.html.erb +65 -0
  20. data/app/views/zuora_connect/static/session_error.html.erb +63 -0
  21. data/config/initializers/apartment.rb +95 -0
  22. data/config/initializers/object_method_hooks.rb +27 -0
  23. data/config/initializers/redis.rb +10 -0
  24. data/config/initializers/resque.rb +5 -0
  25. data/config/initializers/to_bool.rb +24 -0
  26. data/config/routes.rb +12 -0
  27. data/db/migrate/20100718151733_create_connect_app_instances.rb +9 -0
  28. data/db/migrate/20101024162319_add_tokens_to_app_instance.rb +6 -0
  29. data/db/migrate/20101024220705_add_token_to_app_instance.rb +5 -0
  30. data/db/migrate/20110131211919_add_sessions_table.rb +13 -0
  31. data/db/migrate/20110411200303_add_expiration_to_app_instance.rb +5 -0
  32. data/db/migrate/20110413191512_add_new_api_token.rb +5 -0
  33. data/db/migrate/20110503003602_add_catalog_data_to_app_instance.rb +6 -0
  34. data/db/migrate/20110503003603_add_catalog_mappings_to_app_instance.rb +5 -0
  35. data/db/migrate/20110503003604_catalog_default.rb +5 -0
  36. data/db/migrate/20180301052853_add_catalog_attempted_at.rb +5 -0
  37. data/lib/resque/additions.rb +53 -0
  38. data/lib/resque/dynamic_queues.rb +131 -0
  39. data/lib/resque/self_lookup.rb +19 -0
  40. data/lib/tasks/zuora_connect_tasks.rake +24 -0
  41. data/lib/zuora_connect_oauth_alpha.rb +38 -0
  42. data/lib/zuora_connect_oauth_alpha/configuration.rb +40 -0
  43. data/lib/zuora_connect_oauth_alpha/controllers/helpers.rb +165 -0
  44. data/lib/zuora_connect_oauth_alpha/engine.rb +30 -0
  45. data/lib/zuora_connect_oauth_alpha/exceptions.rb +50 -0
  46. data/lib/zuora_connect_oauth_alpha/railtie.rb +35 -0
  47. data/lib/zuora_connect_oauth_alpha/version.rb +4 -0
  48. data/lib/zuora_connect_oauth_alpha/views/helpers.rb +9 -0
  49. data/test/controllers/zuora_connect/api/v1/app_instance_controller_test.rb +13 -0
  50. data/test/dummy/README.rdoc +28 -0
  51. data/test/dummy/Rakefile +6 -0
  52. data/test/dummy/app/assets/javascripts/application.js +13 -0
  53. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  54. data/test/dummy/app/controllers/application_controller.rb +5 -0
  55. data/test/dummy/app/helpers/application_helper.rb +2 -0
  56. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  57. data/test/dummy/bin/bundle +3 -0
  58. data/test/dummy/bin/rails +4 -0
  59. data/test/dummy/bin/rake +4 -0
  60. data/test/dummy/bin/setup +29 -0
  61. data/test/dummy/config.ru +4 -0
  62. data/test/dummy/config/application.rb +26 -0
  63. data/test/dummy/config/boot.rb +5 -0
  64. data/test/dummy/config/database.yml +25 -0
  65. data/test/dummy/config/environment.rb +5 -0
  66. data/test/dummy/config/environments/development.rb +41 -0
  67. data/test/dummy/config/environments/production.rb +79 -0
  68. data/test/dummy/config/environments/test.rb +42 -0
  69. data/test/dummy/config/initializers/assets.rb +11 -0
  70. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  71. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  72. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  73. data/test/dummy/config/initializers/inflections.rb +16 -0
  74. data/test/dummy/config/initializers/mime_types.rb +4 -0
  75. data/test/dummy/config/initializers/session_store.rb +3 -0
  76. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  77. data/test/dummy/config/locales/en.yml +23 -0
  78. data/test/dummy/config/routes.rb +4 -0
  79. data/test/dummy/config/secrets.yml +22 -0
  80. data/test/dummy/public/404.html +67 -0
  81. data/test/dummy/public/422.html +67 -0
  82. data/test/dummy/public/500.html +66 -0
  83. data/test/dummy/public/favicon.ico +0 -0
  84. data/test/fixtures/zuora_connect/app_instances.yml +11 -0
  85. data/test/integration/navigation_test.rb +8 -0
  86. data/test/lib/generators/zuora_connect/datatable_generator_test.rb +16 -0
  87. data/test/models/zuora_connect/app_instance_test.rb +9 -0
  88. data/test/test_helper.rb +21 -0
  89. data/test/zuora_connect_test.rb +7 -0
  90. metadata +361 -0
@@ -0,0 +1,9 @@
1
+ class CreateConnectAppInstances < ActiveRecord::Migration
2
+ def change
3
+ if !ActiveRecord::Base.connection.table_exists?('zuora_connect_app_instances')
4
+ create_table :zuora_connect_app_instances do |t|
5
+ t.timestamps null: false
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ class AddTokensToAppInstance < ActiveRecord::Migration
2
+ def change
3
+ add_column :zuora_connect_app_instances, :access_token, :string unless column_exists? :zuora_connect_app_instances, :access_token
4
+ add_column :zuora_connect_app_instances, :refresh_token, :string unless column_exists? :zuora_connect_app_instances, :refresh_token
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddTokenToAppInstance < ActiveRecord::Migration
2
+ def change
3
+ add_column :zuora_connect_app_instances, :token, :string unless column_exists? :zuora_connect_app_instances, :token
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ class AddSessionsTable < ActiveRecord::Migration
2
+ def change
3
+ if !ActiveRecord::Base.connection.table_exists?('sessions')
4
+ create_table :sessions do |t|
5
+ t.string :session_id, :null => false
6
+ t.text :data
7
+ t.timestamps
8
+ end
9
+ add_index :sessions, :session_id, :unique => true
10
+ add_index :sessions, :updated_at
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ class AddExpirationToAppInstance < ActiveRecord::Migration
2
+ def change
3
+ add_column :zuora_connect_app_instances, :oauth_expires_at, :datetime unless column_exists? :zuora_connect_app_instances, :oauth_expires_at
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddNewApiToken < ActiveRecord::Migration
2
+ def change
3
+ add_column :zuora_connect_app_instances, :api_token, :string unless column_exists? :zuora_connect_app_instances, :api_token
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class AddCatalogDataToAppInstance < ActiveRecord::Migration
2
+ def change
3
+ add_column :zuora_connect_app_instances, :catalog_updated_at, :datetime unless column_exists? :zuora_connect_app_instances, :catalog_updated_at
4
+ add_column :zuora_connect_app_instances, :catalog, :jsonb, default: {} unless column_exists? :zuora_connect_app_instances, :catalog
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddCatalogMappingsToAppInstance < ActiveRecord::Migration
2
+ def change
3
+ add_column :zuora_connect_app_instances, :catalog_mapping, :jsonb, default: {} unless column_exists? :zuora_connect_app_instances, :catalog_mapping
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class CatalogDefault < ActiveRecord::Migration
2
+ def change
3
+ change_column :zuora_connect_app_instances, :catalog, :jsonb, default: {}
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddCatalogAttemptedAt < ActiveRecord::Migration
2
+ def change
3
+ add_column :zuora_connect_app_instances, :catalog_update_attempt_at, :datetime unless column_exists? :zuora_connect_app_instances, :catalog_update_attempt_at
4
+ end
5
+ end
@@ -0,0 +1,53 @@
1
+ module Resque
2
+ module Additions
3
+ def dequeue_from(queue, klass, *args)
4
+ ####### ------ Resque Job --------
5
+ # Perform before_dequeue hooks. Don't perform dequeue if any hook returns false
6
+ before_hooks = Plugin.before_dequeue_hooks(klass).collect do |hook|
7
+ klass.send(hook, *args)
8
+ end
9
+ return if before_hooks.any? { |result| result == false }
10
+
11
+ destroyed = Job.destroy(queue, klass, *args)
12
+
13
+ Plugin.after_dequeue_hooks(klass).each do |hook|
14
+ klass.send(hook, *args)
15
+ end
16
+
17
+ destroyed
18
+ end
19
+
20
+ ####### ------ Resque Delayed Job --------
21
+ # Returns delayed jobs schedule timestamp for +klass+, +args+.
22
+ def scheduled_at_with_queue(queue, klass, *args)
23
+ search = encode(job_to_hash_with_queue(queue,klass, args))
24
+ redis.smembers("timestamps:#{search}").map do |key|
25
+ key.tr('delayed:', '').to_i
26
+ end
27
+ end
28
+
29
+ # Given an encoded item, remove it from the delayed_queue
30
+ def remove_delayed_with_queue(queue, klass, *args)
31
+ search = encode(job_to_hash_with_queue(queue,klass, args))
32
+ remove_delayed_job(search)
33
+ end
34
+
35
+ #Given a timestamp and job (klass + args) it removes all instances and
36
+ # returns the count of jobs removed.
37
+ #
38
+ # O(N) where N is the number of jobs scheduled to fire at the given
39
+ # timestamp
40
+ def remove_delayed_job_with_queue_from_timestamp(timestamp, queue, klass, *args)
41
+ return 0 if Resque.inline?
42
+
43
+ key = "delayed:#{timestamp.to_i}"
44
+ encoded_job = encode(job_to_hash_with_queue(queue, klass, args))
45
+
46
+ redis.srem("timestamps:#{encoded_job}", key)
47
+ count = redis.lrem(key, 0, encoded_job)
48
+ clean_up_timestamp(key, timestamp)
49
+
50
+ count
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,131 @@
1
+ module Resque
2
+ module DynamicQueues
3
+ def filter_busy_queues qs
4
+ busy_queues = Resque::Worker.working.map { |worker| worker.job["queue"] }.compact
5
+ Array(qs.dup).compact - busy_queues
6
+ end
7
+
8
+ def rotated_queues
9
+ @n ||= 0
10
+ @n += 1
11
+ rot_queues = queues # since we rely on the resque-dynamic-queues plugin, this is all the queues, expanded out
12
+ if rot_queues.size > 0
13
+ @n = @n % rot_queues.size
14
+ rot_queues.rotate(@n)
15
+ else
16
+ rot_queues
17
+ end
18
+ end
19
+
20
+ def queue_depth queuename
21
+ busy_queues = Resque::Worker.working.map { |worker| worker.job["queue"] }.compact
22
+ # find the queuename, count it.
23
+ busy_queues.select {|q| q == queuename }.size
24
+ end
25
+
26
+ DEFAULT_QUEUE_DEPTH = 0
27
+ def should_work_on_queue? queuename
28
+ return true if @queues.include? '*' # workers with QUEUES=* are special and are not subject to queue depth setting
29
+ max = DEFAULT_QUEUE_DEPTH
30
+ unless ENV["RESQUE_QUEUE_DEPTH"].nil? || ENV["RESQUE_QUEUE_DEPTH"] == ""
31
+ max = ENV["RESQUE_QUEUE_DEPTH"].to_i
32
+ end
33
+ return true if max == 0 # 0 means no limiting
34
+ cur_depth = queue_depth(queuename)
35
+ log! "queue #{queuename} depth = #{cur_depth} max = #{max}"
36
+ return true if cur_depth < max
37
+ false
38
+ end
39
+
40
+ def reserve_with_round_robin
41
+ qs = rotated_queues
42
+ qs.each do |queue|
43
+ log! "Checking #{queue}"
44
+ if should_work_on_queue?(queue) && @job_in_progress = Resque::Job.reserve(queue)
45
+ log! "Found job on #{queue}"
46
+ return @job_in_progress
47
+ end
48
+ # Start the next search at the queue after the one from which we pick a job.
49
+ @n += 1
50
+ end
51
+
52
+ nil
53
+ rescue Exception => e
54
+ log "Error reserving job: #{e.inspect}"
55
+ log e.backtrace.join("\n")
56
+ raise e
57
+ end
58
+
59
+ # Returns a list of queues to use when searching for a job.
60
+ #
61
+ # A splat ("*") means you want every queue (in alpha order) - this
62
+ # can be useful for dynamically adding new queues.
63
+ #
64
+ # The splat can also be used as a wildcard within a queue name,
65
+ # e.g. "*high*", and negation can be indicated with a prefix of "!"
66
+ #
67
+ # An @key can be used to dynamically look up the queue list for key from redis.
68
+ # If no key is supplied, it defaults to the worker's hostname, and wildcards
69
+ # and negations can be used inside this dynamic queue list. Set the queue
70
+ # list for a key with Resque.set_dynamic_queue(key, ["q1", "q2"]
71
+ #
72
+ def queues_with_dynamic
73
+ queue_names = @queues.dup
74
+
75
+ return queues_without_dynamic if queue_names.grep(/(^!)|(^@)|(\*)/).size == 0
76
+
77
+ real_queues = Resque.queues
78
+ matched_queues = []
79
+
80
+ #Remove Queues under Api Limits
81
+ api_limit_instances = Redis.current.keys('APILimits:*').map {|key| key.split('APILimits:').last.to_i}
82
+ real_queues = real_queues.select {|key| key if !api_limit_instances.include?((key.match(/^(\d*)_.*/) || [])[1].to_i)}
83
+
84
+ #Queue Pausing
85
+ paused_instances = Redis.current.keys('resque:PauseQueue:*').map {|key| key.split('resque:PauseQueue:').last.to_i}
86
+ real_queues = real_queues.select {|key| key if !paused_instances.include?((key.match(/^(\d*)_.*/) || [])[1].to_i)}
87
+
88
+ while q = queue_names.shift
89
+ q = q.to_s
90
+
91
+ if q =~ /^(!)?@(.*)/
92
+ key = $2.strip
93
+ key = hostname if key.size == 0
94
+
95
+ add_queues = Resque.get_dynamic_queue(key)
96
+ add_queues.map! { |q| q.gsub!(/^!/, '') || q.gsub!(/^/, '!') } if $1
97
+
98
+ queue_names.concat(add_queues)
99
+ next
100
+ end
101
+
102
+ if q =~ /^!/
103
+ negated = true
104
+ q = q[1..-1]
105
+ end
106
+
107
+ patstr = q.gsub(/\*/, '.*')
108
+ pattern = /^#{patstr}$/
109
+ if negated
110
+ matched_queues -= matched_queues.grep(pattern)
111
+ else
112
+ matches = real_queues.grep(/^#{pattern}$/)
113
+ matches = [q] if matches.size == 0 && q == patstr
114
+ matched_queues.concat(matches.sort)
115
+ end
116
+ end
117
+
118
+ return matched_queues.uniq
119
+ end
120
+
121
+
122
+ def self.included(receiver)
123
+ receiver.class_eval do
124
+ alias queues_without_dynamic queues
125
+ alias queues queues_with_dynamic
126
+ alias reserve_without_round_robin reserve
127
+ alias reserve reserve_with_round_robin
128
+ end
129
+ end
130
+ end
131
+ 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,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,38 @@
1
+ require 'zuora_connect_oauth_alpha/configuration'
2
+ require "zuora_connect_oauth_alpha/engine"
3
+ require 'zuora_connect_oauth_alpha/exceptions'
4
+ require 'zuora_connect_oauth_alpha/controllers/helpers'
5
+ require 'zuora_connect_oauth_alpha/views/helpers'
6
+ require 'zuora_connect_oauth_alpha/railtie'
7
+ require 'resque/additions'
8
+ require 'resque/dynamic_queues'
9
+ require 'resque/self_lookup'
10
+
11
+ module ZuoraConnect
12
+ class << self
13
+ attr_accessor :configuration
14
+ end
15
+ module Controllers
16
+ autoload :Helpers, 'zuora_connect_oauth_alpha/controllers/helpers'
17
+ end
18
+
19
+ module Views
20
+ ActionView::Base.send(:include, Helpers)
21
+ end
22
+
23
+ def self.configuration
24
+ @configuration ||= Configuration.new
25
+ end
26
+
27
+ def self.reset
28
+ @configuration = Configuration.new
29
+ end
30
+
31
+ def self.configure
32
+ yield(configuration)
33
+ ::Apartment.excluded_models << "Delayed::Job" if configuration.delayed_job
34
+ ::Apartment.excluded_models.concat(configuration.additional_apartment_models) if configuration.additional_apartment_models.class == Array
35
+
36
+ return configuration
37
+ end
38
+ end
@@ -0,0 +1,40 @@
1
+ module ZuoraConnect
2
+ class Configuration
3
+ attr_accessor :oauth_client_id, :oauth_client_secret, :oauth_client_redirect_uri,:use_s3, :default_locale,:dev_mode_appinstance ,:dev_mode_admin, :dev_mode_user, :dev_mode_pass, :default_time_zone,:delayed_job,:url, :private_key, :dev_mode_logins,:dev_mode_mode, :dev_mode_options, :mode, :timeout,:dev_mode_secret_access_key,:dev_mode_access_key_id,:aws_region, :s3_bucket_name, :s3_folder_name, :additional_apartment_models
4
+
5
+ def initialize
6
+ @default_locale = :en
7
+ @default_time_zone = Time.zone
8
+ @url = "https://connect.zuora.com"
9
+ @mode = "Production"
10
+ @delayed_job = false
11
+ @use_s3 = false
12
+ @private_key = ENV["CONNECT_KEY"]
13
+ @additional_apartment_models = []
14
+
15
+ # OAuth Settings
16
+ @oauth_client_id = ""
17
+ @oauth_client_secret = ""
18
+ @oauth_client_redirect_uri = "https://connect.zuora.com/"
19
+
20
+ # DEV MODE OPTIONS
21
+ @dev_mode_logins = { "target_login" => {"tenant_type" => "Zuora", "username" => "user", "password" => "pass", "url" => "url"} }
22
+ @dev_mode_options = {"name" => {"config_name" => "name", "datatype" => "type", "value" => "value"}}
23
+ @dev_mode_mode = "Universal"
24
+ @dev_mode_appinstance = "1"
25
+ @dev_mode_user = "test"
26
+ @dev_mode_pass = "test"
27
+ @dev_mode_admin = false
28
+ @dev_mode_secret_access_key = nil
29
+ @dev_mode_access_key_id = nil
30
+ @aws_region = "us-west-2"
31
+ @s3_bucket_name = "rbm-apps"
32
+ @s3_folder_name = Rails.application.class.parent_name
33
+ end
34
+
35
+ def private_key
36
+ raise "Private Key Not Set" if @private_key.blank?
37
+ @private_key.include?("BEGIN") ? @private_key : Base64.urlsafe_decode64(@private_key)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,165 @@
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
+ request.session_options[:skip] = true
10
+ start_time = Time.now
11
+ if request.headers["API-Token"].present?
12
+ @appinstance = ZuoraConnect::AppInstance.where(:api_token => request.headers["API-Token"]).first
13
+ Rails.logger.debug("[#{@appinstance.id}] API REQUEST - API token") if @appinstance.present?
14
+ check_instance
15
+ else
16
+ authenticate_or_request_with_http_basic do |username, password|
17
+ @appinstance = ZuoraConnect::AppInstance.where(:token => password).first
18
+ @appinstance ||= ZuoraConnect::AppInstance.where(:api_token => password).first
19
+ Rails.logger.debug("[#{@appinstance.id}] API REQUEST - Basic Auth") if @appinstance.present?
20
+ check_instance
21
+ end
22
+ end
23
+ Rails.logger.info("[#{@appinstance.blank? ? "N/A" : @appinstance.id}] Authenticate App API Request Completed In - #{(Time.now - start_time).round(2)}s")
24
+ end
25
+
26
+ def authenticate_connect_app_request
27
+ start_time = Time.now
28
+
29
+ if ZuoraConnect.configuration.mode == "Production"
30
+ if request["data"]
31
+ setup_instance_via_data
32
+ else
33
+ setup_instance_via_session
34
+ end
35
+ else
36
+ setup_instance_via_dev_mode
37
+ end
38
+ #Call .data_lookup with the current session to retrieve session. In some cases session may be stored/cache in redis
39
+ #so data lookup provides a model method that can be overriden per app.
40
+ if params[:controller] != 'zuora_connect/api/v1/app_instance' && params[:action] != 'drop'
41
+ if @appinstance.new_session_for_ui_requests(:params => params)
42
+ @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
43
+ end
44
+ end
45
+ PaperTrail.whodunnit = session["#{@appinstance.id}::user::email"] if defined?(PaperTrail) && session["#{@appinstance.id}::user::email"].present?
46
+ begin
47
+ I18n.locale = session["#{@appinstance.id}::user::locale"] ? session["#{@appinstance.id}::user::locale"] : @appinstance.locale
48
+ rescue I18n::InvalidLocale => ex
49
+ Rails.logger.error("Invalid Locale: #{ex.message}")
50
+ end
51
+ Time.zone = session["#{@appinstance.id}::user::timezone"] ? session["#{@appinstance.id}::user::timezone"] : @appinstance.timezone
52
+ Rails.logger.info("[#{@appinstance.blank? ? "N/A" : @appinstance.id}] Authenticate App Request Completed In - #{(Time.now - start_time).round(2)}s")
53
+ end
54
+
55
+ def persist_connect_app_session
56
+ if @appinstance.present?
57
+ if defined?(Redis.current)
58
+ @appinstance.cache_app_instance
59
+ else
60
+ session.merge!(@appinstance.save_data)
61
+ end
62
+ end
63
+ end
64
+
65
+ def check_connect_admin!
66
+ raise ZuoraConnect::Exceptions::AccessDenied.new("User is not an authorized admin for this application") if !session["#{@appinstance.id}::admin"]
67
+ end
68
+
69
+ def check_connect_admin
70
+ return session["#{@appinstance.id}::admin"]
71
+ end
72
+
73
+ private
74
+ def setup_instance_via_data
75
+ session.clear
76
+ values = JSON.parse(ZuoraConnect::AppInstance.decrypt_response(Base64.urlsafe_decode64(request["data"])))
77
+ Rails.logger.debug("Data: #{values.to_json}")
78
+ if values["param_data"]
79
+ values["param_data"].each do |k ,v|
80
+ params[k] = v
81
+ end
82
+ end
83
+ session["#{values["appInstance"]}::destroy"] = values["destroy"]
84
+ session["appInstance"] = values["appInstance"]
85
+ if values["current_user"]
86
+ session["#{values["appInstance"]}::admin"] = values["current_user"]["admin"] ? values["current_user"]["admin"] : false
87
+ session["#{values["appInstance"]}::user::timezone"] = values["current_user"]["timezone"]
88
+ session["#{values["appInstance"]}::user::locale"] = values["current_user"]["locale"]
89
+ session["#{values["appInstance"]}::user::email"] = values["current_user"]["email"]
90
+ end
91
+
92
+ Rails.logger.debug("App Params: #{values.to_json}}") if Rails.env != "production"
93
+
94
+ @appinstance = ZuoraConnect::AppInstance.where(:id => values["appInstance"].to_i).first
95
+ if @appinstance.blank?
96
+ Apartment::Tenant.switch!("public")
97
+ begin
98
+ Apartment::Tenant.create(values["appInstance"].to_s)
99
+ rescue Apartment::TenantExists => ex
100
+ Rails.logger.debug("Tenant Already Exists")
101
+ end
102
+ @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"])
103
+ @appinstance.save(:validate => false)
104
+ else
105
+ @appinstance.access_token = values["access_token"] if !values["access_token"].blank? && @appinstance.access_token != values["access_token"]
106
+ @appinstance.refresh_token = values["refresh_token"] if !values["refresh_token"].blank? && @appinstance.refresh_token != values["refresh_token"]
107
+ @appinstance.oauth_expires_at = values["expires"] if !values["expires"].blank?
108
+ @appinstance.api_token = values["api_token"] if !values["api_token"].blank? && @appinstance.api_token != values["api_token"]
109
+ if @appinstance.access_token_changed? && @appinstance.refresh_token_changed?
110
+ @appinstance.save(:validate => false)
111
+ else
112
+ raise ZuoraConnect::Exceptions::AccessDenied.new("Authorization mistmatch. Possible tampering")
113
+ end
114
+ end
115
+ end
116
+
117
+ def setup_instance_via_session
118
+ if session["appInstance"].present?
119
+ @appinstance = ZuoraConnect::AppInstance.where(:id => session["appInstance"]).first
120
+ else
121
+ raise ZuoraConnect::Exceptions::SessionInvalid.new("Session Blank -- Relaunch Application")
122
+ end
123
+ end
124
+
125
+ def setup_instance_via_dev_mode
126
+ session["appInstance"] = ZuoraConnect.configuration.dev_mode_appinstance
127
+ user = ZuoraConnect.configuration.dev_mode_user
128
+ key = ZuoraConnect.configuration.dev_mode_pass
129
+ values = {:user => user , :key => key, :appinstance => session["appInstance"]}
130
+ @appinstance = ZuoraConnect::AppInstance.where(:id => values[:appinstance].to_i).first
131
+ if @appinstance.blank?
132
+ puts "make new!"
133
+ Apartment::Tenant.switch!("public")
134
+ begin
135
+ Apartment::Tenant.create(values[:appinstance].to_s)
136
+ rescue Apartment::TenantExists => ex
137
+ Apartment::Tenant.drop(values[:appinstance].to_s)
138
+ retry
139
+ end
140
+
141
+ @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]}")
142
+ @appinstance.save(:validate => false)
143
+ end
144
+ if @appinstance.access_token.blank? || @appinstance.refresh_token.blank? || @appinstance.token.blank? || @appinstance.api_token.blank?
145
+ @appinstance.update_attributes!(:access_token => values["user"], :refresh_token => values["key"], :token => "#{values[:key]}#{values[:key]}", :api_token => "#{values[:key]}#{values[:key]}")
146
+ end
147
+ session["#{@appinstance.id}::admin"] = ZuoraConnect.configuration.dev_mode_admin
148
+ end
149
+
150
+ #API ONLY
151
+ def check_instance
152
+ if @appinstance.present?
153
+ if @appinstance.new_session_for_api_requests(:params => params)
154
+ @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
155
+ end
156
+ Thread.current[:appinstance] = @appinstance
157
+ PaperTrail.whodunnit = "API User" if defined?(PaperTrail)
158
+ return true
159
+ else
160
+ render text: "Access Denied", status: :unauthorized
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end