ruby code to download a file from url with basic authentication - ruby-on-rails

I am new to ruby and I am learning it.
I am looking to download a file from one url(eg: https://myurl.com/123/1.zip), with basic authentication. I tried to execute the following ruby script, from windows command prompt..
require 'net/http'
uri = URI('https://myurl.com/123/1.zip')
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https',
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|
request = Net::HTTP::Get.new uri.request_uri
request.basic_auth 'john#test.com', 'John123'
response = http.request request # Net::HTTPResponse object
puts response
puts response.body
end
When I executed the script, I see no errors but the file isn't downloaded. Could you please kindly correct my code

You can try this:
require 'open-uri'
File.open('/path/your.file', "wb") do |file|
file.write open('https://myurl.com/123/1.zip', :http_basic_authentication => ['john#test.com', 'John123']).read
end

You were almost there. Just make use of ruby's send_data method
require 'net/http'
uri = URI('https://myurl.com/123/1.zip')
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https',
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|
request = Net::HTTP::Get.new uri.request_uri
request.basic_auth 'john#test.com', 'John123'
http.request(request) do |response|
send_data(response.body, filename: 'set_filename.pdf')
end
end

Related

Rescue and this external API call

I am using the following code to query maxmind for geolocation of a user's IP address. I want to make sure I am prepared for any errors/timeouts from maxmind's servers. Should I implement some type of rescue? If so, what is recommended?
uri = URI("https://geoip.maxmind.com/geoip/v2.1/city/#{request.remote_ip}?pretty")
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https',
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|
request = Net::HTTP::Get.new uri.request_uri
request.basic_auth 'USER_ID', 'KEY'
response = http.request request # Net::HTTPResponse object
if response.kind_of? Net::HTTPSuccess
location_hash = JSON.parse(response.body)
end
end
end
To rescue all exceptions:
begin
#your code
rescue Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
# do something with exception
end
You can also rescue single errors putting different rescues (use comma to rescue more than one at once):
begin
# your code
rescue Timeout::Error => e
rescue Errno::EINVAL => e
...
end

Curl on Ruby on Rails

how to use curl on ruby on rails? Like this one
curl -d 'params1[name]=name&params2[email]' 'http://mydomain.com/file.json'
Just in case you don't know, it requires 'net/http'
require 'net/http'
uri = URI.parse("http://example.org")
# Shortcut
#response = Net::HTTP.post_form(uri, {"user[name]" => "testusername", "user[email]" => "testemail#yahoo.com"})
# Full control
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data({"user[name]" => "testusername", "user[email]" => "testemail#yahoo.com"})
response = http.request(request)
render :json => response.body
Hope it'll helps others.. :)
Here is a curl to ruby's net/http converter: https://jhawthorn.github.io/curl-to-ruby/
For instance, a curl -v www.google.com command is equivalent in Ruby to:
require 'net/http'
require 'uri'
uri = URI.parse("http://www.google.com")
response = Net::HTTP.get_response(uri)
# response.code
# response.body
The most basic example of what you are trying to do is to execute this with backticks like this
`curl -d 'params1[name]=name&params2[email]' 'http://mydomain.com/file.json'`
However this returns a string, which you would have to parse if you wanted to know anything about the reply from the server.
Depending on your situation I would recommend using Faraday. https://github.com/lostisland/faraday
The examples on the site are straight forward. Install the gem, require it, and do something like this:
conn = Faraday.new(:url => 'http://mydomain.com') do |faraday|
faraday.request :url_encoded # form-encode POST params
faraday.response :logger # log requests to STDOUT
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
end
conn.post '/file.json', { :params1 => {:name => 'name'}, :params2 => {:email => nil} }
The post body will automatically be turned into a url encoded form string.
But you can just post a string as well.
conn.post '/file.json', 'params1[name]=name&params2[email]'

Trying to access Basecamp API via Rails

I'm trying to access the Basecamp API through Rails, but it responds with a SocketError. My code is like this:
require 'rubygems'
require 'net/https'
http = Net::HTTP.new('https://webonise.basecamphq.com')
http.use_ssl = true
http.start do |http|
req = Net::HTTP::GET.new('/projects.xml')
req.basic_auth 'username' , 'password'
resp, data = http.request(req)
end
The response is:
SocketError: getaddrinfo: Name or service not known
Net::HTTP.new takes a hostname, not a URI, as its first argument. Try calling URI.parse to break up the URI into the parts you want first:
require 'rubygems'
require 'net/http'
uri = URI.parse("https://webonise.basecamphq.com/")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri.request_uri)
req.basic_auth 'username', 'password'
resp = http.request(req)
body = resp.body
You'll also have to get the body in the response from the body method.

