curl to Ruby request for connecting to wheniwork - ruby-on-rails

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)

Related

Bad Request trying to call service with Digest Auth from ruby

I'm trying to call a service with Digest Auth from a rails application and it always returns a 400 bad request error.
I've used net-http-digest_auth gem to create the headers but I think I've missed something.
def get_digest(url)
uri = URI.parse(url)
http = Net::HTTP.new uri.host, uri.port
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
req = Net::HTTP::Get.new(uri.request_uri)
# Fist call with the 401 and auth headers
digest_response = http.request(req)
digest_auth_request = Net::HTTP::DigestAuth.new
uri.user = digest_auth[:user]
uri.password = digest_auth[:password]
auth = digest_auth_request.auth_header uri, digest_response['www-authenticate'], 'GET', true
req.add_field 'Authorization', auth
response = http.request(req)
# Response is always #<Net::HTTPBadRequest 400 Bad Request readbody=true>
if response.code.to_i == 200
response_body = response.body
else
error
end
response_body
end
The request's headers look like this:
Digest username=\"myuser#mydomain.com\", realm=\"Digest\", algorithm=MD5-sess, qop=\"auth\", uri=\"/path/WS/my%20user/path/path/path/path/service.svc\", nonce=\"+Upgraded+v1e3f88bce1c32bd15avn421e440ca6622ebadd4522f7ed201fab1421c39d8fd15b771b972c9eb59894f8879307b9e6a5544476bc05cc7885a\", nc=00000000, cnonce=\"d42e6ea8a37aadsasdbea1231232456709\", response=\"7fbfc75cc3aasdasd342230ebf57ac37df\""
I can't figure out what's happening, is there any other gem to make this easier?
Finally found the problem by comparing browser header vs ruby header.
I wasn't calculating "nc" (calls counter) correctly. After adding +1 it started to return a 401 error (now I have a different problem ;)).

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) }

Ruby github API

I am new to ruby programming. I was trying to write below ruby code to create a comment in Github gist.
uri = URI.parse("https://api.github.com/gists/xxxxxxxxxxx/comments")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = (uri.scheme == 'https')
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri.request_uri)
request.body = {
"body" => "Chef run failed "
}.to_json
response = http.request(request)
response2 = JSON.parse(response.body)
puts response2
But I executed below script then I always get {"message"=>"Not Found", "documentation_url"=>"https://developer.github.com/v3"}
Don't know what I am doing wrong. Appreciate help.
Make sure that you're authenticated first. From the Github API docs on Authentication:
There are three ways to authenticate through GitHub API v3. Requests
that require authentication will return 404 Not Found, instead of 403
Forbidden, in some places. This is to prevent the accidental leakage
of private repositories to unauthorized users.
You can do this by creating an OAuth2 token and setting it as an HTTP header:
request['Authorization'] = 'token YOUR_OAUTH_TOKEN'
You can also pass the OAuth2 token as a POST parameter:
uri.query = URI.encode_www_form(access_token: 'YOUR_OAUTH_TOKEN')
# Encoding really isn't necessary though for this though, so this should suffice
uri.query = 'access_token=YOUR_OAUTH_TOKEN'

heroku is given a 403 forbidden for a New::HTTP.new ... any idea why?

uri = URI.parse("https://cloudfront.amazonaws.com/2010-08-01/distribution/#{config['cloud_dist_id']}/invalidation")
req = Net::HTTP::Post.new(uri.path)
req.initialize_http_header({
'x-amz-date' => date,
'Content-Type' => 'text/xml',
'Authorization' => "AWS %s:%s" % [config['access_key_id'], Base64.encode64(digest.digest)]
})
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
res = http.request(req)
When I output:
puts http.inspect
puts res.inspect
Locally it works fine:
#<Net::HTTP cloudfront.amazonaws.com:443 open=false>
#<Net::HTTPCreated 201 Created readbody=true>
But on heroku:
#<Net::HTTPForbidden 403 Forbidden readbody=true>
Failed 403
Any idea why this is failing on heroku. Why it's forbidden? Thanks
Heroku adds additional output headers your application is not aware of at the moment of signing your request.
Try to explicitly limit scope of headers which participate in signature, there are some options in AWS API for this
make it test with heroku console.
It should work as i am using same thing but using HTTParty.
Thanks

Resources