class Soaspec::OAuth2

Handles working with OAuth2

Attributes

access_tokens[RW]

@attr [Hash] access_tokens List of access tokens. They are mapped according to the OAuth parameters used

debug_oauth[W]

Specify whether to see params sent to and retrieved from oauth. This will put password in log file, only recommended for debugging

instance_urls[RW]

List of URLs to that define the instance of an application

refresh_token[RW]

@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
request_message[W]

@return [Boolean] Whether to include request message describing OAuth (either full or simplified)

retry_limit[RW]

@return [Integer] How many times to attempt to authenticate before raising exception

token_url[RW]

Default token url used across entire suite

params[RW]

@attr [Hash] OAuth parameters

retry_count[RW]

@attr [Integer] Count of tries to obtain access token

Public Class Methods

debug_oauth?() click to toggle source

@return [Boolean] Whether to see params sent to & received from oauth URL

# File lib/soaspec/o_auth2.rb, line 37
def debug_oauth?
  @debug_oauth || false
end
new(params_sent, api_username = nil) click to toggle source

@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 [resource] Api server that handles authenticated requests @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

# File lib/soaspec/o_auth2.rb, line 61
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
request_message?() click to toggle source

@return [Boolean] Whether to include request message describing OAuth (either full or simplified)

# File lib/soaspec/o_auth2.rb, line 42
def request_message?
  @request_message
end

Public Instance Methods

access_token() click to toggle source

@return [String] Existing or new access token, dependent on refresh_token attribute

# File lib/soaspec/o_auth2.rb, line 90
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
debug_oauth?() click to toggle source

Retrieve whether to debug oauth parameters based on global settings @return [Boolean] Whether to see params sent to & received from oauth URL

# File lib/soaspec/o_auth2.rb, line 77
def debug_oauth?
  self.class.debug_oauth?
end
instance_url() click to toggle source

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

# File lib/soaspec/o_auth2.rb, line 85
def instance_url
  Soaspec::OAuth2.instance_urls[params] ||= response['instance_url']
end
password() click to toggle source

@return [String] Password to use in OAuth request

# File lib/soaspec/o_auth2.rb, line 125
def password
  params[:security_token] ? (params[:password] + params[:security_token]) : params[:password]
end
payload() click to toggle source

Payload to add to o-auth request dependent on params provided @return [Hash] Payload for retrieving OAuth access token

# File lib/soaspec/o_auth2.rb, line 131
def payload
  payload = { client_id: params[:client_id], client_secret: params[:client_secret] }
  payload.merge!(if params[:password] && params[:username]
                   password_grant_type_params
                 else
                   { grant_type: 'client_credentials' }.merge multipart false
                 end)
  payload[:resource] = params[:resource] if params[:resource]
  payload
end
request_message() click to toggle source

@return [String] String to represent OAuth for logging logs

# File lib/soaspec/o_auth2.rb, line 116
def request_message
  if debug_oauth?
    "request_params: #{payload}"
  else
    params[:username] ? "User '#{params[:username]}'" : 'client_credentials'
  end
end
response() click to toggle source

@return [Hash] Hash containing access token parameters

# File lib/soaspec/o_auth2.rb, line 101
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

Private Instance Methods

multipart(default) click to toggle source

@param [Boolean] default Default value for multipart @return [Hash] Multipart set to true if not set and is grant_type password

# File lib/soaspec/o_auth2.rb, line 153
def multipart(default)
  return { multipart: true } if (params[:multipart].nil? && default) || params[:multipart]

  {}
end
password_grant_type_params() click to toggle source
# File lib/soaspec/o_auth2.rb, line 144
def password_grant_type_params
  {
    grant_type: 'password', username: params[:username],
    password: password
  }.merge multipart true
end