Cannot get anything in https protocol with curl, httparty or net::http

I am having trouble to get anything using https.
I can't fetch anything like:
curl -k https://graph.facebook.com
or
uri = URI('https://graph.facebook.com/davidarturo')
Net::HTTP.get(uri)
I get:
error: EOFError: end of file reached
Also there is no luck with httparty and https
As you use 'https' protocol, you must explicitly tell about it in case of using net/http library:
require 'net/http'
uri = URI('https://graph.facebook.com/davidarturo')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.scheme == 'https'
http.start do |h|
response = h.request Net::HTTP::Get.new(uri.request_uri)
puts response.body if Net::HTTPSuccess
end

Rails 3 getting gmail contacts using omniauth?

I am successfully login with google credentials using omniauth? omniauth is providing uid as following link
https://www.google.com/accounts/o8/id?id=xxxxxxxxxx
by using the above link is possible to get gmail contacts or their any other way to get gmail contact
No, Omniauth just provides authentication.
There is a gem that might be interesting for you: https://github.com/cardmagic/contacts
Quote: "Contacts is a universal interface to grab contact list information from various providers including Hotmail, AOL, Gmail, Plaxo and Yahoo."
Edit: Take a look at this blog post too: http://rtdptech.com/2010/12/importing-gmail-contacts-list-to-rails-application/
Get your client_id and client_secret from here. This is rough script, which works perfectly fine. Modified it as per your needs.
require 'net/http'
require 'net/https'
require 'uri'
require 'rexml/document'
class ImportController < ApplicationController
def authenticate
#title = "Google Authetication"
client_id = "xxxxxxxxxxxxxx.apps.googleusercontent.com"
google_root_url = "https://accounts.google.com/o/oauth2/auth?state=profile&redirect_uri="+googleauth_url+"&response_type=code&client_id="+client_id.to_s+"&approval_prompt=force&scope=https://www.google.com/m8/feeds/"
redirect_to google_root_url
end
def authorise
begin
#title = "Google Authetication"
token = params[:code]
client_id = "xxxxxxxxxxxxxx.apps.googleusercontent.com"
client_secret = "xxxxxxxxxxxxxx"
uri = URI('https://accounts.google.com/o/oauth2/token')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data('code' => token, 'client_id' => client_id, 'client_secret' => client_secret, 'redirect_uri' => googleauth_url, 'grant_type' => 'authorization_code')
request.content_type = 'application/x-www-form-urlencoded'
response = http.request(request)
response.code
access_keys = ActiveSupport::JSON.decode(response.body)
uri = URI.parse("https://www.google.com/m8/feeds/contacts/default/full?oauth_token="+access_keys['access_token'].to_s+"&max-results=50000&alt=json")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
contacts = ActiveSupport::JSON.decode(response.body)
contacts['feed']['entry'].each_with_index do |contact,index|
name = contact['title']['$t']
contact['gd$email'].to_a.each do |email|
email_address = email['address']
Invite.create(:full_name => name, :email => email_address, :invite_source => "Gmail", :user_id => current_user.id) # for testing i m pushing it into database..
end
end
rescue Exception => ex
ex.message
end
redirect_to root_path , :notice => "Invite or follow your Google contacts."
end
end
Screenshot for settings.

Resources