-
-
Save tombh/3371226 to your computer and use it in GitHub Desktop.
A utility for signing an url using OAuth in a way that's convenient for debugging
This file contains 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
# This whole thing is horrible. | |
# Firstly Yahoo's website, docs and UI are terrible. | |
# Second, OAuth!? For a simple search API, WTF!? | |
# Thirdly, this code is bodged together, undocumented and didn't work with queries that needed URI escaping (but does now) | |
# GRRRRRRRRRRRRRRRRRRRRR! | |
require 'net/http' | |
# A utility for signing an url using OAuth in a way that's convenient for debugging | |
# Note: the standard Ruby OAuth lib is here http://github.com/mojodna/oauth | |
# License: http://gist.github.com/375593 | |
# Usage: see example.rb below | |
require 'uri' | |
require 'cgi' | |
require 'openssl' | |
require 'base64' | |
class OauthUtil | |
attr_accessor :consumer_key, :consumer_secret, :token, :token_secret, :req_method, | |
:sig_method, :oauth_version, :callback_url, :params, :req_url, :base_str | |
def initialize | |
@consumer_key = '' | |
@consumer_secret = '' | |
@token = '' | |
@token_secret = '' | |
@req_method = 'GET' | |
@sig_method = 'HMAC-SHA1' | |
@oauth_version = '1.0' | |
@callback_url = '' | |
end | |
# openssl::random_bytes returns non-word chars, which need to be removed. using alt method to get length | |
# ref http://snippets.dzone.com/posts/show/491 | |
def nonce | |
Array.new( 5 ) { rand(256) }.pack('C*').unpack('H*').first | |
end | |
def percent_encode( string ) | |
# ref http://snippets.dzone.com/posts/show/1260 | |
return URI.escape( string, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]") ).gsub('*', '%2A') | |
end | |
# @ref http://oauth.net/core/1.0/#rfc.section.9.2 | |
def signature | |
key = percent_encode( @consumer_secret ) + '&' + percent_encode( @token_secret ) | |
# ref: http://blog.nathanielbibler.com/post/63031273/openssl-hmac-vs-ruby-hmac-benchmarks | |
digest = OpenSSL::Digest::Digest.new( 'sha1' ) | |
hmac = OpenSSL::HMAC.digest( digest, key, @base_str ) | |
# ref http://groups.google.com/group/oauth-ruby/browse_thread/thread/9110ed8c8f3cae81 | |
Base64.encode64( hmac ).chomp.gsub( /\n/, '' ) | |
end | |
# sort (very important as it affects the signature), concat, and percent encode | |
# @ref http://oauth.net/core/1.0/#rfc.section.9.1.1 | |
# @ref http://oauth.net/core/1.0/#9.2.1 | |
# @ref http://oauth.net/core/1.0/#rfc.section.A.5.1 | |
def query_string | |
pairs = [] | |
@params.sort.each { | key, val | | |
pairs.push( "#{ percent_encode( key ) }=#{ percent_encode( val.to_s ) }" ) | |
} | |
pairs.join '&' | |
end | |
# organize params & create signature | |
def sign( parsed_url ) | |
@params = { | |
'oauth_consumer_key' => @consumer_key, | |
'oauth_nonce' => nonce, | |
'oauth_signature_method' => @sig_method, | |
'oauth_timestamp' => Time.now.to_i.to_s, | |
'oauth_version' => @oauth_version | |
} | |
# if url has query, merge key/values into params obj overwriting defaults | |
if parsed_url.query | |
@params.merge! CGI.parse( parsed_url.query ) | |
end | |
@params['q'] = CGI.escape @params['q'].first | |
# @ref http://oauth.net/core/1.0/#rfc.section.9.1.2 | |
@req_url = parsed_url.scheme + '://' + parsed_url.host + parsed_url.path | |
# create base str. make it an object attr for ez debugging | |
# ref http://oauth.net/core/1.0/#anchor14 | |
@base_str = [ | |
@req_method, | |
percent_encode( req_url ), | |
# normalization is just x-www-form-urlencoded | |
percent_encode( query_string ) | |
].join( '&' ) | |
# add signature | |
@params[ 'oauth_signature' ] = signature | |
return self | |
end | |
end | |
def get_boss_results(args,buckets) | |
url = "http://yboss.yahooapis.com/ysearch/"+buckets+"?" | |
arg_count = 0 | |
args.each do|key,value| | |
url = url + key + "=" + CGI.escape(value) + "&" | |
++arg_count | |
end | |
if(arg_count > 0) | |
url.slice!(url.length-1) | |
end | |
parsed_url = URI.parse( url ) | |
o = OauthUtil.new | |
o.consumer_key = "RONPAULAMIRITE--" | |
o.consumer_secret = "sObRav3" | |
Net::HTTP.start( parsed_url.host ) { | http | | |
req = Net::HTTP::Get.new "#{ parsed_url.path }?#{ o.sign(parsed_url).query_string }" | |
response = http.request(req) | |
return JSON.parse(response.read_body)['bossresponse']['web']['results'] | |
} | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment