Created
December 19, 2016 23:09
-
-
Save cyberhobo/12ec1fb84595c74494258a80f531846b to your computer and use it in GitHub Desktop.
Basis for a Ruby Freemius HTTP API client.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Freemius | |
API_HOST = 'api.freemius.com' | |
SANDBOX_HOST = 'sandbox-api.freemius.com' | |
class Base | |
# Options taken from http://docs.freemius.apiary.io/#introduction/the-authentication-header | |
# * host Default is api.freemius.com | |
# * api_version Default is v1 | |
# * scope_entity Default is 'plugin'. Could also be 'developer', 'install', 'site', 'user' | |
# * scope_entity_id Required. | |
# * public_key Required. | |
# * secret_key Required. | |
def initialize(options) | |
Freemius.host = options.fetch(:host) { API_HOST } | |
Freemius.api_version = options.fetch(:api_version) { 'v1' } | |
Freemius.scope_entity = options.fetch(:scope_entity) { 'plugin' } | |
Freemius.scope_entity_id = options.fetch(:scope_entity_id) do | |
raise ArgumentError.new('Scope entity ID is required to initialize Freemius') if Freemius.scope_entity_id.nil? | |
end | |
Freemius.public_key = options.fetch(:public_key) do | |
raise ArgumentError.new('Public key is required to initialize Freemius') if Freemius.public_key.nil? | |
end | |
Freemius.secret_key = options.fetch(:secret_key) do | |
raise ArgumentError.new('Secret key is required to initialize Freemius') if Freemius.secret_key.nil? | |
end | |
end | |
def base_url | |
"https://#{Freemius.host}#{base_path}" | |
end | |
def base_path | |
"/#{Freemius.api_version}/#{Freemius.scope_entity.pluralize}/#{Freemius.scope_entity_id}" | |
end | |
def submit(method, path, data = {}) | |
body = [:put, :post].include?(method) ? data.to_json : '' | |
headers = headers(method, "#{base_path}/#{path.split('?').first}", body) | |
response = http_client.run_request(method, path, body, headers) | |
JSON.parse(response.body) | |
end | |
private | |
def http_client | |
@http_client ||= Faraday.new(base_url, :ssl => { :ca_file => ENV['CERT_PATH'], :version => :TLSv1 }) | |
end | |
def headers(method, path, body) | |
formatted_date = Time.now.strftime('%a, %e %b %Y %H:%M:%S %z') | |
content_type = 'application/json' | |
md5 = body.empty? ? '' : Digest::MD5.hexdigest(body) | |
signature_content = "#{method.to_s.upcase}\n#{md5}\n#{content_type}\n#{formatted_date}\n#{path}" | |
digest = OpenSSL::Digest.new('sha256') | |
signature = base64_url_encode(OpenSSL::HMAC.hexdigest(digest, Freemius.secret_key, signature_content)) | |
{ | |
'Authorization' => "FS #{Freemius.scope_entity_id}:#{Freemius.public_key}:#{signature}", | |
'Content-Type' => content_type, | |
'Date' => formatted_date | |
} | |
end | |
def base64_url_encode(data) | |
Base64::encode64( data ).tr('+/', '-_').gsub('=', '').gsub("\n", '') | |
end | |
end | |
class << self | |
attr_accessor :host, | |
:scope_entity, | |
:scope_entity_id, | |
:public_key, | |
:secret_key, | |
:api_version | |
def configure | |
yield self | |
true | |
end | |
alias :config :configure | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment