Rails Basic Base64 Authentication - ruby-on-rails

I'm trying to replicate this GET curl request:
curl -D- -X GET -H "Authorization: Basic dGVzdEB0YXByZXNlYXJjaC5jb206NGMzMTg2Mjg4YWUyM2ZkOTY2MWNiNWRmY2NlMTkzMGU="
-H "Content-Type: application/json" http://staging.example.com/api/v1/campaigns
The auth is generated with an email + an api key this way in Ruby:
auth = "Basic" + Base64::encode64("test#example.com:4c3186288ae23fd9661cb5dfcce1930e")
What's the best way to replicate this in Ruby/Rails?
Here's what I've been trying:
auth = "Basic" + Base64::encode64("example#example.com#:4c3186288ae23fd9661cb5dfcce1930e")
uri = URI.parse("https://www.staging.example.com/api/v1/campaigns")
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)
request.env['HTTP_AUTHORIZATION'] = auth
response = http.request(request)
puts response.body
Based off of a few other SO's and blogs I've found, but then I get undefined method 'env' for #<Net::HTTP::Get GET> back.
Any ideas how I can set that so the message comes out like this?
Authorization: Basic dGVzdEB0YXByZXNlYXJjaC5jb206NGMzMTg2Mjg4YWUyM2ZkOTY2MWNiNWRmY2NlMTkzMGU=

request['Authorization'] = "Basic " + Base64::encode64("example#example.com#:4c3186288ae23fd9661cb5dfcce1930e")

Here's a more straightforward way, using request.basic_auth to handle all the messy details:
request = Net::HTTP::Post.new(uri)
request.basic_auth(username, password)
http = Net::HTTP.new(uri.host, uri.port)
response = http.request(request)

Related

Rails - How to add contacts to SendGrid marketing campaigns via API

I need to make HTTP get and post requests with SendGrid to add contacts to our account, however there doesn't seem to be a gem for their email marketing functionality.
It boils down to making a few requests however I can't get past their authentication step.
They say to do this
curl -X "GET" "https://api.sendgrid.com/v3/templates" -H "Authorization: Bearer Your.API.Key-HERE" -H "Content-Type: application/json"
And using the Rest-Client gem I'm trying to make the authentication request like so...
username = 'username'
api_key = 'SG.MY_API_KEY'
key = Base64.encode64(username + ":" + api_key)
headers = {"Authorization" => "Bearer #{key}", "Content-Type" => "application/json"}
response = RestClient.get 'https://api.sendgrid.com/v3/templates', headers
which returns...
RestClient::Unauthorized: 401 Unauthorized: {"errors":[{"field":null,"message":"authorization required"}]}
The ultimate objective of using their API is to add contacts.
How am I incorrectly making this get request?
I ended up figuring it out. For future reference, here's the code that worked...
require 'rest_client'
api_key = 'YOUR_API_KEY'
headers = {'Authorization' => "Bearer #{api_key}"}
data = {:email => 'email#website.com'}
response = RestClient.post 'https://api.sendgrid.com/v3/contactdb/recipients', [data].to_json, headers
To add marketing contacts to your SendGrid account via the API,
see the documentation at https://sendgrid.api-docs.io/v3.0/contacts-api-recipients/add-recipients
You can see sample code in the "code generation" section of the page.
require 'uri'
require 'net/http'
url = URI("https://api.sendgrid.com/v3/contactdb/recipients")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["authorization"] = 'Bearer <<YOUR_API_KEY>>'
request["content-type"] = 'application/json'
request.body = "[{\"email\":\"example#example.com\",\"first_name\":\"\",\"last_name\":\"User\",\"age\":25},{\"email\":\"example2#example.com\",\"first_name\":\"Example\",\"last_name\":\"User\",\"age\":25}]"
response = http.request(request)
puts response.read_body

Rails http GET request with no ssl verification and basic auth

