Class: MAuth::Client

Inherits:
Object
  • Object
show all
Includes:
Authenticator, Signer
Defined in:
lib/mauth/client.rb,
lib/mauth/errors.rb,
lib/mauth/client/signer.rb,
lib/mauth/client/authenticator.rb,
lib/mauth/client/security_token_cacher.rb

Overview

does operations which require a private key and corresponding app uuid. this is primarily:

  • signing outgoing requests and responses

  • authenticating incoming requests and responses, which may require retrieving the appropriate public key from mAuth (which requires a request to mAuth which is signed using the private key)

this nominally operates on request and response objects, but really the only requirements are that the object responds to the methods of MAuth::Signable and/or MAuth::Signed (as appropriate)

Defined Under Namespace

Modules: Authenticator, Signer Classes: ConfigurationError

Constant Summary collapse

MWS_TOKEN =
'MWS'
MWSV2_TOKEN =
'MWSV2'
AUTH_HEADER_DELIMITER =
';'
RACK_ENV_APP_UUID_KEY =
'mauth.app_uuid'
SIGNING_DIGEST =
OpenSSL::Digest.new('SHA512')

Constants included from Signer

Signer::UNABLE_TO_SIGN_ERR

Constants included from Authenticator

Authenticator::ALLOWED_DRIFT_SECONDS

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Signer

#signature_v1, #signature_v2, #signed, #signed_headers, #signed_headers_v1, #signed_headers_v2, #signed_v1, #signed_v2

Methods included from Authenticator

#authentic?, #authenticate!

Constructor Details

#initialize(config = {}) ⇒ Client

new client with the given App UUID and public key. config may include the following (all config keys may be strings or symbols):

  • private_key - required for signing and for authentication. may be given as a string or a OpenSSL::PKey::RSA instance.

  • app_uuid - required in the same circumstances where a private_key is required

  • mauth_baseurl - required. needed to retrieve public keys.

  • mauth_api_version - required. only ‘v1’ exists / is supported as of this writing.

  • logger - a Logger to which any useful information will be written. if this is omitted and Rails.logger exists, that will be used.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/mauth/client.rb', line 71

def initialize(config = {})
  # stringify symbol keys
  given_config = config.stringify_symbol_keys
  # build a configuration which discards any irrelevant parts of the given config (small memory usage matters here)
  @config = {}
  if given_config['private_key_file'] && !given_config['private_key']
    given_config['private_key'] = File.read(given_config['private_key_file'])
  end
  @config['private_key'] =
    case given_config['private_key']
    when nil
      nil
    when String
      PrivateKeyHelper.load(given_config['private_key'])
    when OpenSSL::PKey::RSA
      given_config['private_key']
    else
      raise MAuth::Client::ConfigurationError,
        "unrecognized value given for 'private_key' - this may be a " \
        "String, a OpenSSL::PKey::RSA, or omitted; instead got: #{given_config['private_key'].inspect}"
    end
  @config['app_uuid'] = given_config['app_uuid']
  @config['mauth_baseurl'] = given_config['mauth_baseurl']
  @config['mauth_api_version'] = given_config['mauth_api_version']
  @config['logger'] = given_config['logger'] || begin
    if Object.const_defined?(:Rails) && Rails.logger
      Rails.logger
    else
      require 'logger'
      is_win = RUBY_PLATFORM =~ /mswin|windows|mingw32|cygwin/i
      null_device = is_win ? 'NUL' : '/dev/null'
      ::Logger.new(File.open(null_device, File::WRONLY))
    end
  end

  request_config = { timeout: 10, open_timeout: 3 }
  request_config.merge!(symbolize_keys(given_config['faraday_options'])) if given_config['faraday_options']
  @config['faraday_options'] = { request: request_config } || {}
  @config['ssl_certs_path'] = given_config['ssl_certs_path'] if given_config['ssl_certs_path']
  @config['v2_only_authenticate'] = given_config['v2_only_authenticate'].to_s.casecmp('true').zero?
  @config['v2_only_sign_requests'] = given_config['v2_only_sign_requests'].to_s.casecmp('true').zero?
  @config['v1_only_sign_requests'] = given_config['v1_only_sign_requests'].to_s.casecmp('true').zero?
  if @config['v2_only_sign_requests'] && @config['v1_only_sign_requests']
    raise MAuth::Client::ConfigurationError, 'v2_only_sign_requests and v1_only_sign_requests may not both be true'
  end

  @config['disable_fallback_to_v1_on_v2_failure'] =
    given_config['disable_fallback_to_v1_on_v2_failure'].to_s.casecmp('true').zero?
  @config['use_rails_cache'] = given_config['use_rails_cache']
end

Class Method Details

.default_config(options = {}) ⇒ Object

returns a configuration (to be passed to MAuth::Client.new) which is configured from information stored in standard places. all of which is overridable by options in case some defaults do not apply.

options (may be symbols or strings) - any or all may be omitted where your usage conforms to the defaults.

  • mauth_config - MAuth configuration. defaults to load this from environment variables. if this is specified, no environment variable is loaded, and the given config is passed through with any other defaults applied. at the moment, the only other default is to set the logger.

  • logger - by default checks ::Rails.logger



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/mauth/client.rb', line 44

def self.default_config(options = {})
  options = options.stringify_symbol_keys

  # find mauth config
  mauth_config = options['mauth_config'] || ConfigEnv.load

  unless mauth_config.key?('logger')
    # the logger. Rails.logger if it exists, otherwise, no logger
    mauth_config['logger'] = options['logger'] || begin
      if Object.const_defined?(:Rails) && ::Rails.respond_to?(:logger)
        Rails.logger
      end
    end
  end

  mauth_config
end

Instance Method Details

#assert_private_key(err) ⇒ Object



166
167
168
# File 'lib/mauth/client.rb', line 166

def assert_private_key(err)
  raise err unless private_key
end

#cache_storeObject



170
171
172
# File 'lib/mauth/client.rb', line 170

def cache_store
  Rails.cache if @config['use_rails_cache'] && Object.const_defined?(:Rails) && ::Rails.respond_to?(:cache)
end

#client_app_uuidObject



126
127
128
# File 'lib/mauth/client.rb', line 126

def client_app_uuid
  @config['app_uuid']
end

#disable_fallback_to_v1_on_v2_failure?Boolean

Returns:

  • (Boolean)


158
159
160
# File 'lib/mauth/client.rb', line 158

def disable_fallback_to_v1_on_v2_failure?
  @config['disable_fallback_to_v1_on_v2_failure']
end

#faraday_optionsObject



142
143
144
# File 'lib/mauth/client.rb', line 142

def faraday_options
  @config['faraday_options']
end

#loggerObject



122
123
124
# File 'lib/mauth/client.rb', line 122

def logger
  @config['logger']
end

#mauth_api_versionObject



134
135
136
# File 'lib/mauth/client.rb', line 134

def mauth_api_version
  @config['mauth_api_version'] || raise(MAuth::Client::ConfigurationError, 'no configured mauth_api_version!')
end

#mauth_baseurlObject



130
131
132
# File 'lib/mauth/client.rb', line 130

def mauth_baseurl
  @config['mauth_baseurl'] || raise(MAuth::Client::ConfigurationError, 'no configured mauth_baseurl!')
end

#private_keyObject



138
139
140
# File 'lib/mauth/client.rb', line 138

def private_key
  @config['private_key']
end

#ssl_certs_pathObject



146
147
148
# File 'lib/mauth/client.rb', line 146

def ssl_certs_path
  @config['ssl_certs_path']
end

#v1_only_sign_requests?Boolean

Returns:

  • (Boolean)


162
163
164
# File 'lib/mauth/client.rb', line 162

def v1_only_sign_requests?
  @config['v1_only_sign_requests']
end

#v2_only_authenticate?Boolean

Returns:

  • (Boolean)


154
155
156
# File 'lib/mauth/client.rb', line 154

def v2_only_authenticate?
  @config['v2_only_authenticate']
end

#v2_only_sign_requests?Boolean

Returns:

  • (Boolean)


150
151
152
# File 'lib/mauth/client.rb', line 150

def v2_only_sign_requests?
  @config['v2_only_sign_requests']
end