How to perform this kind of CURL request on Ruby - ruby-on-rails

I am using an API provided by my web host with whom I can register new clients and domains. Unfortunately they don't provide much documentation (basically none) and I'm not very used to cURL
They give ONE and very superficial example of how to create a new client, and it is as follows
curl -d "clienteTipo=I&clienteCPFCNPJ=00112135045&clienteEmpresa=NomeEmpresa&clienteNome=meunome&clienteEmail=email#dominio.com.br&clienteEmailCobranca=emailcobranca#dominio.com.br&clienteSenhaPainel=654321&clienteFone=555100000000&clienteFax=555100000001&clienteCEP=44587421&clienteEndereco=ruanome&clienteBairro=meubairro&clienteCidade=porto alegre&clienteEstado=rs&clienteLimiteMapeamento=1&clienteLimiteSubdominio=2&clienteLimiteMysql=3&clienteLimiteMssql=1&clienteLimitePgsql=1&clienteLimiteFirebird=1&clienteLimiteFTPADD=1&clienteUniBox=on&clienteAcessoFTP=on&clienteAcessoDownloadBackup=on" -k --digest -u usuario:senha -X POST https://api.kinghost.net/cliente
How can I transform this on a cURL request on Ruby keeping the parameters as informed above?
This must be a POST, but I wonder how I have to inform these parameters, they look like a query string. And what is this Digest thing?

Here is an (untested) example using rest-client that might get you started https://github.com/rest-client/rest-client).
According to what I was able to find online, rest-client automatically supports the digest authentication that that curl request is doing.
require 'rest-client'
response = RestClient::Request.execute(
method: :post,
url: 'https://api.kinghost.net/cliente',
verify_ssl: false,
user: "usuario",
password: "senha",
headers: {
params: {
clienteTipo: "I",
clienteCPFCNPJ: "00112135045",
clienteEmpresa: "NomeEmpresa",
clienteNome: "meunome",
clienteEmail: "email#dominio.com.br",
clienteEmailCobranca: "emailcobranca#dominio.com.br",
clienteSenhaPainel: "654321",
clienteFone: "555100000000",
clienteFax: "555100000001",
clienteCEP: "44587421",
clienteEndereco: "ruanome",
clienteBairro: "meubairro",
clienteCidade: "porto alegre",
clienteEstado: "rs",
clienteLimiteMapeamento: "1",
clienteLimiteSubdominio: "2",
clienteLimiteMysql: "3",
clienteLimiteMssql: "1",
clienteLimitePgsql: "1",
clienteLimiteFirebird: "1",
clienteLimiteFTPADD: "1",
clienteUniBox: "on",
clienteAcessoFTP: "on",
clienteAcessoDownloadBackup: "on"
}
}
)

the wonders of curl :)
-k means unsecure (i.e don't check SSL)
--digest is the authentication type
-u name:password is the actual username and password
-X POST it's a post
-d "blah blah" blah blah is the payload
now onto ruby:
I would look at https://github.com/rest-client/rest-client or at https://github.com/jnunemaker/httparty
It's just a matter of figuring out how to perform the post. The digest might be tricky but IIRC it can be some via Authorization header.

after struggling for a while and testing different libraries, I used Ruby to run a system command, since cURL is not dependant on Ruby
output = `curl -d "clienteTipo=#{client_type}&clienteCPFCNPJ=#{client_id}&clienteEmpresa=#{company_name}&clienteNome=#{client_name}&clienteEmail=#{client_email}&clienteEmailCobranca=#{client_billing_email}&clienteSenhaPainel=#{password}&clienteFone=#{client_phone}&clienteFax=#{client_fax}&clienteCEP=#{client_zip_code}&clienteEndereco=#{client_address}&clienteBairro=#{client_neighborhood}&clienteCidade=#{client_city}&clienteEstado=#{client_state}&clienteLimiteMapeamento=1&clienteLimiteSubdominio=1&clienteLimiteMysql=1&clienteLimiteMssql=1&clienteLimitePgsql=1&clienteLimiteFirebird=1&clienteLimiteFTPADD=1&clienteUniBox=on&clienteAcessoFTP=on&clienteAcessoDownloadBackup=on" -k --digest -u MY_USER:MY_PASSWORD -X POST API_URL`
p output
xml = Hash.from_xml(output) #in my case it returns a XML string
Now output contains the response

Related

Ratpack/Groovy - read the body of a call

I want to create a "mock" server using Ratpack/Groovy and we need to read the data-raw from a call
I haven't had a problem reading headers or parameters, but I need to read the body of a request
Examplle:
curl --location --POST request 'http://localhost:5050/authenticate' \
--header 'Content-type: application/json' \
--raw-data '{
"username": "testbase01#domain.com",
"password": "12345678"
}'
we need to parse and process the username and password fields
We have tried to read the request.body, or the body.text, but we have not been successful.
Basically the example found in the solution at https://stackoverflow.com/questions/23636248/parse-json-in-ratpack-groovy would be what we need, but it hasn't worked for us either
Our environment has the following dependencies
#Grab('io.ratpack:ratpack-groovy:1.6.1'),
#Grab('org.slf4j:slf4j-simple:1.7.22'),
#Grab("io.ratpack:ratpack-jackson:0.9.17")
and we are using https://github.com/Vad1mo/hello-world-rest as primary image
If you have a small example, to be able to adapt it to our needs