I am trying to make a http get request as specified in the title.
What I've written:
uri = URI.parse("https://myaddress.com")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
#data = http.get(uri.request_uri)
The request is sent where I want it to be sent and I receive an Unauthorized response (as expected, because I did not specify the basic auth).
I've tried
http.basic_auth 'user', 'pass'
But there's no such method for the type of my http variable.
How can I add the auth details?
Update: I tried to use something like here RUBY - SSL, Basic Auth, and POST, but after replacing Post with Get, I cannot use the 'use_ssl', nor 'verify_mode' attributes (I get no such attribute error).
Update 2: I figured out that I can set the 'use_ssl' attribute on a Net::HTTP object and the 'basic_auth' on a Net::HTTP::Get object.
Now the question is how can I make them work together?
Well, I ended up finding an answer. Maybe this will help others:
url = URI.parse('https://myaddress.com')
req = Net::HTTP::Get.new(url.path)
req.basic_auth 'user', 'pass'
sock = Net::HTTP.new(url.host, url.port)
sock.use_ssl = true
sock.verify_mode = OpenSSL::SSL::VERIFY_NONE
resp = sock.start {|http| http.request(req) }

RAILS Send get request to onesignal using API Key RESTApi

Its a RESTAPI and I need to send get request to onesignal.
url = https://onesignal.com/api/v1/apps
All they have mentioned is this:
curl --include \
--header "Authorization: Basic your_key_here" \
https://onesignal.com/api/v1/apps
I have tried something like this:
def index
url = URI.parse('https://onesignal.com/api/v1/apps?apikey=mykey')
req = Net::HTTP::Get.new(url.to_s)
res = Net::HTTP.start(url.host, url.port) {|http|
http.request(req)
}
puts res.body
end
but this doesn't work.
The result should be in json.
I get this error:
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx/1.4.6 (Ubuntu)</center>
</body>
</html>
Based on code from OneSignal webpage your request should be:
uri = URI.parse("https://onesignal.com/api/v1/apps")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(
uri.path,
"Content-Type" => "application/json",
"Authorization" => "Basic NGXXX...XXXBlNjJj"
)
response = http.request(request)
puts response.body
In your case error was associated with not using http.use_ssl = true, but you have several other things to add, like authorization header for example.

curl to Ruby request for connecting to wheniwork

Back story
I've spent a few days on the Ruby gem for wheniwork, and it's been a nightmare. To make a long story short, the gem had a dependency of an older version of activesupport and I basically forked their repo and made a compatible version for my ruby project. I was able to create a new gem and attempted to use it, but I was getting the following json message:
{"error"=>"User login required for this resource.", "code"=>1000}
The username, password, and api key were set. What I basically need to do is access our account on wheniwork, and retrieve data.
This is an example using the curl command
curl https://api.wheniwork.com/2/login \
--data '{"username":"user#example.com","password":"*******"}' \
-H "W-Key: iworksoharditsnotfunny"
Essentially, I would get some kind of return object from wheniwork that would contain the token. I'd use this token for future requests to the wheniwork site.
To (Ruby)
A new attempt to translate this to Ruby
require 'net/http'
data = {'credentials' => {'username' => 'XXXXX#XXXXX.com','password' => 'XXXXX', 'W-Key' => '111111111XXXXX'}}
uri = URI.parse("https://api.wheniwork.com/2/login/")
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.path, initheader = {'Content-Type' =>'application/json'})
request.add_field('Content-Type', 'application/json')
request.body = data.to_json
response = http.request(request)
Result:
#<Net::HTTPUnauthorized 401 Unauthorized readbody=true>
If you have any idea or clue (or basically anything that would help me here), I would appreciate it beyond words. Thanks!
Got it!! The major issue(s) were that the api key and (username+password) combo are two separate pieces.
I was so close the entire time, but here it is:
data = {'username' => 'XXXX#XXXXXXX.com','password' => 'XXXXX'}
uri = URI.parse("https://api.wheniwork.com/2/login/")
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.path)
request.add_field('W-Key', 'XXXXXXXXXXXXX')
request.body = data.to_json
response = http.request(request)
puts JSON.parse(response.body)

need help in making post request in ruby

I need help in creating a post request in ruby. but i don't want to use Net::Http library. i just want to use curl commands to make post requests.
here is my existing code.
`
uri = URI.parse("http://example.com")
header = {'Content-Type' => 'application/json','Accept' => "application/json"}
req_data = {"name" => params[:user][:login], "pass" =>params[:user][:password]}
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = req_data.to_json
response = http.request(request)
`
You have a chance to execute command from user's input. With Shellwords.escape should be ok.
cmd_tpl = %{curl -H "Content-Type: application/json" -H "Accept: application/json" -d "name=%s&pass=%s" %s}
cmd = cmd % [
Shellwords.escape(URI.encode(params[:user][:login])),
Shellwords.escape(URI.encode(params[:user][:password])),
Shellwords.escape("http://example.com")
]
content = `#{cmd}`

Resources