telesign-2.2.4/0000755000004100000410000000000014360310073013356 5ustar www-datawww-datatelesign-2.2.4/telesign.gemspec0000644000004100000410000000414414360310073016540 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: telesign 2.2.4 ruby lib Gem::Specification.new do |s| s.name = "telesign".freeze s.version = "2.2.4" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["TeleSign".freeze] s.date = "2017-05-25" s.description = "TeleSign Ruby SDK".freeze s.email = "support@telesign.com".freeze s.files = ["lib/telesign.rb".freeze, "lib/telesign/appverify.rb".freeze, "lib/telesign/messaging.rb".freeze, "lib/telesign/phoneid.rb".freeze, "lib/telesign/rest.rb".freeze, "lib/telesign/score.rb".freeze, "lib/telesign/util.rb".freeze, "lib/telesign/voice.rb".freeze] s.homepage = "http://rubygems.org/gems/telesign".freeze s.licenses = ["MIT".freeze] s.rubygems_version = "3.2.5".freeze s.summary = "TeleSign Ruby SDK".freeze if s.respond_to? :specification_version then s.specification_version = 4 end if s.respond_to? :add_runtime_dependency then s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_runtime_dependency(%q.freeze, [">= 3.0.0", "< 5.0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) else s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 3.0.0", "< 5.0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) end end telesign-2.2.4/lib/0000755000004100000410000000000014360310073014124 5ustar www-datawww-datatelesign-2.2.4/lib/telesign.rb0000644000004100000410000000026714360310073016270 0ustar www-datawww-datarequire 'telesign/appverify' require 'telesign/messaging' require 'telesign/phoneid' require 'telesign/rest' require 'telesign/score' require 'telesign/util' require 'telesign/voice' telesign-2.2.4/lib/telesign/0000755000004100000410000000000014360310073015736 5ustar www-datawww-datatelesign-2.2.4/lib/telesign/phoneid.rb0000644000004100000410000000135614360310073017716 0ustar www-datawww-datarequire 'telesign/rest' PHONEID_RESOURCE = '/v1/phoneid/%{phone_number}' module Telesign # A set of APIs that deliver deep phone number data attributes that help optimize the end user # verification process and evaluate risk. class PhoneIdClient < RestClient # The PhoneID API provides a cleansed phone number, phone type, and telecom carrier information to determine the # best communication method - SMS or voice. # # See https://developer.telesign.com/docs/phoneid-api for detailed API documentation. def phoneid(phone_number, **params) self.post(PHONEID_RESOURCE % {:phone_number => phone_number}, **params) end private def content_type "application/json" end end end telesign-2.2.4/lib/telesign/rest.rb0000644000004100000410000001757214360310073017254 0ustar www-datawww-datarequire 'pp' require 'json' require 'time' require 'base64' require 'openssl' require 'securerandom' require 'net/http/persistent' module Telesign SDK_VERSION = '2.2.4' # The TeleSign RestClient is a generic HTTP REST client that can be extended to make requests against any of # TeleSign's REST API endpoints. # # RequestEncodingMixin offers the function _encode_params for url encoding the body for use in string_to_sign outside # of a regular HTTP request. # # See https://developer.telesign.com for detailed API documentation. class RestClient @@user_agent = "TeleSignSDK/ruby-{#{SDK_VERSION} #{RUBY_DESCRIPTION} net/http/persistent" # A simple HTTP Response object to abstract the underlying net/http library response. # * +http_response+ - A net/http response object. class Response attr_accessor :status_code, :headers, :body, :ok, :json def initialize(http_response) @status_code = http_response.code @headers = http_response.to_hash @body = http_response.body @ok = http_response.kind_of? Net::HTTPSuccess begin @json = JSON.parse(http_response.body) rescue JSON::JSONError @json = nil end end end # TeleSign RestClient, useful for making generic RESTful requests against the API. # # * +customer_id+ - Your customer_id string associated with your account. # * +api_key+ - Your api_key string associated with your account. # * +rest_endpoint+ - (optional) Override the default rest_endpoint to target another endpoint. # * +timeout+ - (optional) How long to wait for the server to send data before giving up, as a float. def initialize(customer_id, api_key, rest_endpoint: 'https://rest-api.telesign.com', proxy: nil, timeout: 10) @customer_id = customer_id @api_key = api_key @rest_endpoint = rest_endpoint @http = Net::HTTP::Persistent.new(name: 'telesign', proxy: proxy) unless timeout.nil? @http.open_timeout = timeout @http.read_timeout = timeout end end # Generates the TeleSign REST API headers used to authenticate requests. # # Creates the canonicalized string_to_sign and generates the HMAC signature. This is used to authenticate requests # against the TeleSign REST API. # # See https://developer.telesign.com/docs/authentication for detailed API documentation. # # * +customer_id+ - Your account customer_id. # * +api_key+ - Your account api_key. # * +method_name+ - The HTTP method name of the request as a upper case string, should be one of 'POST', 'GET', # 'PUT' or 'DELETE'. # * +resource+ - The partial resource URI to perform the request against, as a string. # * +url_encoded_fields+ - HTTP body parameters to perform the HTTP request with, must be a urlencoded string. # * +date_rfc2616+ - The date and time of the request formatted in rfc 2616, as a string. # * +nonce+ - A unique cryptographic nonce for the request, as a string. # * +user_agent+ - (optional) User Agent associated with the request, as a string. def self.generate_telesign_headers(customer_id, api_key, method_name, resource, content_type, encoded_fields, date_rfc2616: nil, nonce: nil, user_agent: nil) if date_rfc2616.nil? date_rfc2616 = Time.now.httpdate end if nonce.nil? nonce = SecureRandom.uuid end content_type = (%w[POST PUT].include? method_name) ? content_type : '' auth_method = 'HMAC-SHA256' string_to_sign = "#{method_name}" string_to_sign << "\n#{content_type}" string_to_sign << "\n#{date_rfc2616}" string_to_sign << "\nx-ts-auth-method:#{auth_method}" string_to_sign << "\nx-ts-nonce:#{nonce}" if !content_type.empty? and !encoded_fields.empty? string_to_sign << "\n#{encoded_fields}" end string_to_sign << "\n#{resource}" digest = OpenSSL::Digest.new('sha256') key = Base64.decode64(api_key) signature = Base64.encode64(OpenSSL::HMAC.digest(digest, key, string_to_sign)).strip authorization = "TSA #{customer_id}:#{signature}" headers = { 'Authorization'=>authorization, 'Date'=>date_rfc2616, 'x-ts-auth-method'=>auth_method, 'x-ts-nonce'=>nonce } unless user_agent.nil? headers['User-Agent'] = user_agent end headers end # Generic TeleSign REST API POST handler. # # * +resource+ - The partial resource URI to perform the request against, as a string. # * +params+ - Body params to perform the POST request with, as a hash. def post(resource, **params) execute(Net::HTTP::Post, 'POST', resource, **params) end # Generic TeleSign REST API GET handler. # # * +resource+ - The partial resource URI to perform the request against, as a string. # * +params+ - Body params to perform the GET request with, as a hash. def get(resource, **params) execute(Net::HTTP::Get, 'GET', resource, **params) end # Generic TeleSign REST API PUT handler. # # * +resource+ - The partial resource URI to perform the request against, as a string. # * +params+ - Body params to perform the PUT request with, as a hash. def put(resource, **params) execute(Net::HTTP::Put, 'PUT', resource, **params) end # Generic TeleSign REST API DELETE handler. # # * +resource+ - The partial resource URI to perform the request against, as a string. # * +params+ - Body params to perform the DELETE request with, as a hash. def delete(resource, **params) execute(Net::HTTP::Delete, 'DELETE', resource, **params) end private # Generic TeleSign REST API request handler. # # * +method_function+ - The net/http request to perform the request. # * +method_name+ - The HTTP method name, as an upper case string. # * +resource+ - The partial resource URI to perform the request against, as a string. # * +params+ - Body params to perform the HTTP request with, as a hash. def execute(method_function, method_name, resource, **params) resource_uri = URI.parse("#{@rest_endpoint}#{resource}") encoded_fields = '' if %w[POST PUT].include? method_name request = method_function.new(resource_uri.request_uri) if content_type == "application/x-www-form-urlencoded" unless params.empty? encoded_fields = URI.encode_www_form(params, Encoding::UTF_8) request.set_form_data(params) end else encoded_fields = params.to_json request.body = encoded_fields request.set_content_type("application/json") end else resource_uri.query = URI.encode_www_form(params, Encoding::UTF_8) request = method_function.new(resource_uri.request_uri) end headers = RestClient.generate_telesign_headers(@customer_id, @api_key, method_name, resource, content_type, encoded_fields, user_agent: @@user_agent) headers.each do |k, v| request[k] = v end http_response = @http.request(resource_uri, request) Response.new(http_response) end def content_type "application/x-www-form-urlencoded" end end end telesign-2.2.4/lib/telesign/voice.rb0000644000004100000410000000205314360310073017370 0ustar www-datawww-datarequire 'telesign/rest' VOICE_RESOURCE = '/v1/voice' VOICE_STATUS_RESOURCE = '/v1/voice/%{reference_id}' module Telesign # TeleSign's Voice API allows you to easily send voice messages. You can send alerts, reminders, and notifications, # or you can send verification messages containing time-based, one-time passcodes (TOTP). class VoiceClient < RestClient # Send a voice call to the target phone_number. # # See https://developer.telesign.com/docs/voice-api for detailed API documentation. def call(phone_number, message, message_type, **params) self.post(VOICE_RESOURCE, phone_number: phone_number, message: message, message_type: message_type, **params) end # Retrieves the current status of the voice call. # # See https://developer.telesign.com/docs/voice-api for detailed API documentation. def status(reference_id, **params) self.get(VOICE_STATUS_RESOURCE % {:reference_id => reference_id}, **params) end end end telesign-2.2.4/lib/telesign/appverify.rb0000644000004100000410000000171414360310073020273 0ustar www-datawww-datarequire 'telesign/rest' APPVERIFY_STATUS_RESOURCE = '/v1/mobile/verification/status/%{external_id}' module Telesign # App Verify is a secure, lightweight SDK that integrates a frictionless user verification process into existing # native mobile applications. class AppVerifyClient < RestClient # Retrieves the verification result for an App Verify transaction by external_id. To ensure a secure verification # flow you must check the status using TeleSign's servers on your backend. Do not rely on the SDK alone to # indicate a successful verification. # # See https://developer.telesign.com/docs/app-verify-android-sdk-self#section-get-status-service or # https://developer.telesign.com/docs/app-verify-ios-sdk-self#section-get-status-service for detailed # API documentation. def status(external_id, **params) self.get(APPVERIFY_STATUS_RESOURCE % {:external_id => external_id}, **params) end end end telesign-2.2.4/lib/telesign/messaging.rb0000644000004100000410000000210114360310073020232 0ustar www-datawww-datarequire 'telesign/rest' MESSAGING_RESOURCE = '/v1/messaging' MESSAGING_STATUS_RESOURCE = '/v1/messaging/%{reference_id}' module Telesign # TeleSign's Messaging API allows you to easily send SMS messages. You can send alerts, reminders, and notifications, # or you can send verification messages containing one-time passcodes (OTP). class MessagingClient < RestClient # Send a message to the target phone_number. # # See https://developer.telesign.com/docs/messaging-api for detailed API documentation. def message(phone_number, message, message_type, **params) self.post(MESSAGING_RESOURCE, phone_number: phone_number, message: message, message_type: message_type, **params) end # Retrieves the current status of the message. # # See https://developer.telesign.com/docs/messaging-api for detailed API documentation. def status(reference_id, **params) self.get(MESSAGING_STATUS_RESOURCE % {:reference_id => reference_id}, **params) end end end telesign-2.2.4/lib/telesign/score.rb0000644000004100000410000000125714360310073017403 0ustar www-datawww-datarequire 'telesign/rest' SCORE_RESOURCE = '/v1/score/%{phone_number}' module Telesign # Score provides risk information about a specified phone number. class ScoreClient < RestClient # Score is an API that delivers reputation scoring based on phone number intelligence, traffic patterns, machine # learning, and a global data consortium. # # See https://developer.telesign.com/docs/score-api for detailed API documentation. def score(phone_number, account_lifecycle_event, **params) self.post(SCORE_RESOURCE % {:phone_number => phone_number}, account_lifecycle_event: account_lifecycle_event, **params) end end end telesign-2.2.4/lib/telesign/util.rb0000644000004100000410000000231514360310073017241 0ustar www-datawww-datarequire 'base64' require 'openssl' require 'securerandom' module Telesign class Util def self.random_with_n_digits(n) n.times.map { SecureRandom.random_number(10) }.join end # Verify that a callback was made by TeleSign and was not sent by a malicious client by verifying the signature. # # * +api_key+ - the TeleSign API api_key associated with your account. # * +signature+ - the TeleSign Authorization header value supplied in the callback, as a string. # * +json_str+ - the POST body text, that is, the JSON string sent by TeleSign describing the transaction status. def verify_telesign_callback_signature(api_key, signature, json_str) digest = OpenSSL::Digest.new('sha256') key = Base64.decode64(api_key) your_signature = Base64.encode64(OpenSSL::HMAC.digest(digest, key, json_str)).strip unless signature.length == your_signature.length return false end # avoid timing attack with constant time equality check signatures_equal = true signature.split('').zip(your_signature.split('')).each do |x, y| unless x == y signatures_equal = false end end signatures_equal end end end