# frozen_string_literal: true require_relative 'error' module LeapSalesforce # Code related to authorising in LeapSalesforce # Specific authorisation parameters are stored here. More general settings # are stored at the layer above this module Auth @access_token = nil @instance_url = nil # @return [String] Setup JWT trail head SETUP_JWT_LINK = 'https://trailhead.salesforce.com/content/learn/projects/automate-cicd-with-gitlab/https://trailhead.salesforce.com/content/learn/projects/automate-cicd-with-gitlab/integrate-with-gitlab' class << self # @return [String] Access token taken from sfdx attr_writer :access_token # Instance Url taken from sfdx attr_writer :instance_url # @return [String] Output from SFDX command attr_accessor :sfdx_display_output # @return [String] Access token taken from sfdx. Value is extracted if # not cached. If not using sfdx this will not be stored here but # within Soaspec which caches the OAuth result def access_token return @access_token if @access_token extract_sfdx_variables raise 'Instance URL was not set correctly' if @access_token&.empty? @access_token end # @return [String] Instance URL taken from sfdx. Value is extracted if # not cached def instance_url return @instance_url if @instance_url extract_sfdx_variables raise 'Instance URL was not set correctly' if @instance_url&.empty? @instance_url end # @return [Boolean] Whether Sfdx authentication variables are set def sfdx_variables? !(access_token && instance_url).nil? end # @return [TrueClass] Whether JWT file exists Exception is raised if it # is not def jwt_file? ENV['JWT_FOLDER'] ||= Dir.exist?('JWT') ? 'JWT' : 'assets' unless File.exist?(File.join(ENV['JWT_FOLDER'], 'server.key')) raise LeapSalesforce::SetupError, 'Please create JWT file in ' \ " '#{ENV['JWT_FOLDER']}/server.key' following #{SETUP_JWT_LINK}" end true end # @return [Boolean] Whether SFDX Access token and instance url have been manually set # If not they will be attempted to be retrieved via JWT, SF_USERNAME & SF_CONSUMER_KEY def manually_set_auth? ENV['SFDX_ACCESS_TOKEN'] ||= ENV['SCRATCH_ACCESS_TOKEN'] ENV['SFDX_INSTANCE_URL'] ||= ENV['SCRATCH_INSTANCE_URL'] return false unless ENV['SFDX_ACCESS_TOKEN'] && ENV['SFDX_INSTANCE_URL'] !ENV['SFDX_ACCESS_TOKEN'].empty? && !ENV['SFDX_INSTANCE_URL'].empty? end # Extract sfdx variables and store them # Set ENV['SCRATCH_ORG'] to true to authenticate and run against sandbox def extract_sfdx_variables return unless LeapSalesforce.sfdx LeapSalesforce.client_id = ENV['SF_CONSUMER_KEY'] if manually_set_auth? url_obtained = ENV['SFDX_INSTANCE_URL'] self.instance_url = url_obtained[-1] == '/' ? url_obtained[0..-2] : url_obtained self.access_token = ENV['SFDX_ACCESS_TOKEN'] return end unless ENV['SF_USERNAME'] && ENV['SF_CONSUMER_KEY'] logger.error "No CREDENTIALS FILE found at #{CREDENTIAL_FILE}." unless File.exist? CREDENTIAL_FILE raise SetupError, 'Please set SF_USERNAME and SF_CONSUMER_KEY environment variables' end script_name = if ENV['SCRATCH_ORG'] && !ENV['SCRATCH_ORG'].empty? raise "Please set SCRATCH_ORG_ALIAS when SCRATCH_ORG(#{ENV['SCRATCH_ORG']}) is set" unless ENV['SCRATCH_ORG_ALIAS'] puts "Using sandbox #{ENV['SCRATCH_ORG_ALIAS']}" 'get_scratch_auth' else 'get_prod_auth' end puts "Using JWT folder '#{ENV['JWT_FOLDER']}'" self.sfdx_display_output = `sh #{__dir__}/#{script_name}.sh` self.access_token = from_output 'Access Token' url_obtained = from_output 'Instance Url' self.instance_url = url_obtained[-1] == '/' ? url_obtained[0..-2] : url_obtained end private def from_output(variable) var_line = sfdx_display_output.lines.find do |line| line.start_with? variable end raise LeapSalesforce::SetupError, "Error retrieving from #{sfdx_display_output}" unless var_line var_line.split[-1] end end end end