How to pass OAuth token using google-api-ruby-client People API? - ruby-on-rails

We are migrating a large enterprise application from the Google Contacts API to the People API.
Before, using the OAuth token to make requests to the Contacts API was easy. We would authenticate with OAuth, and then pass the token to the Google Contacts API like so:
# access_token is the token we receive from OAuth
#user = GoogleContactsApi::User.new(access_token)
# make a request
contact_objects = user.contacts
The PeopleService code shows how to use an API key, and then only makes mention of the OAuth token:
# API key. Your API key identifies your project and provides you with API access,
# quota, and reports. Required unless you provide an OAuth 2.0 token
But I've been unable to find an example of how to use the OAuth token to make requests to the People API using the Ruby gem.
Could you please provide a simple example of how to make a People API request using the OAuth token? Specifically, we want access to a user's contacts' email address and phone numbers. I believe we will be using get_people. If you could provide this specific example, that would be wonderful.
Thank you! 😄

It looks like we needed to access access_token.token and set it like so:
require 'google/apis/people_v1'
class GooglePeopleApiWrapper
attr_reader :service, :access_token
def initialize(oauth_object)
# outh_object is the `access_token` from my question, which is
# provided in the OAuth response
#oauth_object = oauth_object
#service = Google::Apis::PeopleV1::PeopleServiceService.new
#service.authorization = #oauth_object.token
end
def fetch_contacts
# Fetch the next 10 events for the user
contact_objects = #service.list_person_connections(
'people/me',
page_size: 10,
person_fields: 'names,emailAddresses,phoneNumbers',
)
etc...
end
end

Related

Where I can take correct API token for requests to Trello behalf on user (ruby-trello)

I am using Ruby on Rails 5.2 and gems: ruby-trello, devise, omniauth-trello.
I want to make authorized requests on behalf of Trello user same as shows here: https://github.com/jeremytregunna/ruby-trello#multiple-users
Example from git docs:
#client_bob = Trello::Client.new(
:consumer_key => YOUR_CONSUMER_KEY,
:consumer_secret => YOUR_CONSUMER_SECRET,
:oauth_token => "Bob's access token",
:oauth_token_secret => "Bob's access secret"
)
My steps:
User (Bob) sign in with Trello and get his own oauth_secret and oauth_token
App creates a Trello::Client for Bob using:
his own oauth data (:oauth_token, :oauth_token_secret)
I got consumer_key from here: https://trello.com/app-key (in the top of page, first block with key field)
consumer_secret was taken from https://trello.com/app-key too, but from the bottom of page, last block with key secret
After this, I'm trying to get any data from Bob's trello account (boards, lists, tasks etc.) but always getting 500 error (invalid token).
Could you explain what I'm doing wrong?
Thank you in advance.
What I did was implementing a session controller to request and authorize access to user's trello and then call Trello::Client with the authorization params inside the callback method on the controller.
Check out this:Trello OAuth 1.0 authorization with Ruby
Then inside the authorization method you can call Trello::Client using :oauth_token and :oauth_token_secret from get_access_token call or store them both on the session object and use them anywhere.

How to hit Office 365 API from Ruby?

I am attempting to access the Office 365 API from a Ruby on Rails backend and am having problems.
Whether I use the ruby_outlook gem (github) or follow Microsoft's official Ruby on Rails sample, I am getting 401 unauthorized.
My access_token is being saved using Omniauth and is valid, I checked by pasting it in here.
Am I using the correct access_token? It is over 1400 characters long (1442 to be exact). Can anyone show me an example of how to properly call the Office 365 Mail API from Ruby?
Code Example (using Faraday):
key = #auth[:key]
conn = Faraday.new(:url => 'https://outlook.office.com') do |faraday|
# Outputs to the console
faraday.response :logger
# Uses the default Net::HTTP adapter
faraday.adapter Faraday.default_adapter
end
response = conn.get do |request|
request.url '/api/v2.0/me/contacts'
request.headers['Authorization'] = "Bearer #{key}"
request.headers['Accept'] = 'application/json'
end
Code Example (using ruby_outlook gem):
client = RubyOutlook::Client.new
key = #auth[:key]
page = 1
view_size = 30
fields = [
'DisplayName',
'EmailAddresses'
]
sort = {:sort_field => 'DisplayName', :sort_order => 'ASC'}
contacts = client.get_contacts key, view_size, page, fields, sort
The exact error that the ruby_outlook gem returns is:
{"ruby_outlook_error"=>401}
The problem is a mismatch between the scopes in your token and the API endpoint you're using. The scope has to match the endpoint.
In your case, you requested a Graph API scope, but you're calling the Outlook API endpoint.
You should only have to register in one place for your client ID and secret: https://apps.dev.microsoft.com. It sounds like you may have also registered an app in the Azure Management Portal (which requires you to specify scopes in the registration itself).
Make sure you're using a client ID from apps.dev.microsoft.com and make sure your scopes are requested as 'https://outlook.office.com' scopes, and you should be good to go.
That Omniauth strategy might require that you register in the Azure Management Portal if they are dependent on Azure's v1 auth endpoints. In that case, forget what I said about apps.dev.microsoft.com and instead change your app registration to use the appropriate permissions from Microsoft Exchange Online.
UPDATE: Based on your comments, that Omniauth strategy DOES require the v1 Azure auth/token endpoints, so you have 2 options if you want to keep using that strategy:
Change your code to use the Graph endpoints. You'll need to use the Faraday option above (ruby_outlook is designed for the Outlook endpoints), and change your URL to https://graph.microsoft.com, and the request.url to /v1.0/me/contacts.
Create a new app registration at https://dev.outlook.com/appregistration, which will create the proper scopes for your code. You'll need an Office 365 account to login to the app registration tool.

Rails API: Authenticate users from native mobile apps using username/password or facebook token

So I have been pulling my hair out for a few days now trying to figure out how to add username/password authentication to my rails mobile API.
Here is a brief overview of my current authentication flow:
User selects "login with Facebook" on the mobile client, client
redirects to Facebook app and requests access_token
On success, Facebook responds with the access token and the client
redirects back to my app.
The client sends the access token to my API
My API uses the koala gem to check if the access token is valid.
If the token is valid, Facebook sends the users data to the API
where a new user is created. If the user already exists, my API sends down the users data.
My API handles the access token in step 4 as shown below:
def self.authenticate_user_from_facebook(fb_access_token)
user = User.new
graph = Koala::Facebook::API.new(fb_access_token)
profile = graph.get_object('me')
#user['fb_id'] = profile['id']
#user['fb_token'] = fb_access_token
# Generate user hash
uhash = Hash.new
uhash['provider'] = 'facebook'
uhash['uid'] = profile['id']
uhash['info'] = Hash.new
uhash['info']['nickname'] = profile['username']
uhash['info']['name'] = profile['name']
uhash['info']['email'] = profile['email']
uhash['info']['first_name'] = profile['first_name']
uhash['info']['last_name'] = profile['last_name']
uhash['info']['verified'] = profile['verified']
uhash['info']['urls'] = Hash.new
uhash['info']['urls']['Facebook'] = profile['link']
uhash['credentials'] = Hash.new
uhash['credentials']['token'] = fb_access_token
uhash['extra'] = Hash.new
uhash['extra']['raw_info'] = Hash.new
#Save the new data
user = User.apply_auth(uhash)
return user
end
def self.apply_auth(uhash)
User.where(:uid => uhash['uid'], :provider => uhash['provider']).first_or_create do |user|
user.provider = uhash['provider']
user.uid = uhash['uid']
user.nickname = uhash['info']['nickname']
user.email = uhash['info']['email']
user.name = uhash['info']['name']
user.first_name = uhash['info']['first_name']
user.last_name = uhash['info']['last_name']
end
end
Once the user is created, they can make requests to my API using their access token as shown below:
In step 2 the API is using koala to verify the users access token. This is done by applying the following before_filter to all controllers.
before_filter :current_user
and in my application_helper.rb
def current_user
#current_user ||= User.authenticate_user_from_facebook(params[:access_token])
end
Every time a user makes a request to my API the koala gem is used to check if the token is valid, then the request is processed.
What I am trying to add now is authentication with only username and password.
Things I have looked into
I have been constantly referring to Railscast 235, 209, 250, 82 and reading up on OAuth2. I have a basic understanding of how authentication works but Im having trouble applying it to my current authentication flow.
Devise Token Authentication
Referring to Railscast 235, 209, and this blog post:
http://matteomelani.wordpress.com/2011/10/17/authentication-for-mobile-devices/
I can understand how to login and validate a user who logs in with a username and password. However I am confused as to how that will mesh with my Facebook login flow. I do not understand how to create a session with devise for a user who already has an access token generated by Facebook.
OAuth2
Making my API an OAuth2 provider seems like it would be a good way to go, but it seems kind of silly to redirect to a browser, and I don't know if its possible to redirect back from the browser to my app.
Authentication From Scratch
This is the option I am thinking of going with but I would be reinventing the wheel.
Thanks for reading this long post! Any advice is appreciated!
You may want to look into Warden. Warden makes it easy to setup and use different auth strategies whether you use tokens, password or Facebook. It is Rack-based so it also works outside of Rails which is nice if you ever want to use something like Grape for the API.
Here is the RailsCast on Warden. (Pro subscription required)

Rails 3 Linkedin API gem

I'm trying to set up the linkedin api in a rails 3 app using the linkedin gem. I don't want the user to have to authenticate my app in order for the API to get their info. I only need one piece of their public profile (the headline). So, maybe I should just be using xml or json to pull this off (not exactly sure how to get that with linkedin either).
I have the following in a helper so that I can call linkedin_header() in a loop of users. I only have 'client' as the last line of the following code while debugging. It outputs as expected (#). It seems like I am only a step away from success. How can I access a given users headline? I have tried using "client = client.profile(:url => 'linkedin_user_url')", but that return "Call must be made on behalf of a member".
def linkedin_header(account_user)
user = User.find(account_user)
account = Account.where(:user_id => user, :external_id => 1)
api_key = 'aaaaaaaa'
api_secret = 'bbbbbbbb'
client = LinkedIn::Client.new(api_key, api_secret)
rtoken = client.request_token.token # this returns correctly
rsecret = client.request_token.secret # this returns correctly
client
# client = client.profile(:url => 'linkedin_user_url')
end
So, I guess I have two questions. Is my request (public headline of any user) too simple for the above...should I be using XML or JSON. And, if Im close...can I make the API work for me without the user having to authenticate via linkedin.
Based off of what I read from the LinkedIn API reference (http://developer.linkedin.com/documents/authentication)
You have to make requests to their API only after being authenticated. (Using OAuth Keys) Rather than just grabbing the publicly available information.
It seems like since you want a small piece of information (the public headline of any user) you'd want some sort of implementation like Facebook's OpenGraph. After looking around on LinkedIn, I don't see any sort of public implementation like that.
I would suggest checking out this gem:
https://github.com/yatishmehta27/linkedin-scraper
It seems to be the type of solution you're looking for.

Using user's token to make requests to Twitter API in Rails

I'm using Omniauth to get credentials from Twitter for a specific User. Part of the OmniAuth object that I get is like this:
credentials=#
<Hashie::Mash secret="XXXX" token="XXXX">
extra=#<Hashie::Mash access_token=#<OAuth::AccessToken:xxxx #token="xxxx", #secret="xxxxx", ..
Right now I'm storing the credentials[token] and the UID for that specific User. At some point I want to fetch the Twitter API using the auth for that specific User to avoid getting the 150 max requests for a specific IP. Right now I'm just doing this:
twitter_user_name = Twitter.user(user_id).screen_name
So, how can I do to make those requests using the Twitter gem using the auth provided by OmniAuth instead of doing requests from my own IP (unauthenticated calls and therefore limited)
After playing with the gem, I've figured how to do it:
You want to create a new API object for a specific User, so you want to do this:
client = Twitter::Client.new(:oauth_token => 'XXXXX', :oauth_token_secret => 'XXXX')
And use this client to do the requests.

Resources