I have small application, and I will have some external applications put data to this service over http with rest. I already have it working but without authentication. In portal I use devise, and my question is: how to (example desired) authenticate to portal from ruby script level? What to add to following script to authenticate first? I want to protect this controller with devise and then I need authentication part to following script.
require "net/http"
require "json"
#host = "localhost"
#port = 3000
#post_ws = "/external/rd"
#req_body = {
"device" => {
"name" => "device_json",
"operating_system_id" => "7",
"hash_string" => "jfsg3k4ovj0j02jv",
"user_id" => "1"
}
}.to_json
req = Net::HTTP::Post.new(#post_ws, initheader = {'Content-Type' =>'application/json'})
req.body = #req_body
response = Net::HTTP.new(#host, #port).start {|http| http.request(req) }
Regards,
Mateusz
Here is solution:
I used token_authenticatable from devise.
Here is one great answer how to implement it with json. I had some trouble and described them in this question. There is also answer.
Here goes example code:
require "net/http"
require "json"
#host = "localhost"
#port = 3000
#post_sign = "/users/sign_in.json"
#post_ws = "/external/rd"
#req_sign = {
"user" => {
"email" => "some#email.com",
"password" => "123456"
}
}.to_json
sig = Net::HTTP::Post.new(#post_sign, initheader = {'Content-Type' => 'application/json'})
sig.body = #req_sign
http = Net::HTTP.new(#host, #port).start
resp1 = http.request(sig)
puts "Response: #{resp1.code} , Message: #{resp1.message} , Body: #{resp1.body}"
if resp1.code == "200" then
puts "logged in"
json_resp = JSON.parse(resp1.body)
#auth_token = json_resp['auth_token']
#req_body = {
"device" => {
"name" => "device_json",
"operating_system_id" => "7",
"hash_string" => "jfsg3k4ovj0j02jv"
},
"auth_token" => #auth_token
}.to_json
req = Net::HTTP::Post.new(#post_ws, initheader = {'Content-Type' =>'application/json'})
req.body = #req_body
response = http.request(req)
puts "Response: #{response.code} , Message: #{response.message} , Body: #{response.body}"
end
Regards,
Mateusz
Related
I have configured Google api's with my Ruby on Rails project. Also, I have set webhooks for incoming emails.
I have successfully implemented login via Google and get user's inbox messages.
Now, I'm implementing a message reply, but I'm getting "BadRequest" in response.
My code.
uri = URI.parse("https://www.googleapis.com/gmail/v1/users/me/messages/send?access_token=#{access_token}")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json"
request.body = JSON.dump({
"References" => "\u003cCAAY2B8p2CjEjDKz+sXVBQBrda5i5Lz=Dd4fVC21kfx8fhLLCdg#mail.gmail.com\u003e" ,
"In-Reply-To" => "\u003cCAAY2B8p2CjEjDKz+sXVBQBrda5i5Lz=Dd4fVC21kfx8fhLLCdg#mail.gmail.com\u003e" ,
"Subject" => "Re: Test02" ,
"From" => "email#gmail.com" ,
"To" => "email#gmail.com" ,
"threadId"=> "1764cc4c5efa6855",
# "body" => "This is where the response text will go"
})
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
API call response.
response => #<Net::HTTPBadRequest 400 Bad Request readbody=true>
I need to send a reply using google API.
Thanks in advance.
In order to reply to a message using Google API, I have used this method.
client_secrets = Google::APIClient::ClientSecrets.load("#{Rails.root}/config/client_secrets.json")
auth_client = client_secrets.to_authorization
auth_client.update!(
:scope => 'https://mail.google.com/ https://www.googleapis.com/auth/gmail.modify https://www.googleapis.com/auth/gmail.readonly https://www.googleapis.com/auth/pubsub',
:redirect_uri => 'http://localhost:3000/google_code',
:additional_parameters => {
"access_type" => "offline", # offline access
"include_granted_scopes" => "true" # incremental auth
}
)
auth_client.code = auth_code
gmail = Google::Apis::GmailV1::GmailService.new
gmail.authorization = auth_client
message = Mail.new
message.date = Time.now
message.subject = "Re: Test02"
message.from = "email#gmail.com"
message.to = "email#gmail.com"
message.message_id = "\u003cCAFVVPDvD-zK6Akj8djj+uam35ZxFTf2EW4AefW1Ri7OV7AxFVA#mail.gmail.com\u003e"
message.part content_type: 'multipart/alternative' do |part|
part.html_part = Mail::Part.new(body: "Using service Account.", content_type: 'text/html; charset=UTF-8')
end
msg = message.encoded
message_object = Google::Apis::GmailV1::Message.new(raw:message.to_s, thread_id: "1764cc4c5efa6855", content_type: 'message/rfc822')
gmail.send_user_message('me', message_object)
For authorization on the site https://app.guardsaas.com me need:
Open https://app.guardsaas.com/login and get the value "_csrf_token"
Make a POST request https://app.guardsaas.com/login_check
with parameters:
'_username' = login
'_password' = pass
'_remember_me' = 'on'
'_csfr_token' = token from p.1
I wrote a script that first gets a token, and then it is authorized with the help of the site, but it does not work, the error can be covered in SSL, cookie, tried out a bunch of different options - nothing comes out
My code:
require "net/http"
require 'net/https'
require "uri"
uri = URI('https://app.guardsaas.com/login')
token = ""
text = ""
http = Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https',
:verify_mode => OpenSSL::SSL::VERIFY_NONE)
# make a request to get the server's cookies
response = http.get('https://app.guardsaas.com/login')
puts response.code
if (response.code == '200')
all_cookies = response.get_fields('set-cookie')
cookies_array = Array.new
all_cookies.each { | cookie |
cookies_array.push(cookie.split('; ')[0])
}
cookies = cookies_array.join('; ')
text = response.body.to_s
st = text.index('_csrf_token" value=').to_i
token = text[st+20..st+19+40]
puts "token: " + token
data = {
"_username" => 'login',
"_password" => 'pass',
"_remember_me" => 'on',
"_csrf_token" => token
}
data = URI.encode_www_form(data)
headers = {
'Cookie' => cookies,
'Referer' => 'https://app.guardsaas.com',
'Content-Type' => 'application/x-www-form-urlencoded'
}
headers = URI.encode_www_form(headers)
data = http.post('https://app.guardsaas.com/login_check', data, headers)
puts data.body
end
I'm trying to sent a post request that like so based on curl:
curl -XPOST -H content-type:application/json -d "{\"date\":\"2012-07-02\",\"aaaa\":\"bbbbb\", \"cccc\" : \"\[\"dddd\",\"eeee\",\"fffff\"\]\"}" URI -u USERNAME:PASSWORD
In Ruby:
#toSend = {
"date" => "2012-07-02",
"aaaa" => "bbbbb",
"cccc" => ["dddd","eeee","fffff"]
}.to_json
uri = URI.parse("https:/...")
https = Net::HTTP.new(uri.host,uri.port)
https.use_ssl = true
req = Net::HTTP::Post.new(uri.path, initheader = {'Content-Type' =>'application/json'})
req.body = "[ #{#toSend} ]"
req.basic_auth options[:username].to_s, options[:password].to_s
post = https.request(req)
For some reason the auth isn't getting attached what could be wrong with this?
I suspect your request to be run before you even add the auth parameters.
I would go this way:
require 'net/http'
require 'uri'
url = URI.parse('https://....')
req = Net::HTTP::Post.new(url.path)
req.basic_auth options[:username].to_s, options[:password].to_s
req.use_ssl = true
req.form_data({"date" => "2012-07-02", "aaaa" => "bbbbb", "cccc" => ["dddd","eeee","fffff"]})
resp = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }
All of my attempts of passing mimeType and trashed into the client for execution are either failing or returning all my docs regardless of mimeType and trash status.
require 'google/api_client'
require 'launchy'
load 'auth.rb'
def client
#client
end
def drive
#drive
end
def session
unless client
#client = Google::APIClient.new
#drive = client.discovered_api('drive', 'v2')
client.authorization.client_id = client_id
client.authorization.client_secret = secret
client.authorization.scope = 'https://www.googleapis.com/auth/drive'
client.authorization.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
uri = client.authorization.authorization_uri
Launchy.open(uri)
$stdout.write "Enter authorization code: "
client.authorization.code = gets.chomp
client.authorization.fetch_access_token!
end
client
end
#application/vnd.google-apps.spreadsheet
def list_files
session
files = []
#no matter how i go about trying to filter i always get all my docs...
params = "'mimeType' = 'application/vnd.google-apps.spreadsheet' and 'trashed' = false"
params = {'query' => {'mimeType' => 'application/vnd.google-apps.spreadsheet', 'trashed' => false}}
params = {'q' => {'mimeType' => 'application/vnd.google-apps.spreadsheet', 'trashed' => false}}
params = {'q' => "'mimeType' = 'application/vnd.google-apps.spreadsheet' and 'trashed' = false"}
params = {'mimeType' => 'application/vnd.google-apps.spreadsheet', 'trashed' => false}
begin
rsp = client.execute :api_method => drive.files.list, :parameters => params
#rsp = client.execute :api_method => drive.files.list, :q => params # have tried comin
files += rsp.data.items
puts "Token was #{params['pageToken']} but now #{rsp.next_page_token}"
params['pageToken'] = rsp.next_page_token unless rsp.next_page_token.nil?
end while !rsp.next_page_token.nil?
files
end
Also how can i use google drive results to get the spreadsheet key needed to use the spreadsheet api? The Files Resource returned from the query doesn't have any spreadsheet key information.
Could you try this?
params = {'q' => "trashed=false and mimeType='application/vnd.google-apps.spreadsheet'"}
Actually, if you send query with wrong syntax, it would return 400 Bad Request, not 200 Success with all files. It might be the case that you actually are not passing anything.
Is there a way to create an Anonymous (public or private) gist using net/http or net/https?
This worked for me.
require 'net/http'
require 'json'
uri = URI("https://api.github.com/gists")
payload = {
'description' => "My test gist",
'public' => true,
'files' => {
'test.txt' => {
'content' => "This is a test!\n\nI am making a public gist."
}
}
}
req = Net::HTTP::Post.new(uri.path)
req.body = payload.to_json
puts req.inspect
puts req.body.inspect
# GitHub API is strictly via HTTPS, so SSL is mandatory
res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => true) do |http|
http.request(req)
end
puts res.inspect
puts res.body.inspect
Result: My test gist
This gem will do the trick for you https://github.com/defunkt/gist!
For the record, it does require net/https.