class SSO::Client::PassportVerifier

Attributes

device_id[R]
passport_id[R]
passport_secret[R]
passport_state[R]
user_agent[R]
user_ip[R]

Public Class Methods

new(passport_id:, passport_state:, passport_secret:, user_ip:, user_agent: nil, device_id: nil) click to toggle source
# File lib/sso/client/passport_verifier.rb, line 8
def initialize(passport_id:, passport_state:, passport_secret:, user_ip:, user_agent: nil, device_id: nil)
  @passport_id     = passport_id
  @passport_state  = passport_state
  @passport_secret = passport_secret
  @user_ip         = user_ip
  @user_agent      = user_agent
  @device_id       = device_id
end

Public Instance Methods

call() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 17
def call
  fetch_response { |failure| return failure }
  interpret_response

rescue ::JSON::ParserError
  error { 'SSO Server response is not valid JSON.' }
  error { response.inspect }
  Operations.failure :server_response_not_parseable, object: response
end
human_readable_timeout_in_ms() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 27
def human_readable_timeout_in_ms
  "#{timeout_in_milliseconds}ms"
end

Private Instance Methods

auth_hash() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 102
def auth_hash
  signature_request.sign token
end
base_endpoint() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 119
def base_endpoint
  OmniAuth::Strategies::SSO.endpoint
end
endpoint() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 123
def endpoint
  URI.join(base_endpoint, path).to_s
end
fetch_response() { |failure(:server_unreachable, object: response)| ... } click to toggle source
# File lib/sso/client/passport_verifier.rb, line 33
def fetch_response
  yield Operations.failure(:server_unreachable, object: response)                   unless response.code.to_s == '200'
  yield Operations.failure(:server_response_not_parseable, object: response)        unless parsed_response
  yield Operations.failure(:server_response_missing_success_flag, object: response) unless response_has_success_flag?
  Operations.success :server_response_looks_legit
end
insider_id() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 78
def insider_id
  ::SSO.config.oauth_client_id
end
insider_secret() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 82
def insider_secret
  ::SSO.config.oauth_client_secret
end
insider_signature() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 86
def insider_signature
  ::OpenSSL::HMAC.hexdigest signature_digest, insider_secret, user_ip
end
interpret_response() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 40
def interpret_response
  debug { "Interpreting response code #{response_code.inspect}" }

  case response_code
  when :passpord_unmodified then Operations.success(:passport_valid)
  when :passport_changed    then Operations.success(:passport_valid_and_modified, object: received_passport)
  when :passport_invalid    then Operations.failure(:passport_invalid)
  else                           Operations.failure(:unexpected_server_response_status, object: response)
  end
end
params() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 72
def params
  result = { ip: user_ip, agent: user_agent, device_id: device_id, state: passport_state }
  result.merge! insider_id: insider_id, insider_signature: insider_signature
  result
end
parsed_response() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 142
def parsed_response
  response.parsed_response
end
path() click to toggle source

TODO: Needs to be configurable

# File lib/sso/client/passport_verifier.rb, line 115
def path
  OmniAuth::Strategies::SSO.passports_path
end
query_params() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 127
def query_params
  params.merge auth_hash
end
received_passport() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 56
def received_passport
  ::SSO::Client::Passport.new received_passport_attributes

rescue ArgumentError
  error { "Could not instantiate Passport from serialized response #{received_passport_attributes.inspect}" }
  raise
end
received_passport_attributes() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 64
def received_passport_attributes
  attributes = parsed_response['passport']
  attributes.keys.each do |key|
    attributes[(key.to_sym rescue key) || key] = attributes.delete(key)
  end
  attributes
end
response() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 131
def response
  @response ||= response!
end
response!() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 135
def response!
  debug { "Fetching Passport from #{endpoint.inspect}" }
  benchmark(name: 'Passport verification request', metric: 'client.passport.verification.duration') do
    ::HTTParty.get endpoint, timeout: timeout_in_seconds, query: query_params, headers: { 'Accept' => 'application/json' }
  end
end
response_code() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 51
def response_code
  return :unknown_response_code if parsed_response['code'].to_s == ''
  parsed_response['code'].to_s.to_sym
end
response_has_success_flag?() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 146
def response_has_success_flag?
  parsed_response && parsed_response.respond_to?(:key?) && (parsed_response.key?('success') || parsed_response.key?(:success))
end
signature_digest() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 90
def signature_digest
  OpenSSL::Digest.new 'sha1'
end
signature_request() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 98
def signature_request
  Signature::Request.new('GET', path, params)
end
timeout_in_milliseconds() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 106
def timeout_in_milliseconds
  ::SSO.config.passport_verification_timeout_ms.to_i
end
timeout_in_seconds() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 110
def timeout_in_seconds
  (timeout_in_milliseconds / 1000).round 2
end
token() click to toggle source
# File lib/sso/client/passport_verifier.rb, line 94
def token
  Signature::Token.new passport_id, passport_secret
end