module MAuth::Client::AuthenticatorBase

Constants

ALLOWED_DRIFT_SECONDS

Public Instance Methods

authentic?(object) click to toggle source

takes an incoming request or response object, and returns whether the object is authentic according to its signature.

# File lib/mauth/client/authenticator_base.rb, line 10
def authentic?(object)
  log_authentication_request(object)
  begin
    authenticate!(object)
    true
  rescue InauthenticError, MAuthNotPresent, MissingV2Error
    false
  end
end
authenticate!(object) click to toggle source

raises InauthenticError unless the given object is authentic. Will only authenticate with v2 if the environment variable V2_ONLY_AUTHENTICATE is set. Otherwise will fall back to v1 when v2 authentication fails

# File lib/mauth/client/authenticator_base.rb, line 23
def authenticate!(object)
  if object.protocol_version == 2
    begin
      authenticate_v2!(object)
    rescue InauthenticError => e
      raise e if v2_only_authenticate?
      raise e if disable_fallback_to_v1_on_v2_failure?

      object.fall_back_to_mws_signature_info
      raise e unless object.signature

      log_authentication_request(object)
      authenticate_v1!(object)
      logger.warn("Completed successful authentication attempt after fallback to v1")
    end
  elsif object.protocol_version == 1
    if v2_only_authenticate?
      # If v2 is required but not present and v1 is present we raise MissingV2Error
      msg = 'This service requires mAuth v2 mcc-authentication header but only v1 x-mws-authentication is present'
      logger.error(msg)
      raise MissingV2Error, msg
    end

    authenticate_v1!(object)
  else
    sub_str = v2_only_authenticate? ? '' : 'X-MWS-Authentication header is blank, '
    msg = "Authentication Failed. No mAuth signature present; #{sub_str}MCC-Authentication header is blank."
    logger.warn("mAuth signature not present on #{object.class}. Exception: #{msg}")
    raise MAuthNotPresent, msg
  end
end

Private Instance Methods

authenticate_v1!(object) click to toggle source

V1 helpers

# File lib/mauth/client/authenticator_base.rb, line 82
def authenticate_v1!(object)
  time_valid_v1!(object)
  token_valid_v1!(object)
  signature_valid_v1!(object)
end
authenticate_v2!(object) click to toggle source

V2 helpers

# File lib/mauth/client/authenticator_base.rb, line 106
def authenticate_v2!(object)
  time_valid_v2!(object)
  token_valid_v2!(object)
  signature_valid_v2!(object)
end
log_authentication_request(object) click to toggle source

Note: This log is likely consumed downstream and the contents SHOULD NOT be changed without a thorough review of downstream consumers.

# File lib/mauth/client/authenticator_base.rb, line 59
def log_authentication_request(object)
  object_app_uuid = object.signature_app_uuid || '[none provided]'
  object_token = object.signature_token || '[none provided]'
  logger.info(
    "Mauth-client attempting to authenticate request from app with mauth" \
    " app uuid #{object_app_uuid} to app with mauth app uuid #{client_app_uuid}" \
    " using version #{object_token}."
  )
end
log_inauthentic(object, message) click to toggle source
# File lib/mauth/client/authenticator_base.rb, line 69
def log_inauthentic(object, message)
  logger.error("mAuth signature authentication failed for #{object.class}. Exception: #{message}")
end
time_valid_v1!(object) click to toggle source
# File lib/mauth/client/authenticator_base.rb, line 88
def time_valid_v1!(object)
  if object.x_mws_time.nil?
    msg = 'Time verification failed. No x-mws-time present.'
    log_inauthentic(object, msg)
    raise InauthenticError, msg
  end
  time_within_valid_range!(object, object.x_mws_time.to_i)
end
time_valid_v2!(object) click to toggle source
# File lib/mauth/client/authenticator_base.rb, line 112
def time_valid_v2!(object)
  if object.mcc_time.nil?
    msg = 'Time verification failed. No MCC-Time present.'
    log_inauthentic(object, msg)
    raise InauthenticError, msg
  end
  time_within_valid_range!(object, object.mcc_time.to_i)
end
time_within_valid_range!(object, time_signed, now = Time.now) click to toggle source
# File lib/mauth/client/authenticator_base.rb, line 73
def time_within_valid_range!(object, time_signed, now = Time.now)
  return if  (-ALLOWED_DRIFT_SECONDS..ALLOWED_DRIFT_SECONDS).cover?(now.to_i - time_signed)

  msg = "Time verification failed. #{time_signed} not within #{ALLOWED_DRIFT_SECONDS} of #{now}"
  log_inauthentic(object, msg)
  raise InauthenticError, msg
end
token_valid_v1!(object) click to toggle source
# File lib/mauth/client/authenticator_base.rb, line 97
def token_valid_v1!(object)
  return if object.signature_token == MWS_TOKEN

  msg = "Token verification failed. Expected #{MWS_TOKEN}; token was #{object.signature_token}"
  log_inauthentic(object, msg)
  raise InauthenticError, msg
end
token_valid_v2!(object) click to toggle source
# File lib/mauth/client/authenticator_base.rb, line 121
def token_valid_v2!(object)
  return if object.signature_token == MWSV2_TOKEN

  msg = "Token verification failed. Expected #{MWSV2_TOKEN}; token was #{object.signature_token}"
  log_inauthentic(object, msg)
  raise InauthenticError, msg
end