module ZuoraConnect::Controllers::Helpers
def authenticate_connect_app_request
def authenticate_connect_app_request ElasticAPM.set_tag(:trace_id, request.uuid) if defined?(ElasticAPM) && ElasticAPM.running? Thread.current[:appinstance] = nil if request.headers['Zuora-Auth-Token'].present? && request.headers["NEWZUORA"].present? #Debug headers = request.headers.env.select do |k, _| k.downcase.start_with?('http') || k.in?(ActionDispatch::Http::Headers::CGI_VARIABLES) end puts headers #Do we need to refresh session identity zuora_host = request.headers["HTTP_X_FORWARDED_HOST"] || "apisandbox.zuora.com" zuora_client = ZuoraAPI::Login.new(url: "https://#{zuora_host}", session: cookies['ZSession']) zuora_entity_id = request.headers['ZuoraCurrentEntity'] zuora_instance_id = params[:sidebar_launch].to_bool ? nil : (params[:app_instance_id] || session["appInstance"]) #Identity blank or current entity different if (session["ZuoraCurrentIdentity"].blank? || session["ZuoraCurrentEntity"] != zuora_entity_id) begin identity, response = zuora_client.rest_call(url: zuora_client.rest_endpoint("identity")) session["ZuoraCurrentIdentity"] = identity session["ZuoraCurrentEntity"] = identity['entityId'] raise ZuoraConnect::Exceptions::Error.new("Header entity id, '#{zuora_entity_id}' does not match identity call entity id, '#{identity['entityId']}'.") if zuora_entity_id != identity['entityId'] rescue => ex ZuoraConnect.logger.error(ex) render "zuora_connect/static/invalid_launch_request", :locals => {:exception => ex} return end end #Find matching app instances. if zuora_instance_id.present? appinstances = ZuoraConnect::AppInstance.where("zuora_entity_ids ?& array[:entities] = true AND zuora_domain = :host AND id = :id", entities: [zuora_entity_id], host: zuora_client.rest_domain, id: zuora_instance_id).pluck(:id, :name) else #if app_instance_ids is present then permissions still controlled by connect if params[:app_instance_ids].present? begin navbar, response = zuora_client.rest_call(url: zuora_client.rest_endpoint("navigation")) urls = navbar['menus'].map {|x| x['url']} app_env = ENV["DEIS_APP"] || "xyz123" url = urls.compact.select {|url| File.basename(url).start_with?(app_env + '?')}.first task_ids = JSON.parse(Base64.urlsafe_decode64(CGI.parse(URI.parse(url).query)["app_instance_ids"][0])) appinstances = ZuoraConnect::AppInstance.where(:id => task_ids).pluck(:id, :name) rescue => ex ZuoraConnect.logger.error(ex) render "zuora_connect/static/invalid_launch_request", :locals => {:exception => ex} return end else appinstances = ZuoraConnect::AppInstance.where("zuora_entity_ids ?& array[:entities] = true AND zuora_domain = :host", entities: [zuora_entity_id], host: zuora_client.rest_domain).pluck(:id, :name) end end #One deployed instance if appinstances.size == 1 ZuoraConnect.logger.debug("Instance is #{appinstances.to_h.keys.first}") session["appInstance"] = appinstances.to_h.keys.first #We have multiple, user must pick elsif appinstances.size > 1 ZuoraConnect.logger.debug("User must select instance. #{@names}") @names = appinstances.to_h render "zuora_connect/static/launch" return else #Create new app instance raise "Do not support new instance creation right now." end end start_time = Time.now if ZuoraConnect.configuration.mode == "Production" 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) setup_instance_via_data else setup_instance_via_session end else setup_instance_via_dev_mode end #Call .data_lookup with the current session to retrieve session. In some cases session may be stored/cache in redis #so data lookup provides a model method that can be overriden per app. if params[:controller] != 'zuora_connect/api/v1/app_instance' && params[:action] != 'drop' if @appinstance.new_session_for_ui_requests(:params => params) @appinstance.new_session(:session => @appinstance.data_lookup(:session => session)) end end if session["#{@appinstance.id}::user::email"].present? ElasticAPM.set_user(session["#{@appinstance.id}::user::email"]) if defined?(ElasticAPM) && ElasticAPM.running? PaperTrail.whodunnit = session["#{@appinstance.id}::user::email"] if defined?(PaperTrail) end begin I18n.locale = session["#{@appinstance.id}::user::locale"] ? session["#{@appinstance.id}::user::locale"] : @appinstance.locale rescue I18n::InvalidLocale => ex ZuoraConnect.logger.error(ex) if !ZuoraConnect::AppInstance::IGNORED_LOCALS.include?(ex.locale.to_s.downcase) end Time.zone = session["#{@appinstance.id}::user::timezone"] ? session["#{@appinstance.id}::user::timezone"] : @appinstance.timezone ZuoraConnect.logger.debug("[#{@appinstance.blank? ? "N/A" : @appinstance.id}] Authenticate App Request Completed In - #{(Time.now - start_time).round(2)}s") end