Access Google Contacts API on Ruby - ruby-on-rails

I'm struggling to access the Google Contacts API.
First I tried the google-api-ruby-client gem but it turned out that it does not support the Contacts API.
Next shot was the google_contacts_api gem but I struggle to get a oauth_access_token_for_user with the oAuth2 gem. When following the oAuth2 instructions I don't know what to put in authorization_code_value and Basic some_password.
I tried the following:
require 'oauth2'
client = OAuth2::Client.new(ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'], :site => 'http://localhost:9292')
=> #<OAuth2::Client:0x007fcf88938758 #id="blabla.apps.googleusercontent.com", #secret="blabla", #site="http://localhost:9292", #options={:authorize_url=>"/oauth/authorize", :token_url=>"/oauth/token", :token_method=>:post, :connection_opts=>{}, :connection_build=>nil, :max_redirects=>5, :raise_errors=>true}>
client.auth_code.authorize_url(:redirect_uri => 'http://localhost:9292')
=> "http://localhost:9292/oauth/authorize?client_id=blabla.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A9292&response_type=code"
token = client.auth_code.get_token('authorization_code_value', :redirect_uri => 'http://localhost:9292', :headers => {'Authorization' => 'Basic some_password'})
=> Faraday::ConnectionFailed: Connection refused - connect(2) for "localhost" port 9292
I would appreciate if someone could give me detailed step by step instructions how to access the API.

Make sure your app is set up properly and that you've enabled the Contacts API in the Google Developers Console. Then try this:
CLIENT_ID = '?????.apps.googleusercontent.com'
CLIENT_SECRET = 'your_secret'
REDIRECT_URI = 'your_redirect_uri'
client = OAuth2::Client.new(CLIENT_ID, CLIENT_SECRET,
site: 'https://accounts.google.com',
token_url: '/o/oauth2/token',
authorize_url: '/o/oauth2/auth')
url = client.auth_code.authorize_url(scope: "https://www.google.com/m8/feeds",
redirect_uri: REDIRECT_URI)
Visit url in your browser and log in to Google. The url you are redirected to afterwards will contain the token in the parameter code. It will look like this (this next line is not code you run):
actual_redirect_url = "#{REDIRECT_URI}?code=#{code}"
Parse the code from the redirect url, then
token = client.auth_code.get_token(code, :redirect_uri => REDIRECT_URI)
Edit
Someone asked in the comments how to pass the token to the google_contacts_api library. (I wrote the library, so I should know!)
token is an OAuth2::AccessToken object in this example. All you have to do is pass it to the constructor:
user = GoogleContactsApi::User.new(token)
To be extra clear, the constructor accepts the token object, not a string.

It looks like you're authenticating against localhost (should only be referring to localhost in the context of redirecting after authentication). You should be authenticating against Google's OAuth server somewhere in there.
See: https://github.com/google/google-api-ruby-client/blob/master/lib/google/api_client.rb#L165

Related

Trouble Establishing Ouath2 Connection to Microsoft Dynamics via Rails Oauth2 gem

I am new to authentication using Oauth2, and was hoping someone could provide some guidance on how to use the oauth2 gem to correctly perform authentication so as to get a token with Microsoft Dynamics.
I have been able to authorize and get a token with Postman, but as these types of applications greatly facilitate the overall process, it can be difficult to map these things to code, especially when the concepts are new.
For the access token, I have at my disposal:
The Auth URL, which is of the form "https://login.windows.net/<CUSTOMER_IDENTIFIER_HASH>/authorize?resource=https://api.businesscentral.dynamics.com
The Access Token URL, which is of the form "https://login.windows.net/<CUSTOMER_IDENTIFIER_HASH>/oauth2/token?resource=https://api.businesscentral.dynamics.com"
The client_id
The client_secret
I've tried the various examples online, but I either get a nondescript error from oauth2 such as:
OAuth2::Error ():
Or, in other cases, something more particular:
OAuth2::Error ({"code"=>"RequestDataInvalid", "message"=>"Request data is invalid."}:
{"error": {"code": "RequestDataInvalid","message": "Request data is invalid."}}):
Does anyone have any real, working examples on how to successfully obtain a token?
Finaly cracked it.
Had to respecitvely move the resource element out of the auth and the access token urls to:
https://login.windows.net/<CUSTOMER_IDENTIFIER_HASH>/authorize
https://login.windows.net/<CUSTOMER_IDENTIFIER_HASH>/oauth2/token
At that point, i set the client as:
client = OAuth2::Client.new(
client_id,
client_secret,
site: base_url,
grant_type: "client_credentials",
resource: "https://api.businesscentral.dynamics.com",
authorize_url: auth_url,
token_url: token_url,
)
Above, the base_url is:
https://api.businesscentral.dynamics.com/v2.0/<CUSTOMER_IDENTIFIER_HASH>
Then, i call the client to get an auth_code and had to explicitly pass the resource parameter:
client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth2/callback', resource: "https://api.businesscentral.dynamics.com")
I'm not sure if the resource is necessary when getting the token, but finally, I obtain it as follows:
token = client.password.get_token(<AUTHENTICATION_LOGIN>, <AUTHENTICATION_PASS>, resource: "https://api.businesscentral.dynamics.com")
then i can use the token to perform get commands:
token.get('https://api.businesscentral.dynamics.com/v2.0/Sandbox/api/v2.0/companies(<COMPANY_ID_HASH>)/customers', :headers => { 'Accept' => 'application/json' })
I have a feeling I have to do some cleanup on the url for the final get command, but it seems to work this way.

Authentication using Resource Owner Password Credentials in Rails

I am considerably new to OAuth authentication scheme. What pose a problem for me at the moment is getting access_token from server in Rails app.
So far I read few articles covering methods related to Resource Owner Password Credentials in OAuth 2.0, but still it got me nowhere.
To name a few Official documentation regarding ROPC / Introduction to OAuth2 / Description of OAuth2 gem from Intridea
Server that I want to connect with allows password grant. It's deployed by 3rd party, so I assume everything is ok with it. On manual page they defined example of authorization as follows:
curl -X POST -d
'grant_type=password&username=USER_EMAIL&password=YOUR_PASSWORD&client_id=CLIENT_ID&client_secret=CLIENT_SECRET'
'https://auth.example.com/oauth2/token'
I posses all data which is mentioned above. BTW, client_id and client_secret are generic values enclosed in documentation. Server uses Doorkeeper gem to implement OAuth2.
To retrieve access_token from server, I simply put advised by Doorkeeper's wiki code into one of my controllers. Testing ROPC for Doorkeeper
My code in Rails API app utilizing OAuth2 gem from Intridea:
def test
client = OAuth2::Client.new(CLIENT_ID, CLIENT_SECRET,
site: 'https://auth.example.com/oauth2/token')
access_token = client.password.get_token(username, password)
Rails.logger.info access_token.token
end
What I get after visiting localhost/test is Completed 500 Internal Server Error with OAuth2::Error saying that page that I look for doesn't exist.
When trying just use curl from command line with respective data, I recieve:
WWW-Authenticate: Bearer realm="Doorkeeper", error="invalid_grant", error_description="The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."
Please kindly advise what may cause problem in these set-up.
As it seems I overlooked one important thing, we should declare explicitly token_url in relation to site address and not treat site parameter as entire path.
So in order to request access_token my method should look like this:
def test
client = OAuth2::Client.new(client_id,
client_secret,
token_url: "/oauth2/token",
site: "https://www.example.com/" )
access_token = client.password.get_token(username, password)
Rails.logger.info access_token.token
end
Here you can find similar issue to mine.
If someone wants to get access token with password credentials using simple http method, here is example how to approach this thing:
def test
param = {
:client_id => client_id,
:client_secret => client_secret,
:grant_type => 'password',
:username => username,
:password => password
}
uri = URI.parse(service_url)
http = Net::HTTP.new(uri.host, uri.port)
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri)
request.body = param.to_query
response = http.request(request)
Rails.logger.info response.body()
end

