OAuth ruby examples
Jump to navigation
Jump to search
As part of the set of OAuth examples, here are some basic examples in ruby, using the ruby OAuth gem. Feel free to improve. Since they are of no use themselves, it doesn't make much sense to run them! If you need any help, please ask away either on dev@openstreetmap.org or contact Gravitystorm
Registering and Authorising your application
#!/usr/bin/ruby
# Get all the auth details you need
# You wouldn't actually do it this way, but hey.
# Normally you'd distribute the consumer stuff with your
# application, and each user gets the access_token stuff
# But hey, this is just a demo.
require 'rubygems'
require 'oauth'
require 'yaml'
# Format of auth.yml:
# consumer_key: (from osm.org)
# consumer_secret: (from osm.org)
# token: (use oauth setup flow to get this)
# token_secret: (use oauth setup flow to get this)
auth={}
puts "First, go register a new application at "
puts "http://api06.dev.openstreetmap.org/oauth_clients/new"
puts "Tick the appropriate boxes"
puts "Enter the consumer key you are assigned:"
auth["consumer_key"] = gets.strip
puts "Enter the consumer secret you are assigned:"
auth["consumer_secret"] = gets.strip
puts "Your application is now set up, but you need to register"
puts "this instance of it with your user account."
@consumer=OAuth::Consumer.new auth["consumer_key"],
auth["consumer_secret"],
{:site=>"http://api06.dev.openstreetmap.org"}
@request_token = @consumer.get_request_token
puts "Visit the following URL, log in if you need to, and authorize the app"
puts @request_token.authorize_url
puts "When you've authorized that token, enter the verifier code you are assigned:"
verifier = gets.strip
puts "Converting request token into access token..."
@access_token=@request_token.get_access_token(:oauth_verifier => verifier)
auth["token"] = @access_token.token
auth["token_secret"] = @access_token.secret
File.open('auth.yaml', 'w') {|f| YAML.dump(auth, f)}
puts "Done. Have a look at auth.yaml to see what's there."
Making basic HTTP requests
#!/usr/bin/ruby
# Simple OSM Auth example showing GET PUT and DELETE methods
# Requires OAuth rubygem
require 'rubygems'
require 'oauth'
require 'date'
require 'yaml'
# Format of auth.yml:
# consumer_key: (from osm.org)
# consumer_secret: (from osm.org)
# token: (use oauth setup flow to get this)
# token_secret: (use oauth setup flow to get this)
auth = YAML.load(File.open('auth.yaml'))
# The consumer key and consumer secret are the identifiers for this particular application, and are
# issued when the application is registered with the site. Use your own.
@consumer=OAuth::Consumer.new auth['consumer_key'],
auth['consumer_secret'],
{:site=>"http://api06.dev.openstreetmap.org"}
# Create the access_token for all traffic
@access_token = OAuth::AccessToken.new(@consumer, auth['token'], auth['token_secret'])
# Use the access token for various commands. Although these take plain strings, other API methods
# will take XML documents.
@access_token.put('/api/0.6/user/preferences/demo_last_run_time', DateTime.now().to_s, {'Content-Type' => 'text/plain' })
@access_token.put('/api/0.6/user/preferences/deleteme', "This shouldn't be seen", {'Content-Type' => 'text/plain' })
@access_token.delete('/api/0.6/user/preferences/deleteme')
puts @access_token.get('/api/0.6/user/preferences').body
Multipart form uploads
One of the harder things to do is uploading GPX files, since that requires a multipart/form-data POST. The OAuth gem doesn't (appear to) support this, so the request has to be hand-constructed and then signed by the access token. This might change in future versions.
#!/usr/bin/ruby
# hacky script for uploading a file to the OSM GPX api.
# liberally stolen^Winspired by http://gist.github.com/97756
#
# Format of auth.yml:
# consumer_key: (from osm.org)
# consumer_secret: (from osm.org)
# token: (use oauth setup flow to get this)
# token_secret: (use oauth setup flow to get this)
require 'rubygems'
require 'oauth'
require 'xml/libxml'
require 'date'
CRLF = "\r\n"
endpoint_gpx_create = 'http://api06.dev.openstreetmap.org/api/0.6/gpx/create'
if ARGV.size < 1
puts "Usage: #{$0} path_to_gpx_file"
puts "e.g. #{$0} /home/gravitystorm/osm/tracks/20081128.gpx"
exit(1)
end
# Take GPX file from commandline argument
file = File.new(ARGV[0])
# Format of auth.yml:
# consumer_key: (from osm.org)
# consumer_secret: (from osm.org)
# token: (use oauth setup flow to get this)
# token_secret: (use oauth setup flow to get this)
auth = YAML.load(File.open('auth.yaml'))
@consumer=OAuth::Consumer.new auth['consumer_key'],
auth['consumer_secret'],
{:site=>"http://api06.dev.openstreetmap.org"}
@access_token = OAuth::AccessToken.new(@consumer, auth['token'], auth['token_secret'])
# Encodes the request as multipart
def add_multipart_data(req,params)
boundary = Time.now.to_i.to_s(16)
req["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
body = ""
params.each do |key,value|
esc_key = CGI.escape(key.to_s)
body << "--#{boundary}#{CRLF}"
if value.respond_to?(:read)
body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{File.basename(value.path)}\"#{CRLF}"
body << "Content-Type: text/xml#{CRLF*2}"
body << value.read
else
body << "Content-Disposition: form-data; name=\"#{esc_key}\"#{CRLF*2}#{value}"
end
body << CRLF
end
body << "--#{boundary}--#{CRLF*2}"
req.body = body
req["Content-Length"] = req.body.size
end
# Uses the OAuth gem to add the signed Authorization header
def add_oauth(req)
@consumer.sign!(req,@access_token)
end
#Actually do the request and print out the response
url = URI.parse(endpoint_gpx_create)
Net::HTTP.new(url.host, url.port).start do |http|
req = Net::HTTP::Post.new(url.request_uri)
add_multipart_data(req,:file=>file, :tags=>'heheheheh', :description=>'upside down', :public=>'1')
add_oauth(req)
res = http.request(req)
puts res.body
end