Replicate curl command to access Smartsheet in Rails

I am trying to access Smartsheet through API 2.0 in a Ruby-on-Rails app. I can get he following curl command to work
curl --request GET https://api.smartsheet.om/2.0/sheets -H "Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxx"
All attempts to replicate in Ruby code have failed. Can anyone help convert to Ruby?
Thanks!
You have a handful of options to accomplish that. If you want to keep close to curl as you have proposed, you could capture the response of the curl command wraping it with backticks
response = `curl --request GET https://api.smartsheet.om/2.0/sheets -H "Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxx"`
I'd recommend, however, use something like CURB, which provides Ruby binding for libcurl. It would add some syntax sugar, so your request would look like
response = Curl.get("https://api.smartsheet.om/2.0/sheets") do |http|
http.headers['Authorization'] = 'Bearer xxxxxxxxxxxxxxxxxxxxxxxxx'
end
Yet another option would be ditching curl altogether and use a gem like HTTParty. It makes use of Ruby's net/http to make requests.
That would be something along these lines:
response = HTTParty.get("https://api.smartsheet.om/2.0/sheets",
headers: 'Authorization' => 'Bearer xxxxxxxxxxxxxxxxxxxxxxxxx')

Curl -d to Alamofire

Following this page (https://django-oauth-toolkit.readthedocs.org/en/latest/rest-framework/getting_started.html), I was able to setup OAuth for my django project.
The following curl command gives me a token to access resource.
curl -X POST
-d "grant_type=password&username=<user_name>&password=<password>"
-u"<client_id>:<client_secret>" http://localhost:8000/o/token/
However, when I send request using Alamofire, things are a bit strange. This is my code
Alamofire.request(.POST, url, parameters: parameters, encoding: .JSON)
.authenticate(user: client_ID, password: client_Secret)
where parameter is a dictionary
[
"password": <password>,
"grant_type": password,
"username": <username>
]
Using curl command, I can see from Django that request.POST.items() returns the list of parameters. However, using Alamofire, there is nothing. The parameters appeared in request.body instead!
This problem is driving me crazy. Any help will be grateful!
Thanks in advance.
Well, your curl command is posting as Content-Type: application/x-www-form-urlencoded format, whereas you are forcing to post as json (.JSON). For this reason the request has passed as application/json to your django and you are seeing the parameter in body instead of POST.items().
So remove this from your code encoding: .JSON.

Instagram API - cryptic response; not sure if working and unable to test omniauth with this

I am working on a Rails app that has as the requirement logging in with omniuth to Instagram. This would be my first time using Instagram's OAuth endpoint and it is unclear whether it is working (and not clear to project manager either).
I'm using their cURL implementation with the following (will reset it in future) but getting "No matching code found" error which would seem to be the logical first step.
curl \-F 'client_id=4658fa17d45244c88dd13c73949a57d7' \
-F 'client_secret=ae6cfe5d13544eada4dece2ec40ac5dc' \
-F 'grant_type=authorization_code' \
-F 'redirect_uri= http://seek-style.herokuapp.com/arc/services/instagram' \
-F 'code=CODE' \https://api.instagram.com/oauth/access_token
with response
{"code": 400, "error_type": "OAuthException", "error_message": "No matching code found."}
Is there something that I am doing obviously wrong? Is there a finished example of how to get this done? I have seen https://github.com/ropiku/omniauth-instagram but can't tell if still working. Spec's pass but the actual call is mocked.
Edit #1
Per comments, I have added a link to repo https://github.com/trestles/seek that is being used to deploy to Heroku. There's basically nothing in the app and the above cURL to the best of my knowledge should be working (and isn't) so I haven't really even tested this. Perhaps I'm misunderstanding even how Instagram's API is working.
So, I have done a little research on Instagram API.
All the required info is located here: http://instagram.com/developer/authentication/
First of all, you need to get one-time CODE from Instagram. For your app it is pretty easy.
Just set href for your 'auth to instagram' link to:
"https://api.instagram.com/oauth/authorize/?client_id=4658fa17d45244c88dd13c73949a57d7&redirect_uri=http://seek-style.herokuapp.com/arc/services/instagram&response_type=code"
You will receive a redirect from API with CODE as a parameter.
You can handle it in services_controller#instagram or simply extract from application logs.
There should be something like
Processing by ServicesController#instagram as HTML
Parameters: {"code"=>"c25dcdcb96ed4eb9a508fede0cb94e87", "state"=>"e3d6dc22d6cd3cdebf6fb9e51a728a120a6d901cc382c4bf"}
Then you should request an ACCESS_TOKEN from the API
using cURL:
curl \-F 'client_id=YOUR_CLIENT_ID' \
-F 'client_secret=YOUR_CLIENT_SECRET' \
-F 'grant_type=authorization_code' \
-F 'redirect_uri= http://seek-style.herokuapp.com/arc/services/instagram' \
-F 'code=CODE_FROM_ABOVE' \https://api.instagram.com/oauth/access_token
Or using RestClient in services_controller#instagram :
resp = RestClient.post 'https://api.instagram.com/oauth/access_token', {
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
grant_type: 'authorization_code',
redirect_uri: 'http://seek-style.herokuapp.com/arc/services/instagram',
code: params[:code]
}
The cURL response or resp.body in controller should contain something like:
{
"access_token":"1515660384.9f652d3.fcb1e712d41347069ad5c65ccfada994",
"user":{
"username":"petro.softserve",
"bio":"",
"website":"",
"profile_picture":"http:\/\/images.ak.instagram.com\/profiles\/anonymousUser.jpg",
"full_name":"",
"id":"1515660384"
}
}

Strange Rails behavior with custom mime types

I am using Ruby on Rails 4.1 and I am trying to implement an API with a custom mime type. That is, in config/initializers/mime_types.rb I register an alias as like the following:
Mime::Type.register_alias 'application/json', :my_json
From another system I am trying to access the API with curl by running a HTTP PUT request, this way:
curl http://www.my_api.org/articles.my_json --request PUT --header "Content-Type: application/json" --data-binary '{\"key\": {\"a\": \"1\", \"b\": \"2\"}}'
However, by inspecting the ArticlesController parameters in my Rails application, I get the following output (note: article parameters are "unwanted" and those duplicate the "wanted" key parameters):
Parameters: {"key": { "a"=>"1", "b"=>"2" }, "article": { "a"=>"1", "b"=>"2" }}
What is the problem? Is it a bug? How can I solve that?
Note: I have implemented and access other similar API by executing HTTP GET requests and all works as expected. The problem seems to happens only when I execute HTTP PUT requests.
#rafaelfranca - No it is not a bug. It is how wrap_parameters works. You can disable at this file in your application config/initializers/wrap_parameters.rb.
See github.

Resources