OAuth call for a request token yields a 404 error

I am having an incredibly difficult time getting the OAuth gem working correctly for the Flickr API. I'm trying to generate a request token using this code:
user_oauth = OAuth::Consumer.new(consumer_key, consumer_secret, :site => "https://secure.flickr.com/services")
request_token = user_oauth.get_request_token(:oauth_callback => callback_url)
Whenever I run this code it throws an exception "OAuth::Unauthorized (404 Not Found)" on the call to .get_request_token.
I got my end point from: http://www.flickr.com/services/api/misc.overview.html
My OAuth gem is using the default request_token path, which should work with Flickr according to: http://www.flickr.com/services/api/auth.oauth.html#request_token I also tried using the endpoint that this link uses (http://www.flickr.com/services)
When I call .request_token_url on my OAuth::Consumer object, it returns "https://secure.flickr.com/services/oauth/request_token", which I can access in my browser. Thinking that the flickr API might only work with GET requests, I changed the OAuth method to GET and it still didn't work.
I've used this exact same code on different APIs before and it worked, so I'm not really sure what to do at this point. Any help would be appreciated!
I had the same problem. Request_token_url method returns right url, but I watch on true requested url by wireshark and there was www.flickr.com/oauth/request_token.. So it needs to move /services path from :site option into paths options.
This code works for me, now:
consumer = OAuth::Consumer.new(key, secret,
:site => "http://www.flickr.com",
:request_token_path => '/services/oauth/request_token',
:authorize_path => '/services/oauth/authorize',
:access_token_path => '/services/oauth/access_token')
request_token = consumer.get_request_token
I was having the same issue, but my callback url was "oob" which they say to use if you don't have access to a browser. Anyway I took the quotes off the oob and it works now.

