lib/soaspec/o_auth2.rb in soaspec-0.2.32 vs lib/soaspec/o_auth2.rb in soaspec-0.2.33

- old
+ new

@@ -1,142 +1,142 @@ -# frozen_string_literal: true - -require 'erb' - -module Soaspec - # Handles working with OAuth2 - class OAuth2 - # How often to refresh access token - @refresh_token = :always - # List of access tokens. They are mapped according to the OAuth parameters used - @access_tokens = {} - # List of instance URLs. They are mapped according to the OAuth parameters used - @instance_urls = {} - # Whether to see params sent to & received from oauth URL - @request_message = true - # How many times to attempt to authenticate before raising exception - @retry_limit = 2 - class << self - # Default token url used across entire suite - attr_accessor :token_url - # @attr [Symbol] refresh_token How often to refresh access token - # Values are: - # * :always - (Default) Request token from token url every time it is needed - # * :once - Request token once for the entire execution of the suite - attr_accessor :refresh_token - # @attr [Hash] access_tokens List of access tokens. They are mapped according to the OAuth parameters used - attr_accessor :access_tokens - # List of URLs to that define the instance of an application - attr_accessor :instance_urls - # Specify whether to see params sent to and retrieved from oauth. This will put password in log file, only recommended for debugging - attr_writer :debug_oauth - # @return [Boolean] Whether to include request message describing OAuth (either full or simplified) - attr_writer :request_message - # @return [Integer] How many times to attempt to authenticate before raising exception - attr_accessor :retry_limit - # @return [Boolean] Whether to see params sent to & received from oauth URL - def debug_oauth? - @debug_oauth || false - end - - # @return [Boolean] Whether to include request message describing OAuth (either full or simplified) - def request_message? - @request_message - end - end - - # @attr [Hash] OAuth parameters - attr_accessor :params - # @attr [Integer] Count of tries to obtain access token - attr_accessor :retry_count - - # @param [Hash] params_sent Parameters to make OAuth request - # @option params_sent [token_url] URL to retrieve OAuth token from. @Note this can be set globally instead of here - # @option params_sent [client_id] Client ID - # @option params_sent [client_secret] Client Secret - # @option params_sent [username] Username used in password grant - # @option params_sent [password] Password used in password grant - # @option params_sent [security_token] Security Token used in password grant - # @param [String] api_username Username to use which can be set by Soaspec::ExchangeHandler - def initialize(params_sent, api_username = nil) - self.retry_count = 0 # No initial tries at getting access token - params = params_sent.transform_keys_to_symbols - params[:token_url] ||= Soaspec::OAuth2.token_url - raise ArgumentError, 'client_id and client_secret not set' unless params[:client_id] && params[:client_secret] - raise ArgumentError, 'token_url mandatory' unless params[:token_url] - - self.params = params - params[:username] = api_username || ERB.new(params[:username]).result(binding) if params[:username] - params[:security_token] = ERB.new(params[:security_token]).result(binding) if params[:security_token] - params[:token_url] = ERB.new(params[:token_url]).result(binding) if params[:token_url] - params[:password] = ERB.new(params[:password]).result(binding) if params[:password] - end - - # Retrieve whether to debug oauth parameters based on global settings - # @return [Boolean] Whether to see params sent to & received from oauth URL - def debug_oauth? - self.class.debug_oauth? - end - - # Retrieve instance_url according to access token response. - # Some applications have a different instance - # It's assumed this will be constant for a set of oauth parameters - # @return [String] Instance url - def instance_url - Soaspec::OAuth2.instance_urls[params] ||= response['instance_url'] - end - - # @return [String] Existing or new access token, dependent on refresh_token attribute - def access_token - Soaspec::SpecLogger.info request_message if self.class.request_message? - case Soaspec::OAuth2.refresh_token - when :once - Soaspec::OAuth2.access_tokens[params] ||= response['access_token'] - else # Default is :always - response['access_token'] - end - end - - # @return [Hash] Hash containing access token parameters - def response - Soaspec::SpecLogger.info "using oauth_params: #{params}" if debug_oauth? - response = RestClient.post(params[:token_url], payload, cache_control: 'no_cache', verify_ssl: false) - rescue RestClient::Exception => e - Soaspec::SpecLogger.info(["oauth_error: #{e.message}", "oauth_response: #{e.response}"]) - self.retry_count += 1 - sleep 0.1 # Wait if a bit before retying obtaining access token - retry if retry_count < self.class.retry_limit - raise e - else - Soaspec::SpecLogger.info(["response: \n headers: #{response&.headers}\n body: #{response}\n"]) if debug_oauth? - JSON.parse(response) - end - - # @return [String] String to represent OAuth for logging logs - def request_message - if debug_oauth? - "request_params: #{payload}" - else - params[:username] ? "User '#{params[:username]}'" : 'client_credentials' - end - end - - # @return [String] Password to use in OAuth request - def password - params[:security_token] ? (params[:password] + params[:security_token]) : params[:password] - end - - # Payload to add to o-auth request dependent on params provided - # @return [Hash] Payload for retrieving OAuth access token - def payload - payload = { client_id: params[:client_id], client_secret: params[:client_secret] } - payload.merge(if params[:password] && params[:username] - { - grant_type: 'password', username: params[:username], - password: password, multipart: true - } - else - { grant_type: 'client_credentials' } - end) - end - end -end +# frozen_string_literal: true + +require 'erb' + +module Soaspec + # Handles working with OAuth2 + class OAuth2 + # How often to refresh access token + @refresh_token = :always + # List of access tokens. They are mapped according to the OAuth parameters used + @access_tokens = {} + # List of instance URLs. They are mapped according to the OAuth parameters used + @instance_urls = {} + # Whether to see params sent to & received from oauth URL + @request_message = true + # How many times to attempt to authenticate before raising exception + @retry_limit = 2 + class << self + # Default token url used across entire suite + attr_accessor :token_url + # @attr [Symbol] refresh_token How often to refresh access token + # Values are: + # * :always - (Default) Request token from token url every time it is needed + # * :once - Request token once for the entire execution of the suite + attr_accessor :refresh_token + # @attr [Hash] access_tokens List of access tokens. They are mapped according to the OAuth parameters used + attr_accessor :access_tokens + # List of URLs to that define the instance of an application + attr_accessor :instance_urls + # Specify whether to see params sent to and retrieved from oauth. This will put password in log file, only recommended for debugging + attr_writer :debug_oauth + # @return [Boolean] Whether to include request message describing OAuth (either full or simplified) + attr_writer :request_message + # @return [Integer] How many times to attempt to authenticate before raising exception + attr_accessor :retry_limit + # @return [Boolean] Whether to see params sent to & received from oauth URL + def debug_oauth? + @debug_oauth || false + end + + # @return [Boolean] Whether to include request message describing OAuth (either full or simplified) + def request_message? + @request_message + end + end + + # @attr [Hash] OAuth parameters + attr_accessor :params + # @attr [Integer] Count of tries to obtain access token + attr_accessor :retry_count + + # @param [Hash] params_sent Parameters to make OAuth request + # @option params_sent [token_url] URL to retrieve OAuth token from. @Note this can be set globally instead of here + # @option params_sent [client_id] Client ID + # @option params_sent [client_secret] Client Secret + # @option params_sent [username] Username used in password grant + # @option params_sent [password] Password used in password grant + # @option params_sent [security_token] Security Token used in password grant + # @param [String] api_username Username to use which can be set by Soaspec::ExchangeHandler + def initialize(params_sent, api_username = nil) + self.retry_count = 0 # No initial tries at getting access token + params = params_sent.transform_keys_to_symbols + params[:token_url] ||= Soaspec::OAuth2.token_url + raise ArgumentError, 'client_id and client_secret not set' unless params[:client_id] && params[:client_secret] + raise ArgumentError, 'token_url mandatory' unless params[:token_url] + + self.params = params + params[:username] = api_username || ERB.new(params[:username]).result(binding) if params[:username] + params[:security_token] = ERB.new(params[:security_token]).result(binding) if params[:security_token] + params[:token_url] = ERB.new(params[:token_url]).result(binding) if params[:token_url] + params[:password] = ERB.new(params[:password]).result(binding) if params[:password] + end + + # Retrieve whether to debug oauth parameters based on global settings + # @return [Boolean] Whether to see params sent to & received from oauth URL + def debug_oauth? + self.class.debug_oauth? + end + + # Retrieve instance_url according to access token response. + # Some applications have a different instance + # It's assumed this will be constant for a set of oauth parameters + # @return [String] Instance url + def instance_url + Soaspec::OAuth2.instance_urls[params] ||= response['instance_url'] + end + + # @return [String] Existing or new access token, dependent on refresh_token attribute + def access_token + Soaspec::SpecLogger.info request_message if self.class.request_message? + case Soaspec::OAuth2.refresh_token + when :once + Soaspec::OAuth2.access_tokens[params] ||= response['access_token'] + else # Default is :always + response['access_token'] + end + end + + # @return [Hash] Hash containing access token parameters + def response + Soaspec::SpecLogger.info "using oauth_params: #{params}" if debug_oauth? + response = RestClient.post(params[:token_url], payload, cache_control: 'no_cache', verify_ssl: false) + rescue RestClient::Exception => e + Soaspec::SpecLogger.info(["oauth_error: #{e.message}", "oauth_response: #{e.response}"]) + self.retry_count += 1 + sleep 0.1 # Wait if a bit before retying obtaining access token + retry if retry_count < self.class.retry_limit + raise e + else + Soaspec::SpecLogger.info(["response: \n headers: #{response&.headers}\n body: #{response}\n"]) if debug_oauth? + JSON.parse(response) + end + + # @return [String] String to represent OAuth for logging logs + def request_message + if debug_oauth? + "request_params: #{payload}" + else + params[:username] ? "User '#{params[:username]}'" : 'client_credentials' + end + end + + # @return [String] Password to use in OAuth request + def password + params[:security_token] ? (params[:password] + params[:security_token]) : params[:password] + end + + # Payload to add to o-auth request dependent on params provided + # @return [Hash] Payload for retrieving OAuth access token + def payload + payload = { client_id: params[:client_id], client_secret: params[:client_secret] } + payload.merge(if params[:password] && params[:username] + { + grant_type: 'password', username: params[:username], + password: password, multipart: true + } + else + { grant_type: 'client_credentials' } + end) + end + end +end