module ROAuth

Constants

OAUTH_PARAMS
SIGNATURE_METHODS

Supported signature methods;

Public Instance Methods

header(oauth, uri, params = {}, http_method = :get) click to toggle source

Return an OAuth “Authorization” HTTP header from request data

# File lib/roauth.rb, line 14
def header(oauth, uri, params = {}, http_method = :get)
  oauth = oauth.dup
  oauth[:signature_method] ||= "HMAC-SHA1"
  oauth[:version]          ||= "1.0" # Assumed version, according to the spec
  oauth[:nonce]            ||= Base64.encode64(OpenSSL::Random.random_bytes(32)).gsub(/\W/, '')
  oauth[:timestamp]        ||= Time.now.to_i
  oauth[:token]            ||= oauth.delete(:access_key)
  oauth[:token_secret]     ||= oauth.delete(:access_secret)

  sig_params = oauth_params(oauth)
  sig_params[:oauth_signature] = signature(oauth, uri, sig_params.merge(params), http_method)
  sorted_sig_params    = sig_params.sort_by{|k,v| [k.to_s, v.to_s] }
  authorization_params = sorted_sig_params.map {|key, value| 
    [escape(key), "\"#{escape(value)}\""].join("=") 
  }.join(", ")

  %Q{OAuth } + authorization_params
end
parse(header) click to toggle source
# File lib/roauth.rb, line 33
def parse(header)
  header = header.dup
  header = header.gsub!(/^OAuth\s/, "")
  header = header.split(", ")
  header = header.inject({}) {|hash, item|
    key, value = item.split("=")
    key.gsub!(/^oauth_/, "")
    value.gsub!(/(^"|"$)/, "")
    hash[key.to_sym] = unescape(value)
    hash
  }
  header[:access_key] = header[:token]
  header
end
verify(oauth, header, uri, params = {}, http_method = :get) click to toggle source
# File lib/roauth.rb, line 48
def verify(oauth, header, uri, params = {}, http_method = :get)
  header = header.is_a?(String) ? parse(header) : header.dup

  client_signature = header.delete(:signature)
  oauth[:consumer_key]     ||= header[:consumer_key]
  oauth[:token]            ||= header[:token]
  oauth[:token_secret]     ||= oauth.delete(:access_secret)
  oauth[:signature_method] ||= "HMAC-SHA1"
  oauth[:version]          ||= "1.0"

  sig_params = params.dup
  sig_params.merge!(oauth_params(header))

  client_signature == signature(oauth, uri, sig_params, http_method)
end

Protected Instance Methods

escape(value) click to toggle source

Escape characters in a string according to the OAuth spec

# File lib/roauth.rb, line 88
def escape(value)
  URI.escape(value.to_s, /[^a-zA-Z0-9\-\.\_\~]/) # Unreserved characters -- must not be encoded
end
normalize(params) click to toggle source

Normalize a string of parameters based on the OAuth spec

# File lib/roauth.rb, line 97
def normalize(params)
  # Stringify keys - so we can compare them
  params.keys.each {|key| params[key.to_s] = params.delete(key) }
  params.sort_by {|key, values| key.to_s }.map do |key, values|
    if values.is_a?(Array)
      # Multiple values were provided for a single key
      # in a hash
      values.sort_by(&:to_s).collect do |v|
        [escape(key), escape(v)] * "="
      end
    else
      [escape(key), escape(values)] * "="
    end
  end * "&"
end
oauth_params(oauth) click to toggle source
# File lib/roauth.rb, line 65
def oauth_params(oauth)
  oauth = oauth.to_a.select {|key, value|
    OAUTH_PARAMS.include?(key)
  }
  oauth.inject({}) {|hash, (key, value)|
    hash["oauth_#{key}"] = value
    hash
  }
end
signature(oauth, uri, params, http_method = :get) click to toggle source
# File lib/roauth.rb, line 75
def signature(oauth, uri, params, http_method = :get)
  uri = URI.parse(uri)
  uri.query = nil
  uri = uri.to_s

  sig_base = http_method.to_s.upcase + "&" + escape(uri) + "&" + escape(normalize(params))
  digest   = SIGNATURE_METHODS[oauth[:signature_method]]
  secret   = "#{escape(oauth[:consumer_secret])}&#{escape(oauth[:token_secret])}"

  Base64.encode64(OpenSSL::HMAC.digest(digest, secret, sig_base)).chomp.gsub(/\n/, "")
end
unescape(value) click to toggle source
# File lib/roauth.rb, line 92
def unescape(value)
  URI.unescape(value)
end