Oauth2 token not working for gmail_xoauth gem - ruby

I'm currently getting a token via the omniauth-google-oauth2 gem per the following: https://github.com/zquestz/omniauth-google-oauth2
I store the token that comes back from the auth_hash.
I then try to use the token by calling:
require 'gmail_xoauth'
imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
imap.authenticate('XOAUTH2', 'myemail#gmail.com', Token.last)
Problem is that I get an error:
[8] pry(main)> imap.authenticate('XOAUTH2', 'myemail#gmail.com', Token.last)
Token Load (0.6ms) SELECT "tokens".* FROM "tokens" ORDER BY "tokens"."id" DESC LIMIT 1
Net::IMAP::NoResponseError: Invalid credentials (Failure)
from /Users/username/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/net/imap.rb:1171:in `get_tagged_response'

Ok I took a look at google-api-client and I started to use that a little more. Seems like the best solution at the moment is to do the following:
create an options hash that includes the gmail parameters and the gmail api_method
use the service you initialize with your access_token to create your query in the options hash
Below you can see a rough example that you can use
client = Google::APIClient.new
client.authorization.access_token = token
service = client.discovered_api 'gmail'
options = {parameters: {'userId' => 'email#gmail.com'}, api_method: service.users.messages.list}
client.execute(options)
I mean this is pretty clunky and should be DRY'd up. (Hopefully google creates a better gem around this)

The solution was to update the scope of omniauth for gmail.
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'],
{
scope: [
'https://mail.google.com/','https://www.googleapis.com/auth/userinfo.email'
]
}
end

Related

How to display linkedin profile information in Rails

I'm working on an app that will have a linkedin sign in button. Once the user signs in using their linkedin in username and password. I want to display their information on the home page.
Currently I'm using 'omniauth', 'omniauth-linkedin-oauth2' to authenticate the user.
The person working on this before me completed the authentication process but I can't understand how to display the users info. The authentication was implemented by following RailsCast #235 & #236 Omniauth Part 1 and 2.
This is the omniauth.rb file.
Rails.application.config.middleware.use OmniAuth::Builder do
provider :linkedin, 'LINKEDIN_KEY', 'LINKEDIN_SECRET', :scope => 'r_fullprofile r_emailaddress r_network', :fields => ['id', 'email-address', 'first-name', 'last-name']
end
I want to display all the fields from the omniauth.rb file.
I understand its a really silly issue but I'm really new to Ruby on Rails so I'd greatly appreciate it if someone can guide me through the process.
Based on the Authentications Controller in Part 2
You can get the fields from the omniauth hash:
omniauth = request.env["omniauth.auth"]
first_name = omniauth[:info][:first_name]
last_name = omniauth[:info][:last_name]
summary = omniauth[:extra][:raw_info][:summary]
headline = omniauth[:extra][:raw_info][:headline]
image = omniauth[:info][:image]
email = omniauth[:info][:email]
token = omniauth[:credentials][:token]
secret = omniauth[:credentials][:secret]
profile_url = omniauth[:info][:urls][:public_profile]
Those are the basic info you need from the authentication hash, if you need more data, you can use the following gem (using the user's token):
gem 'linkedin-oauth2', '~> 0.1.1'

How to make request by Octokit client

I'm using token to access github api by Octokit client.
client = Octokit::Client.new(access_token: TOKEN)
It seems that is ok:
client.rate_limit
=> #<struct Octokit::RateLimit
limit=5000,
remaining=4998,
resets_at=2013-11-25 03:38:41 +0200,
resets_in=3533>
So now I want to get some info
repo = client.repo 'rails/rails'
repo.rels[:events]
repo.rels[:events].get.data
But when I'm getting next page
repo.rels[:events].get[:next]
I'm hitting the rate limit in 60 requests per hour.
It seems that next requests are not authorized by token.
How to make all request be authorized by token?
Maybe your token has been expired or your client variable lost scope.
Create a initializers/octokit.rb with authentication:
Octokit.configure do |c|
c.client_id = ENV['GITHUB_ID']
c.client_secret = ENV['GITHUB_SECRET']
end
I chose to do by id and secret.
And make your requests with:
repo = Octokit.repo 'rails/rails'
After create the initializer, you can test in rails c:
> Octokit.rate_limit
=> #<struct Octokit::RateLimit limit=5000, remaining=4927, resets_at=2016-04-22 12:24:52 -0300, resets_in=2102>
Taken from the Octokit documentation:
Note: While Octokit auto pagination will set the page size to the
maximum 100, and seek to not overstep your rate limit, you probably
want to use a custom pattern for traversing large lists.

Fetch friends count using Odnoklassniki API in Ruby

looking for working solution to Fetch friends count using Odnoklassniki API in Ruby
tried to use lemur and school_friend gems without success
require 'school_friend'
SchoolFriend.application_id = '193320768'
SchoolFriend.application_key = 'CBALsdsASDBA'
SchoolFriend.secret_key = 'A3AA9342CR47DA4BC315'
SchoolFriend.api_server = 'http://api.odnoklassniki.ru'
puts SchoolFriend.users.is_app_user(:uid => '571931088692')
{"error_code"=>100, "error_data"=>nil, "error_msg"=>"PARAM : Missed required parameter: access_token"}
even i specify access_token as mentioned in docs like that:
session = SchoolFriend.session(:access_token => 'token_from_oauth2_client')
session.friends.get
{"error_code"=>100, "error_data"=>nil, "error_msg"=>"PARAM : Missed required parameter: access_token"}
i still get same error
Becouse odnoklassniki api requires access token
your request to this api should be like
http://api.odnoklassniki.ru/fb.do?method=friends.get&application_key=[APPLICATION_KEY]&sig=[SIG]&access_token=[ACCESS_TOKEN]
I'm use lemur and for me it works fine
i'm initialize it like
odnoklassniki = Lemur::API.new(APP_SECRET, Public_key, Access_token, APP_ID)
where APP_SECRET, Public_key and APP_ID you have after registration your app
Access_token you have after use sign in to odnoklassniki via omniauth
and then i can call api method like
odnoklassniki.get(method: 'friends.get')
this returns something like that
["55726542234", "32131394541", "532139395874", "94691213891"]

Generating Paypal Signature, 'X-PAYPAL-AUTHORIZATION' in Ruby

Is there any library in Ruby that generates the Signature, 'X-PAYPAL-AUTHORIZATION' header that is required to make calls on behalf of the account holder who has authorized us through the paypal Permissions API.
I am done with the permissions flow and get the required access token, tokenSecret. I feel I am generating the signature incorrectly as all my calls with the the generated 'X-PAYPAL-AUTHORIZATION' fail. They give the following errors:
For NVP call I get:
You do not have permissions to make this API call
And for the GetBasicPersonalData call I get:
Authentication failed. API credentials are incorrect.
Has anyone gone through this in Ruby? What is best way to generate signature. Paypal has just provided some SDK in Paypal, Java, but not the algorithm to generate signature.
Thanks,
Nilesh
Take a look at the PayPal Permissions gem.
https://github.com/moshbit/paypal_permissions
Specifically lib/paypal_permissions/x_pp_authorization.rb
require 'cgi'
require 'openssl'
require 'base64'
class Hash
def to_paypal_permissions_query
collect do |key, value|
"#{key}=#{value}"
end.sort * '&'
end
end
module ActiveMerchant #:nodoc:
module Billing #:nodoc:
module XPPAuthorization
public
def x_pp_authorization_header url, api_user_id, api_password, access_token, access_token_verifier
timestamp = Time.now.to_i.to_s
signature = x_pp_authorization_signature url, api_user_id, api_password, timestamp, access_token, access_token_verifier
{ 'X-PAYPAL-AUTHORIZATION' => "token=#{access_token},signature=#{signature},timestamp=#{timestamp}" }
end
public
def x_pp_authorization_signature url, api_user_id, api_password, timestamp, access_token, access_token_verifier
# no query params, but if there were, this is where they'd go
query_params = {}
key = [
paypal_encode(api_password),
paypal_encode(access_token_verifier),
].join("&")
params = query_params.dup.merge({
"oauth_consumer_key" => api_user_id,
"oauth_version" => "1.0",
"oauth_signature_method" => "HMAC-SHA1",
"oauth_token" => access_token,
"oauth_timestamp" => timestamp,
})
sorted_query_string = params.to_paypal_permissions_query
base = [
"POST",
paypal_encode(url),
paypal_encode(sorted_query_string)
].join("&")
base = base.gsub /%([0-9A-F])([0-9A-F])/ do
"%#{$1.downcase}#{$2.downcase}" # hack to match PayPal Java SDK bit for bit
end
digest = OpenSSL::HMAC.digest('sha1', key, base)
Base64.encode64(digest).chomp
end
# The PayPalURLEncoder java class percent encodes everything other than 'a-zA-Z0-9 _'.
# Then it converts ' ' to '+'.
# Ruby's CGI.encode takes care of the ' ' and '*' to satisfy PayPal
# (but beware, URI.encode percent encodes spaces, and does nothing with '*').
# Finally, CGI.encode does not encode '.-', which we need to do here.
def paypal_encode str
s = str.dup
CGI.escape(s).gsub('.', '%2E').gsub('-', '%2D')
end
end
end
end
Sample parameters:
url = 'https://svcs.sandbox.paypal.com/Permissions/GetBasicPersonalData'
api_user_id = 'caller_1234567890_biz_api1.yourdomain.com'
api_password = '1234567890'
access_token = 'YJGjMOmTUqVPlKOd1234567890-jdQV3eWCOLuCQOyDK1234567890'
access_token_verifier = 'PgUjnwsMhuuUuZlPU1234567890'
The X-PAYPAL-AUTHORIZATION header [is] generated with URL "https://svcs.paypal.com/Permissions/GetBasicPersonalData". (see page 23, and chapter 7, at the link)
NVP stating "You do not have permissions to make this API call" means your API credentials are correct, just that your account does not have permission for the particular API you are trying to call. Something between the two calls you are submitting is not using the same API credentials.
For NVP call I get:
What NVP call?
TransactionSearch (see comments below)
Also, if you haven't already done so, you will want to use the sandbox APP-ID for testing in the sandbox, and you will need to apply for an app-id with Developer Technical Services (DTS) at PayPal to get an App-ID for live.
EDIT:
To use the TransactionSearch API, all you should be submitting is below. You do not need to specify any extra headers.
USER=xxxxxxxxxxxxxxxxxx
PWD=xxxxxxxxxxxxxxxxxx
SIGNATURE=xxxxxxxxxxxxxxxxxx
METHOD=TransactionSearch
VERSION=86.0
STARTDATE=2009-10-11T00:00:00Z
TRANSACTIONID=1234567890
//And for submitting API calls on bob's behalf, if his PayPal email was bob#bob.com:
SUBJECT=bob#bob.com

Using Ruby + OAuth to access Yelp API

I just getting started with OAuth, and I tried to make a small client to connect to some webservices... I tried twitter and it worked like a charm, however, I also tried to access Yelp V2 API (following their Python example) but I always get back as an answers:
HTTP 400 Bad Request
Missing parameter: oauth_consumer_key
Here's my code:
require 'rubygems'
require 'oauth'
CONSUMER_KEY = "MY_CONSUMER_KEY"
SECRET = "MY_CONSUMER_SECRET"
TOKEN = "MY_TOKEN"
TOKEN_SECRET = "MY_TOKEN_SECRET"
consumer = OAuth::Consumer.new( CONSUMER_KEY,SECRET, {:site => "http://api.yelp.com", :signature_method => "HMAC-SHA1", :scheme => :header})
access_token = OAuth::AccessToken.new( consumer, TOKEN,TOKEN_SECRET)
p access_token.get("/v2/search?location=new+york").body
Regardless to say, that code works with twitter API without any problem (I actually followed twitter's example code)
Cheers and thanks in advance,
Ze
Use :query_string instead of :header and everything will work (at least for me).
Same code, using Signet:
require 'signet/oauth_1/client'
client = Signet::OAuth1::Client.new(
:consumer_key => 'MY_CONSUMER_KEY',
:consumer_secret => 'MY_CONSUMER_SECRET',
:access_token_key => 'MY_TOKEN_KEY',
:access_token_secret => 'MY_TOKEN_SECRET'
)
response = client.fetch_protected_resource(
:uri => 'http://api.yelp.com/v2/search?location=new+york'
)
# The Rack response format is used here
status, headers, body = response
p body
As per the Yelp documentation, the OAuth parameters do not have to be passed in the query string. The fact that the accepted answer resolved the issue indicates to me that there's probably a bug in the oauth gem causing this.

Resources