Getting a 401 oauth_signature error when trying to get an request token from Evernote using OAuth

I am trying to get an Evernote request token using the OAuth gem with Ruby on Rails:
customer = OAuth::Consumer.new("consumer_key_here", "consumer_secret_here",{ :site=>"http://sandbox.evernote.com/",:request_token_path => "/oauth",:oauth_signature_method => "PLAINTEXT" })
#request_token = customer.get_request_token
But I'm getting this error
OAuth::Unauthorized in PagesController#home
401 oauth_signature
What could be causing this?
Change site url to use https - I had the same issue.
Evernote's sample code now contains a Ruby OAuth example that uses the OAuth gem. You can download the sample code from http://www.evernote.com/about/developer/api/.
In this case, you need to pass the oauth_callback parameter when getting a request token, because the Evernote OAuth provider implements OAuth 1.0a.
consumer = OAuth::Consumer.new(consumerKey, consumerSecret, {
:site => "https://sandbox.evernote.com/",
:request_token_path => "/oauth",
:access_token_path => "/oauth",
:authorize_path => "/OAuth.action"})
requestToken = consumer.get_request_token(
:oauth_callback => "http://www.me.com/callback")
Also, there's no need to set the signature method to PLAINTEXT; Evernote's provider supports HMAC-SHA1, which is what the OAuth gem uses by default.
You need to put your OAuth consumer key and consumer secret in the new method where it currently says "consumer_key_here" and "consumer_secret_here".
If you do have values there for your real code, check and make sure they are correct-- it sounds silly, but I had this same problem yesterday with OAuth and it turns out I was using the wrong variables.

Rails app using Oauth to post to Twitter, getting "not authorized" when running in production server. OK in localhost

I'm trying to use Twitter's Oauth Single Token for posting from a rails app to my twitter feed (single user use-case is perfect for my app). This Is what I'm talking about.
Here's the relevant part of my code:
twitter_consumer_key = 'AAAAAA...'
twitter_consumer_secret = 'BBBBBB///'
oauth_token = 'CCCCC....'
oauth_token_secret = 'DDD.....'
consumer = OAuth::Consumer.new(twitter_consumer_key, twitter_consumer_secret, :site => "http://api.twitter.com", :scheme => :header)
access_token = OAuth::AccessToken.from_hash(consumer, :oauth_token => oauth_token, :oauth_token_secret => oauth_token_secret)
response = access_token.post("http://api.twitter.com/1/statuses/update.json", {:status => "Coffee's ready at 191 Peachtree!! "+Time.now.to_i.to_s})
logger.info response.inspect
When I run this in my local machine, everything goes well and the post is created on my feed. When I run it on my production server (centos5.5, Apache 2, Passenger, Rails 3.0.4) I get "HTTPUnauthorized".
Any ideas on how to troubleshoot this?
Thanks in advance.
Try with filling Callback URL in settings of your application on dev.twitter.com.
Should be something like that:
Callback URL http://yousite.com/auth/twitter/callback
Per abraham's comment, I'm adding the solution as an answer instead of a comment:
My server's timezone was incorrectly set so I was getting the following error in the response body:
{"request":"\/1\/statuses\/update.json","error":"Timestamp out of bounds"}
I set the time and timezone correctly and now it's working fine.
:)

Resources