Skip to content

Instantly share code, notes, and snippets.

@dafoo
Forked from erikeldridge/example.rb
Last active December 11, 2015 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dafoo/4603517 to your computer and use it in GitHub Desktop.
Save dafoo/4603517 to your computer and use it in GitHub Desktop.
require 'oauth_util.rb'
require 'net/http'
o = OauthUtil.new
o.consumer_key = 'examplek9SGJUTUpocjZ5QjBJmQ9WVdrOVVFNHdSR2x1TkhFbWNHbzlNQS0tJnM9Y29uc3VtkZXJzZWNyZXQmeD0yYg--';
o.consumer_secret = 'exampled88d4109c63e778dsadcdd5c1875814977';
url = 'http://query.yahooapis.com/v1/yql?q=select%20*%20from%20social.updates.search%20where%20query%3D%22search%20terms%22&diagnostics=true';
parsed_url = URI.parse( url )
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)
print response.read_body
}
# 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
def encode_key_value(key, val)
"#{ percent_encode( key ) }=#{ percent_encode( val.to_s ) }"
end
# sort (very important as it affects the signature), concat, and percent encode
# sort also important within elements of same name
# @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 |
# CGI.parse returns an array for each key/values. Array.to_s includes the square brackets
# http://www.ruby-doc.org/stdlib-1.9.3/libdoc/cgi/rdoc/CGI.html#method-c-parse
if val.is_a?(Array)
val.sort.each do |val_element|
pairs.push(encode_key_value(key, val_element))
end
else
pairs.push(encode_key_value(key, val))
end
}
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
# @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
@dafoo
Copy link
Author

dafoo commented Jan 23, 2013

When arguments are passed in from the driver code, CGI.parse returns an array for each key/values. Array.to_s includes the square brackets which makes some parameters reject the string as being inva

{"bossresponse":{"responsecode":"400","reason":"Invalid value in parameter 'flags'"}}

This change will account for a param name being an Array, sorts it according to the Normalize Request Parameters section in OAuth 1.0 before encoding it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment