class TrustMe

Constants

API_URL

Public: URL to the TeleSign REST API.

Returns a URI::HTTPS instance.

VERSION

Public Class Methods

config() { |config| ... } click to toggle source

Public: Gets/sets configuration info to connect to the TeleSign API.

Example

TrustMe.config do |c|
  c.customer_id = "1234"
  c.secret_key  = "secret"
end

Returns a Struct.

# File lib/trust_me.rb, line 25
def self.config
  @config ||= Struct.new(:customer_id, :secret_key).new
  yield @config if block_given?
  @config
end
new(customer_id = nil, secret_key = nil) click to toggle source

Public: Creates a new TrustMe instance.

customer_id - TeleSign customer ID secret_key - TeleSign secret key

Raises RuntimeError if credentials aren't setup.

Returns nothing.

# File lib/trust_me.rb, line 39
def initialize(customer_id = nil, secret_key = nil)
  @customer_id = customer_id || self.class.config.customer_id
  @secret_key  = secret_key  || self.class.config.secret_key

  unless @customer_id && @secret_key
    raise "You must supply API credentials. Try `TrustMe.new " \
      '"customer_id", "secret_key"` or `TrustMe.config`'
  end
end

Public Instance Methods

generate_headers(options = {}) click to toggle source

Public: Generates headers used to authenticate with the API.

options - Hash of options

:resource - API resource (required)
:params   - Params to send (required)

Raises KeyError if any required keys are missing.

See: docs.telesign.com/rest/content/rest-auth.html

Returns a Hash.

# File lib/trust_me.rb, line 120
def generate_headers(options = {})
  content_type = "application/x-www-form-urlencoded"
  date         = Time.now.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT")
  nonce        = generate_uuid

  content = [
    "POST",
    content_type,
    "", # Blank spot for "Date" header, which is overridden by x-ts-date
    "x-ts-auth-method:HMAC-SHA256",
    "x-ts-date:#{date}",
    "x-ts-nonce:#{nonce}",
    options.fetch(:params),
    options.fetch(:resource)
  ].join("\n")

  hash   = OpenSSL::Digest::SHA256.new rand.to_s
  key    = Base64.decode64(@secret_key)
  digest = OpenSSL::HMAC.digest(hash, key, content)
  auth   = Base64.encode64(digest)

  {
    "Authorization"    => "TSA #{@customer_id}:#{auth}",
    "Content-Type"     => content_type,
    "x-ts-date"        => date,
    "x-ts-auth-method" => "HMAC-SHA256",
    "x-ts-nonce"       => nonce
  }
end
send_verification_call!(number, options = {}) click to toggle source

Public: Send a verification call to the given phone number.

number - The phone number to call options - Hash of options

:verify_code - Code to send the user, if not supplied a 5-digit
               code is automatically generated
:language    - Language to use on the call, defaults to "en-US"
:ucid        - Use case ID, defaults to "TRVF"
               (Transaction Verification)

See: docs.telesign.com/rest/content/verify-call.html#index-5

Returns a Hash.

# File lib/trust_me.rb, line 62
def send_verification_call!(number, options = {})
  verify_code = options.fetch(:verify_code, generate_code)

  output = api_request(
    :resource => "/v1/verify/call",
    :params   => encode_hash(
      :ucid         => options.fetch(:ucid, "TRVF"),
      :phone_number => number,
      :language     => options.fetch(:language, "en-US"),
      :verify_code  => verify_code
    )
  )

  { :data => output, :code => verify_code }
end
send_verification_sms!(number, options = {}) click to toggle source

Public: Send a verification SMS to the given phone number.

number - The phone number to message options - Hash of options

:verify_code - Code to send the user, if not supplied a 5-digit
               code is automatically generated
:language    - Language to use on the call, defaults to "en-US"
:ucid        - Use case ID, defaults to "TRVF"
               (Transaction Verification)
:template    - Optional text template, must include "$$CODE$$"

See: docs.telesign.com/rest/content/verify-sms.html#index-5

Returns a Hash.

# File lib/trust_me.rb, line 92
def send_verification_sms!(number, options = {})
  verify_code = options.fetch(:verify_code, generate_code)

  output = api_request(
    :resource => "/v1/verify/sms",
    :params   => encode_hash(
      :ucid         => options.fetch(:ucid, "TRVF"),
      :phone_number => number,
      :language     => options.fetch(:language, "en-US"),
      :verify_code  => verify_code,
      :template     => options[:template]
    )
  )

  { :data => output, :code => verify_code }
end

Private Instance Methods

api_request(options = {}) click to toggle source

Private: Submits an API request via POST.

options - Hash of options

:resource - API resource (required)
:params   - Params to send (required)

Raises KeyError if any required keys are missing. Raises a Net::HTTP exception if the request is not successful.

Returns a Hash.

# File lib/trust_me.rb, line 202
def api_request(options = {})
  http         = Net::HTTP.new(API_URL.host, API_URL.port)
  http.use_ssl = API_URL.scheme == "https"

  if http.use_ssl?
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    http.cert_store  = OpenSSL::X509::Store.new
    http.cert_store.add_cert cacert
  end

  headers  = generate_headers(options)
  body     = options.fetch(:params)
  resource = options.fetch(:resource)
  response = http.request_post resource, body, headers
  output   = parse_json(response.body)

  if response.is_a? Net::HTTPSuccess
    output
  else
    raise response.error_type.new(
      "#{response.code} #{response.message.dump}\n" \
      "Response body: #{output.inspect}",
      response
    )
  end
end
cacert() click to toggle source

Private: CA certificate file to verify SSL connection with `API_URL`

Returns an OpenSSL::X509::Certificate instance.

# File lib/trust_me.rb, line 171
def cacert
  @cacert ||= OpenSSL::X509::Certificate.new \
    File.read(File.expand_path("../../vendor/cacert.pem", __FILE__))
end
encode_hash(hash) click to toggle source

Private: URL-encodes a hash to a string for submission via HTTP.

hash - A Hash to encode

Returns a String.

# File lib/trust_me.rb, line 164
def encode_hash(hash)
  URI.encode_www_form hash
end
generate_code() click to toggle source

Private: Generates a random 5 digit code.

Returns a String.

# File lib/trust_me.rb, line 155
def generate_code
  (0..4).map { (48 + rand(10)).chr }.join
end
generate_uuid() click to toggle source

Private: Generates a UUID.

Returns a String.

# File lib/trust_me.rb, line 188
def generate_uuid
  SecureRandom.uuid
end
parse_json(string) click to toggle source

Private: Parse the given JSON string.

string - Raw JSON string

Returns a Hash.

# File lib/trust_me.rb, line 181
def parse_json(string)
  JSON.parse string
end